Skip to content

Log

log

Centralised logging configuration shared by the server, CLI, GUI, and Modal jobs

One Setup
  • setup_logging configures the mirumoji logger with a rotating file handler and / or a Rich console handler

  • The file format is clean and structured for later reading, while the console renders through Rich

  • A request-scoped context (REQUEST_CONTEXT) lets the server tag every log line emitted while handling a request with its correlation id, so a single request's logs can be followed across the file

MIRUMOJI_LOGGING_THEME = Theme({'accent': '#E2533B', 'accent.soft': '#F08A6E', 'info': '#5E83A4', 'success': '#8AA06A', 'danger': 'bold #C8503D', 'warning': '#D9A441', 'muted': '#7E7567', 'heading': 'bold #F4EEE3', 'ink': '#F4EEE3', 'highlighter.ok': '#8AA06A', 'highlighter.bad': 'bold #C8503D', 'highlighter.warn': '#D9A441', 'highlighter.number': '#C99A57', 'highlighter.uuid': '#F08A6E', 'highlighter.correlation': '#F08A6E', 'highlighter.method': 'bold #F4EEE3', 'highlighter.status_ok': '#8AA06A', 'highlighter.status_warn': '#D9A441', 'highlighter.status_bad': 'bold #C8503D', 'highlighter.path': '#5E83A4', 'highlighter.url': 'underline #5E83A4', 'highlighter.module': '#7E7567'}) module-attribute

Defines the Rich theme for mirumoji's console logging messages mimicking the frontend's Sumi & Shu design

REQUEST_CONTEXT = ContextVar('mirumoji_request_context') module-attribute

Process-scoped, request-local context populated by the server's LoggingMiddleware

Holds the current request's correlation_id, method, path, client_ip, and query. Empty outside of a request (launcher or startup logs)

Context variables are process-wide and must be declared at module level (the stdlib forbids creating them in a closure), so a module singleton is not used

MirumojiHighlighter

Bases: RegexHighlighter

Custom Rich highlighter for mirumoji's console logging messages

get_console() cached

Returns the shared server-side Rich console

Built once on first use (not at import) and reused so the console log handler and the themed transfer progress bars (server.progress) share a single output stream instead of fighting over stdout

Returns:

Type Description
Console

The shared themed Console

get_request_context()

Returns the current request-scoped logging context

Returns:

Type Description
dict[str, str]

The context dict, or an empty dict outside of a request

setup_logging(*, log_file='backend.log', console=True, level=None, capture_root=False)

Configures the mirumoji logger with shared handlers and formatters

Handlers
  • A RotatingFileHandler (5 MB x 3 backups) under HOST_LOG_PATH, using a clean structured format, when log_file is given

  • A themed Rich console handler when console is True

Idempotent

On each call, only the handlers attached by this module are cleared so that repeated calls never stack handlers or disturb third-party ones

Parameters:

Name Type Description Default
log_file str | None

Log file name under HOST_LOG_PATH, or None for no file handler (Modal containers only emit to stdout)

'backend.log'
console bool

Whether to attach the Rich console handler

True
level str | int | None

Explicit level, or None to read MIRUMOJI_LOGGING_LEVEL (default INFO)

None
capture_root bool

When True, also attach the same file handler to the root logger so third-party records get a UTF-8 sink instead of logging's last-resort stderr handler. Requires log_file

False

Raises:

Type Description
ValueError

If capture_root is set without a log_file

takeover_logging(*, log_file='backend.log', console=True, level=None)

Makes mirumoji's logging authoritative for the whole process

Framework Agnostic
  • Rather than reconfiguring a specific server (uvicorn, hypercorn, ...), this strips the handlers from every existing logger and turns their propagation back on, so every record funnels to the root logger, which carries mirumoji's themed handlers

  • A _ThirdPartyNoiseFilter then drops non-mirumoji records below WARNING, so a server's INFO chatter (access log, startup banners) stays quiet while its warnings and errors surface themed

Handlers
  • A RotatingFileHandler (5 MB x 3 backups) under HOST_LOG_PATH, using a clean structured format, when log_file is given

  • A themed Rich console handler when console is True

Call Order

Call from create_app, the app factory. It runs after an ASGI server has created its own loggers but before the server emits any line, so even the first startup banner is captured and quieted

Parameters:

Name Type Description Default
log_file str | None

Log file name under HOST_LOG_PATH, or None for no file handler

'backend.log'
console bool

Whether to attach the Rich console handler

True
level str | int | None

Explicit level, or None to read MIRUMOJI_LOGGING_LEVEL (default INFO)

None

teardown_logging()

Closes and removes every handler this module attached, releasing the log file

Why It Matters
  • On Windows, an open file handle blocks deleting the folder it lives in, and platformdirs nests the log directory inside the data directory (.../mirumoji/{version}/Logs)

  • So the rotating log handler holds the whole data directory open. Call this at server shutdown, and before wiping the storage directory, so the directory can actually be removed

Coverage

Clears the managed handlers from the root logger (where takeover attaches them) and from every named logger (where setup_logging attaches them for the launcher), closing each so its file is released