exlab_wizard.logging.manager#
Canonical logger factory + configuration. Backend Spec §16.2.1, §16.2.2, §16.2.5.
This module is the single allowed call site for logging.getLogger in
the codebase (§16.2.1; pre-commit lint enforces this). All component
authors import get_logger() from exlab_wizard.logging.
The on-disk handler chain is wired up by configure_logging(), which
is invoked once during the FastAPI lifespan startup (§4.5) and may be
re-invoked after a PUT /api/v1/config to pick up a new
logging.level or rotation policy.
The architecture follows §16.2.5: every logger.info(...) call enqueues
the record on a queue.Queue via logging.handlers.QueueHandler,
and a dedicated background thread (QueueListener) drains the queue
into the actual handlers (per-equipment file, central rotating file, and
the stderr stream). This keeps the asyncio event loop unblocked on log
calls while preserving stdlib compatibility for any third-party library
that does logging.getLogger(__name__).info(...).
Functions
|
Install the §16.2.5 queue-based handler chain. |
|
Return a logger for |
- exlab_wizard.logging.manager.configure_logging(config=None)[source]#
Install the §16.2.5 queue-based handler chain.
Idempotent: calling this a second time tears down the existing listener and rebuilds it with the new
config. In-flight log records that have already been enqueued are drained into the old handlers before they’re replaced (seeQueueListener.stop), so aPUT /api/v1/configreconfigure does not lose log output.On first call:
Sets the root logger’s level threshold from
config.level(defaultINFOifconfigisNone).Creates a fresh unbounded
queue.Queue.Wires a
QueueHandleronto the root logger so everylogger.info(...)returns immediately.Builds the real handlers (per-equipment file, central rotating file, stderr stream) and starts a
QueueListenerthread that drains the queue into them.
The per-equipment file handler is only installed when a
local_rootis configured (Phase 3A’sconfigure_loggingaccepts aLoggingConfigonly; future phases may pass an explicitlocal_rootargument). Whenlocal_rootis unset, the chain falls back to central + stderr only – this keeps unit tests that don’t model an equipment root from crashing.- Parameters:
config (
LoggingConfig|None)- Return type:
- exlab_wizard.logging.manager.get_logger(name)[source]#
Return a logger for
name.The ONLY place in the codebase that may call
logging.getLogger(). Component authors must use this entry point; a pre-commit lint rule rejects directlogging.getLoggercalls in any module underexlab_wizard/other than this one (§16.2.1).The returned logger inherits the root level set by
configure_logging(). Ifconfigure_logginghas not been called yet (e.g. during early module import or in unit tests that don’t exercise the handler chain), the logger still works – it just falls through to the stdlib root logger’s defaults until the firstconfigure_loggingcall.