Files

97 lines
3.2 KiB
Python
Raw Permalink Normal View History

2025-04-16 14:23:02 +00:00
import inspect
import logging
import os
from datetime import datetime
from logging import Logger
import colorama
from colorama import Fore, Style
from texteller.globals import Globals
# Initialize colorama for colored console output
colorama.init(autoreset=True)
TEMPLATE = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
class ColoredFormatter(logging.Formatter):
"""Custom formatter to add colors based on log level."""
FORMATS = { # noqa: E501
logging.DEBUG: Fore.LIGHTBLACK_EX + TEMPLATE + Style.RESET_ALL,
logging.INFO: Fore.WHITE + TEMPLATE + Style.RESET_ALL,
logging.WARNING: Fore.YELLOW + TEMPLATE + Style.RESET_ALL,
logging.ERROR: Fore.RED + TEMPLATE + Style.RESET_ALL,
logging.CRITICAL: Fore.RED + Style.BRIGHT + TEMPLATE + Style.RESET_ALL,
} # noqa: E501
def format(self, record):
log_fmt = self.FORMATS.get(record.levelno, self.FORMATS[logging.INFO])
formatter = logging.Formatter(log_fmt, datefmt="%Y-%m-%d %H:%M:%S")
return formatter.format(record)
def get_logger(name: str | None = None, use_file_handler: bool = False) -> Logger:
"""
Creates and configures a logger with the caller's module name (if provided) or the first two modules.
If the module name is too long, it takes the first two modules.
Args:
name (str, optional): Custom logger name. If None, derives from caller's module.
use_file_handler (bool, optional): Whether to use a file handler. Defaults to False.
Returns:
Logger: Configured logger with colored console output and file handler.
"""
# If name is not provided, derive it from the caller's module
if name is None:
# Get the caller's stack frame
frame = inspect.stack()[1]
module = inspect.getmodule(frame[0])
if module and module.__name__:
module_name = module.__name__
# Split module name and take first two components if too long
parts = module_name.split(".")
if len(parts) > 2:
name = ".".join(parts[:2])
else:
name = module_name
else:
name = "root"
# Create or get logger
logger = logging.getLogger(name)
# Prevent duplicate handlers
if logger.handlers:
return logger
# Set logger level
logger.setLevel(Globals().logging_level)
# Create console handler with colored formatter
console_handler = logging.StreamHandler()
console_handler.setLevel(Globals().logging_level)
console_formatter = ColoredFormatter()
console_handler.setFormatter(console_formatter)
logger.addHandler(console_handler)
# Create file handler
if use_file_handler:
log_dir = "logs"
os.makedirs(log_dir, exist_ok=True)
log_file = os.path.join(log_dir, f"{datetime.now().strftime('%Y%m%d')}.log")
file_handler = logging.FileHandler(log_file)
file_handler.setLevel(Globals().logging_level)
# File formatter (no colors)
file_formatter = logging.Formatter(TEMPLATE, datefmt="%Y-%m-%d %H:%M:%S")
file_handler.setFormatter(file_formatter)
logger.addHandler(file_handler)
# Prevent logger from propagating to root logger
logger.propagate = False
return logger