Logging¶
How to use the REvoDesign logging system in your module.
Quick start¶
from REvoDesign.logger import ROOT_LOGGER
logging = ROOT_LOGGER.getChild(__name__)
Every module gets its own child logger from ROOT_LOGGER. The logger name
matches the module path (e.g. REvoDesign.application.launching), so log
output is easy to trace to its source.
Module-level child loggers¶
Use this pattern at module scope:
# my_module.py
from REvoDesign.logger import ROOT_LOGGER
logging = ROOT_LOGGER.getChild(__name__)
def do_work():
logging.info("Starting work")
logging.debug("Detail: %s", some_value)
Instance loggers (plugin / window scope)¶
When a logger belongs to a specific plugin instance rather than the module, store it as an instance attribute:
class REvoDesignPlugin:
def __init__(self):
self.logging = ROOT_LOGGER.getChild(self.__class__.__name__)
def make_window(self):
self.logging.info("Window created")
This avoids cross-plugin state leakage that a module-level logging global
would cause when multiple plugin instances coexist.
Circular import warning¶
Modules that are imported before the logger is initialized (early
bootstrap modules) must NOT create a child logger at import time — the
ROOT_LOGGER may not exist yet. For these early modules, either:
- Delay the
getChildcall to function scope, or - Log via
ROOT_LOGGERdirectly after the logger module has loaded
Configuration¶
Log levels and handlers are configured in src/REvoDesign/config/logger.yaml:
| Setting | Purpose |
|---|---|
handlers.stdout.level |
Console output verbosity |
handlers.file.level |
Rotating file log verbosity |
handlers.notebook.level |
Notebook log verbosity |
loggers.root.level |
Root logger capture level |
The logger_level_setter_ng() function updates both the runtime handlers
and the persisted logger.yaml file.
Log levels¶
Available levels (from list_all_logger_levels()):
DEBUG → INFO → WARNING → ERROR → CRITICAL
These are stored in logger.yaml under levels and cached at runtime.
Structured (JSON) logging¶
File and notebook handlers use REvoDesignLogFormatter which emits each
record as a JSON object with configurable field keys:
{"level": "INFO", "message": "Server started", "timestamp": "2026-07-09T...", "logger": "REvoDesign.server", ...}
Extra attributes added via logging.info("msg", extra={"key": "val"}) are
included in the JSON output automatically.
Known limitations¶
- Windows file-race: Parallel subprocess tasks (e.g. sidechain modeling)
may contend for the rotating log file. The
QueueHandlerserialises writes within a single process but does not coordinate across processes.