Source code for cpp_linter.loggers

import io
import logging
import os

FOUND_RICH_LIB = False
try:  # pragma: no cover
    from rich.logging import RichHandler, get_console  # type: ignore

    FOUND_RICH_LIB = True

    logging.basicConfig(
        format="%(name)s: %(message)s",
        handlers=[RichHandler(show_time=False, show_path=False)],
    )

except ImportError:  # pragma: no cover
    logging.basicConfig()

#: The :py:class:`logging.Logger` object used for outputting data.
logger = logging.getLogger("CPP Linter")
if not FOUND_RICH_LIB:
    logger.debug("rich module not found")

#: A logger for git-bot-feedback lib
git_bot_logger = logging.getLogger("git_bot_feedback")

# setup a separate logger for using github log commands
log_commander = logging.getLogger(
    "CI_LOG_GROUPING"  # the exact logger name used in git-bot-feedback
)
log_commander.setLevel(logging.DEBUG)  # be sure that log commands are output
console_handler = logging.StreamHandler()  # Create special stdout stream handler
console_handler.setFormatter(logging.Formatter("%(message)s"))  # no formatted log cmds
log_commander.addHandler(console_handler)  # Use special handler for log_commander
log_commander.propagate = False


[docs] def should_use_rich() -> bool: """Decide whether log output should be rendered with ``rich``. Call this in the parent process and hand the result to worker processes. With the ``forkserver`` start method (the default on Linux since Python 3.14) workers inherit the environment of the long-lived forkserver, not the parent's current environment, so a check of ``os.environ`` inside the worker can be stale. """ return FOUND_RICH_LIB and "CPP_LINTER_PYTEST_NO_RICH" not in os.environ
[docs] def worker_log_init(log_lvl: int, use_rich: bool | None = None): """Set up logging inside a worker process. :param log_lvl: The log level to apply; passed in because Windows does not copy the parent's log level to subprocesses. :param use_rich: Whether to render logs with ``rich``. Compute this in the parent with :func:`should_use_rich` and pass it in; ``None`` falls back to evaluating it in the current process. """ log_stream = io.StringIO() logger.handlers.clear() logger.propagate = False if use_rich is None: use_rich = should_use_rich() handler: logging.Handler if use_rich: # pragma: no cover console = get_console() console.file = log_stream handler = RichHandler(show_time=False, console=console) handler.setFormatter(logging.Formatter("%(name)s: %(message)s")) else: handler = logging.StreamHandler(log_stream) handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT)) logger.addHandler(handler) # Windows does not copy log level to subprocess. # https://github.com/cpp-linter/cpp-linter/actions/runs/8355193931 logger.setLevel(log_lvl) ## uncomment the following if log_commander is needed in isolated threads # log_commander.handlers.clear() # log_commander.propagate = False # console_handler = logging.StreamHandler(log_stream) # console_handler.setFormatter(logging.Formatter("%(message)s")) # log_commander.addHandler(console_handler) return log_stream