|
| 1 | +"""Colored logging utilities.""" |
| 2 | + |
| 3 | +import logging |
| 4 | + |
| 5 | +class ColoredFormatter(logging.Formatter): |
| 6 | + """A logging formatter that adds ANSI color codes to log levels.""" |
| 7 | + |
| 8 | + # ANSI color codes matching pytest's colors |
| 9 | + COLORS = { |
| 10 | + logging.CRITICAL: "\033[91m", # Red |
| 11 | + logging.ERROR: "\033[91m", # Red |
| 12 | + logging.WARNING: "\033[93m", # Yellow |
| 13 | + logging.INFO: "\033[92m", # Green |
| 14 | + logging.DEBUG: "\033[95m", # Magenta/Purple |
| 15 | + } |
| 16 | + RESET = "\033[0m" |
| 17 | + |
| 18 | + def format(self, record: logging.LogRecord) -> str: |
| 19 | + color = self.COLORS.get(record.levelno, "") |
| 20 | + original_levelname = record.levelname |
| 21 | + if color: |
| 22 | + record.levelname = f'{color}{record.levelname}{self.RESET}' |
| 23 | + result = super().format(record) |
| 24 | + record.levelname = original_levelname |
| 25 | + return result |
| 26 | + |
| 27 | + |
| 28 | +def setup_colored_logging(level: int = logging.INFO) -> None: |
| 29 | + """Set up logging with colored formatter.""" |
| 30 | + logger = logging.getLogger() |
| 31 | + logger.setLevel(level) |
| 32 | + for handler in logger.handlers[:]: |
| 33 | + logger.removeHandler(handler) |
| 34 | + handler = logging.StreamHandler() |
| 35 | + formatter = ColoredFormatter( |
| 36 | + fmt="%(asctime)s.%(msecs)03d %(levelname)s %(message)s", datefmt="%b %d %H:%M:%S" |
| 37 | + ) |
| 38 | + handler.setFormatter(formatter) |
| 39 | + logger.addHandler(handler) |
0 commit comments