#!/usr/bin/env python3 """ Logger module for the Icecast metadata IRC announcer. Uses Loguru for simple yet powerful logging. """ import os import sys from pathlib import Path from loguru import logger class LogManager: """ Manages logging configuration for the Icecast metadata IRC announcer. This class provides a simple interface for configuring and using Loguru throughout the project. It handles log file rotation, formatting, and different log levels. """ def __init__(self, config=None): """ Initialize the LogManager with optional configuration. Args: config: Optional dictionary with logging configuration. If None, default configuration is used. """ self.config = config or {} self.log_dir = Path(self.config.get('log_dir', 'logs')) self.log_level = self.config.get('level', 'INFO').upper() self.log_format = self.config.get('format', "{time:YYYY-MM-DD HH:mm:ss} | " "{level: <8} | " "{name}:{function}:{line} - " "{message}" ) # Create log directory if it doesn't exist if not self.log_dir.exists(): self.log_dir.mkdir(parents=True, exist_ok=True) # Configure logger self._configure_logger() def _configure_logger(self): """Configure Loguru logger with appropriate sinks and formats.""" # Remove default handler logger.remove() # Add console handler logger.add( sys.stderr, format=self.log_format, level=self.log_level, colorize=True ) # Add file handler with rotation log_file = self.log_dir / "icecast_bot.log" logger.add( str(log_file), format=self.log_format, level=self.log_level, rotation="10 MB", # Rotate when file reaches 10MB compression="zip", # Compress rotated logs retention="1 week", # Keep logs for 1 week backtrace=True, # Include backtrace in error logs diagnose=True # Include variables in error logs ) def get_logger(self, name=None): """ Get a logger instance with the given name. Args: name: Optional name for the logger. If None, the calling module's name is used. Returns: A Loguru logger instance. """ if name: return logger.bind(name=name) return logger @staticmethod def set_level(level): """ Set the log level for all handlers. Args: level: Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) """ for handler_id in logger._core.handlers: logger.configure(handler_id, level=level) # Create a default instance for easy import log_manager = LogManager() get_logger = log_manager.get_logger # Export the logger directly for simple usage log = logger # For convenience, export common log levels debug = logger.debug info = logger.info warning = logger.warning error = logger.error critical = logger.critical exception = logger.exception # Example usage: # from logger import log, debug, info, error # log.info("This is an info message") # debug("This is a debug message") # # # Or with a named logger: # from logger import get_logger # logger = get_logger("my_module") # logger.info("This is a message from my_module")