Source code for thesis.core.logging.handlers

"""
Custom log handlers for specialized logging needs.

This module provides custom handlers for specific logging scenarios
in medical imaging pipelines, such as patient-specific logs, step logs,
and performance tracking.
"""

import logging as _stdlib_logging
from pathlib import Path

from loguru import logger

__all__ = [
    "InterceptHandler",
]


[docs] class InterceptHandler(_stdlib_logging.Handler): """ Intercepts stdlib logging records and forwards them to loguru. Install once via logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True) to route all third-party library logs (e.g. Nipype, FSL wrappers) through loguru's formatting. """
[docs] def emit(self, record: _stdlib_logging.LogRecord) -> None: try: level = logger.level(record.levelname).name except ValueError: level = str(record.levelno) # fallback to int level as string # Walk up the call stack to find the real caller (past this handler and # stdlib logging internals like logging.callHandlers). handler_file = str(Path(__file__).resolve()) stdlib_logging_dir = str(Path(_stdlib_logging.__file__).resolve().parent) frame, depth = _stdlib_logging.currentframe(), 2 while frame: frame_path = str(Path(frame.f_code.co_filename).resolve()) in_handler = frame_path == handler_file in_stdlib_logging = frame_path.startswith(stdlib_logging_dir) if not (in_handler or in_stdlib_logging): break frame = frame.f_back # type: ignore[assignment] depth += 1 def _patch_record(log_record: dict) -> None: log_record["name"] = record.name log_record["function"] = record.funcName log_record["line"] = record.lineno log_record["module"] = record.module patched_logger = logger.patch(_patch_record) # type: ignore[arg-type] patched_logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())