Source code for mcal.utils.log
"""Logging helpers for the :mod:`mcal` package.
Warnings and other diagnostics are emitted through the standard
:mod:`logging` module to ``stderr`` so that they stay separate from the
program results printed to ``stdout``. Colour is applied only when
``stderr`` is an interactive terminal.
"""
from __future__ import annotations
import logging
import sys
_RESET = "\033[0m"
_LEVEL_COLORS: dict[int, str] = {
logging.WARNING: "\033[33m", # yellow
logging.ERROR: "\033[31m", # red
logging.CRITICAL: "\033[31m", # red
}
class _ColorFormatter(logging.Formatter):
"""Formatter that prefixes the level name, colourised on a TTY.
Parameters
----------
color : bool
If ``True``, wrap the formatted record in an ANSI colour code that
depends on the record's level. If ``False``, emit plain text with no
escape sequences (suitable for redirected or piped output).
"""
def __init__(self, *, color: bool) -> None:
super().__init__("%(levelname)s: %(message)s")
self._color = color
def format(self, record: logging.LogRecord) -> str:
"""Format a log record, optionally wrapping it in an ANSI colour code.
Parameters
----------
record : logging.LogRecord
The record to format.
Returns
-------
str
The formatted message, colourised when ``color`` is enabled and a
colour is defined for the record's level.
"""
text = super().format(record)
color = _LEVEL_COLORS.get(record.levelno)
if self._color and color is not None:
return f"{color}{text}{_RESET}"
return text
[docs]
def get_logger(name: str) -> logging.Logger:
"""Return a logger for the given name.
Parameters
----------
name : str
Logger name, conventionally the module ``__name__`` so the logger
becomes a child of the ``mcal`` package logger.
Returns
-------
logging.Logger
The requested logger.
"""
return logging.getLogger(name)