llm-gguf-tools/helpers/logger.py

95 lines
3 KiB
Python

"""Colour-coded logging configuration for LLM GGUF tools.
Provides a consistent logging interface with colour-coded output for different
log levels, making it easier to identify warnings, errors, and informational
messages at a glance during tool execution and debugging sessions.
"""
from __future__ import annotations
from logging import (
CRITICAL,
DEBUG,
ERROR,
INFO,
WARNING,
Formatter as LoggingFormatter,
Logger,
LogRecord,
StreamHandler as LoggingStreamHandler,
getLogger,
)
from os import getenv as os_getenv
from sys import stdout as sys_stdout
from typing import ClassVar
DEBUG_MODE = os_getenv("DEBUG", "false").lower() == "true"
class ColourFormatter(LoggingFormatter):
"""Custom formatter adding colours to log messages based on severity level.
Uses ANSI escape codes to provide visual distinction between different
log levels in terminal output. Supports standard logging levels with
appropriate colour coding: DEBUG (cyan), INFO (green), WARNING (yellow),
ERROR (red), and CRITICAL (bold red) for immediate visual feedback.
"""
# ANSI colour codes
COLOURS: ClassVar[dict[int, str]] = {
DEBUG: "\033[36m", # Cyan
INFO: "\033[32m", # Green
WARNING: "\033[33m", # Yellow
ERROR: "\033[31m", # Red
CRITICAL: "\033[1;31m", # Bold Red
}
RESET = "\033[0m"
# Emoji prefixes for different levels
EMOJIS: ClassVar[dict[int, str]] = {
DEBUG: "", # No emoji for debug logs
INFO: "", # No emoji for regular info logs
WARNING: "⚠️ ",
ERROR: "",
CRITICAL: "🔥",
}
def format(self, record: LogRecord) -> str:
"""Format log record with colour and emoji based on severity level.
Enhances standard log formatting by prepending ANSI colour codes and
emoji indicators, then appending reset codes to prevent colour bleeding.
Maintains standard log structure whilst adding visual enhancements for
improved readability in terminal environments.
Returns:
str: Formatted log message with colour and emoji.
"""
# Get colour for this level
colour = self.COLOURS.get(record.levelno, "")
emoji = self.EMOJIS.get(record.levelno, "")
# Format the message with emoji (add space only if emoji exists)
if emoji:
record.msg = f"{emoji} {record.msg}"
formatted = super().format(record)
# Add colour codes
return f"{colour}{formatted}{self.RESET}"
# Create and configure the logger
logger: Logger = getLogger("llm-gguf-tools")
logger.setLevel(DEBUG if DEBUG_MODE else INFO)
# Create console handler with colour formatter
handler = LoggingStreamHandler(sys_stdout)
handler.setLevel(DEBUG if DEBUG_MODE else INFO)
# Set formatter without timestamp for cleaner output
formatter = ColourFormatter(fmt="%(message)s", datefmt="%H:%M:%S")
handler.setFormatter(formatter)
logger.addHandler(handler)
# Prevent propagation to root logger
logger.propagate = False