How to use new hou.logging from 19.0?

   2860   6   0
User Avatar
Member
122 posts
Joined: June 2019
Offline
Just couldn't figure it out from the documentation how to use it in hom.

It looks great actually, but:
- How to fire my own LogEntry?
- Is there a way to register a custom source (for example my viewer state)

Also is there a way to pipe stdout to the new logging?
User Avatar
Staff
1448 posts
Joined: July 2005
Offline
You should be able to add your own sorce using HDK:
https://www.sidefx.com/docs/hdk/class_u_t___universal_log_source_registration.html [www.sidefx.com]

I don't think this is exposed thru HOM yet.

(There is also HOUDINI_DEFAULT_LOG_SOURCES env var you may need to set).
User Avatar
Staff
4438 posts
Joined: July 2005
Offline
Creating new sources and sending logs to these sources has been added to HOM in 19.0.436.

Your last question makes me think you haven't created a new Log Viewer pane yet? Once you enable logging with the far left icon menu, that same icon presents a list of all avaialble log sources (including stdout).
User Avatar
Member
122 posts
Joined: June 2019
Offline
That's great! Thanks!

I actually did just enabled all and completely missed that stdout was there.
Also I tested it with vex assuming that it catch it but it doesn't right now. Which probably could be a good source option as well.

Like in general I was thinking this is the finally replacement for houdini console window (I'd also prefer that it won't popping up if LogViewer is enabled)
User Avatar
Member
380 posts
Joined: July 2005
Offline
I was also pretty keen to checkout/use hou.logging in some of my hda PythonModules.

A couple of simple examples in the docs/docstrings would go a long way to help get up and running quickly.

This seems to be the only post that comes up on the topic.
User Avatar
Member
122 posts
Joined: June 2019
Offline
Logging provides a standard api that compatible with builtin python logging.

I think the easiest way is to create a custom handler for the viewer. Consider this simple example

import hou
import logging

HOU_SEVERITY_MAP = {
    logging.DEBUG: hou.severityType.Message,
    logging.INFO: hou.severityType.ImportantMessage,
    logging.WARNING: hou.severityType.Warning,
    logging.ERROR: hou.severityType.Error,
    logging.CRITICAL: hou.severityType.Fatal
}

class HouLogHandler(logging.StreamHandler):
    def __init__(self):
        super().__init__(self)

    def emit(self, record: logging.LogRecord):
        hlog_entry = hou.logging.LogEntry(record.msg, 
            source_context=record.name, 
            severity=HOU_SEVERITY_MAP[record.levelno], 
            thread_id=record.thread)
        hou.logging.log(hlog_entry)

logger = logging.getLogger("Tool")
logger.handlers =[HouLogHandler()] # addHandler in actual code 
logger.setLevel(logging.DEBUG)

logger.info("Info message") 
logger.warning("Warning") 
logger.error("Error") 
That way you'll see something like this:

With custom handler it's easier to control it and also you can use familiar python logging.

Unfortunately there are couple of issues.
  • While custom sources can be created they are not recognized by LogEntry. It always goes to the Python Logging (that's why I used context for logger name)
  • There is no filter in the viewer by level. I'm just used to this behavior, it's not always convenient to set levels on particular loggers.

Attachments:
logging.png (25.3 KB)

User Avatar
Member
606 posts
Joined: May 2007
Offline
For anyone else ending up in this topic the logging doesn't have to be as fancy as above.
A minimal example would be:
entry = hou.logging.LogEntry(message = "alive!")
hou.logging.log(entry)

If you want to log onto disk, you could add in the beginning
sink = hou.logging.FileSink(filepath)
sink.connect("Python Logging")
  • Quick Links