| import inspect |
| import logging |
| import sys |
| from typing import Literal |
|
|
| from loguru import logger |
|
|
|
|
| def setup_logging( |
| level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "DEBUG", |
| diagnose: bool = True, |
| backtrace: bool = True, |
| colorize: bool = True, |
| ) -> None: |
| """ |
| Setup loguru logging configuration to unify all project logging output |
| |
| Args: |
| level: Log level |
| diagnose: Whether to enable diagnostic information |
| backtrace: Whether to enable backtrace information |
| colorize: Whether to enable colors |
| """ |
| |
| logger.remove() |
|
|
| |
| logger.add( |
| sys.stderr, |
| level=level, |
| colorize=colorize, |
| backtrace=backtrace, |
| diagnose=diagnose, |
| enqueue=True, |
| ) |
|
|
| |
| _setup_logging_intercept() |
|
|
| logger.debug("Logger initialized.") |
|
|
|
|
| def _setup_logging_intercept() -> None: |
| """Setup standard logging library interceptor to redirect to loguru""" |
|
|
| class InterceptHandler(logging.Handler): |
| def emit(self, record: logging.LogRecord) -> None: |
| |
| try: |
| level: str | int = logger.level(record.levelname).name |
| except ValueError: |
| level = record.levelno |
|
|
| |
| frame, depth = inspect.currentframe(), 0 |
| while frame: |
| filename = frame.f_code.co_filename |
| is_logging = filename == logging.__file__ |
| is_frozen = "importlib" in filename and "_bootstrap" in filename |
| if depth > 0 and not (is_logging or is_frozen): |
| break |
| frame = frame.f_back |
| depth += 1 |
|
|
| logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage()) |
|
|
| |
| logging.basicConfig(handlers=[InterceptHandler()], level="INFO", force=True) |
|
|