qq_lib.core.logger

Unified logging utilities for qq.

This module provides a helper for creating consistently formatted loggers using Rich-based output. Loggers automatically adapt to qq's debug mode, support optional timestamps, and apply standardized styling across the codebase.

 1# Released under MIT License.
 2# Copyright (c) 2025-2026 Ladislav Bartos and Robert Vacha Lab
 3
 4"""
 5Unified logging utilities for qq.
 6
 7This module provides a helper for creating consistently formatted loggers using
 8Rich-based output. Loggers automatically adapt to qq's debug mode, support
 9optional timestamps, and apply standardized styling across the codebase.
10"""
11
12import logging
13import os
14import sys
15
16from rich.console import Console
17from rich.logging import RichHandler
18
19from .config import CFG
20
21
22def get_logger(name: str, show_time: bool = False) -> logging.Logger:
23    """
24    Return a logger with unified formatting.
25    If colored=True, use rich's RichHandler with colored levels.
26    """
27    logger = logging.getLogger(name)
28
29    debug_mode = os.environ.get(CFG.env_vars.debug_mode) is not None
30    logger.setLevel(logging.DEBUG if debug_mode else logging.INFO)
31
32    if sys.stderr.isatty():
33        console = Console(stderr=True)
34        handler = RichHandler(
35            console=console,
36            rich_tracebacks=True,
37            show_path=False,
38            show_level=True,
39            show_time=show_time or debug_mode,
40            log_time_format=CFG.date_formats.standard,
41            tracebacks_width=None,
42            tracebacks_code_width=None,
43        )
44    else:
45        handler = logging.StreamHandler(sys.stderr)
46        fmt = (
47            "%(asctime)s %(levelname)-8s %(message)s"
48            if (show_time or debug_mode)
49            else "%(levelname)-8s %(message)s"
50        )
51        handler.setFormatter(logging.Formatter(fmt, datefmt=CFG.date_formats.standard))
52
53    handler.setLevel(logging.DEBUG if debug_mode else logging.INFO)
54    logger.addHandler(handler)
55    logger.propagate = False
56
57    return logger
def get_logger(name: str, show_time: bool = False) -> logging.Logger:
23def get_logger(name: str, show_time: bool = False) -> logging.Logger:
24    """
25    Return a logger with unified formatting.
26    If colored=True, use rich's RichHandler with colored levels.
27    """
28    logger = logging.getLogger(name)
29
30    debug_mode = os.environ.get(CFG.env_vars.debug_mode) is not None
31    logger.setLevel(logging.DEBUG if debug_mode else logging.INFO)
32
33    if sys.stderr.isatty():
34        console = Console(stderr=True)
35        handler = RichHandler(
36            console=console,
37            rich_tracebacks=True,
38            show_path=False,
39            show_level=True,
40            show_time=show_time or debug_mode,
41            log_time_format=CFG.date_formats.standard,
42            tracebacks_width=None,
43            tracebacks_code_width=None,
44        )
45    else:
46        handler = logging.StreamHandler(sys.stderr)
47        fmt = (
48            "%(asctime)s %(levelname)-8s %(message)s"
49            if (show_time or debug_mode)
50            else "%(levelname)-8s %(message)s"
51        )
52        handler.setFormatter(logging.Formatter(fmt, datefmt=CFG.date_formats.standard))
53
54    handler.setLevel(logging.DEBUG if debug_mode else logging.INFO)
55    logger.addHandler(handler)
56    logger.propagate = False
57
58    return logger

Return a logger with unified formatting. If colored=True, use rich's RichHandler with colored levels.