# Logging Configuration import logging import logging.handlers import sys from pathlib import Path from typing import Optional def setup_logging( log_level: str = "INFO", log_file: Optional[str] = None, enable_console: bool = True, max_file_size: int = 10 * 1024 * 1024, # 10MB backup_count: int = 5 ) -> logging.Logger: """ Setup centralized logging configuration Args: log_level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL) log_file: Path to log file (optional) enable_console: Whether to enable console logging max_file_size: Maximum log file size in bytes backup_count: Number of backup files to keep Returns: Configured logger instance """ # Create logs directory if it doesn't exist if log_file: log_path = Path(log_file) log_path.parent.mkdir(parents=True, exist_ok=True) # Configure root logger logger = logging.getLogger("recipe_bot") logger.setLevel(getattr(logging, log_level.upper())) # Clear existing handlers logger.handlers.clear() # Create formatter formatter = logging.Formatter( fmt="%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s", datefmt="%Y-%m-%d %H:%M:%S" ) # Console handler if enable_console: console_handler = logging.StreamHandler(sys.stdout) console_handler.setLevel(getattr(logging, log_level.upper())) console_handler.setFormatter(formatter) logger.addHandler(console_handler) # File handler with rotation if log_file: file_handler = logging.handlers.RotatingFileHandler( filename=log_file, maxBytes=max_file_size, backupCount=backup_count, encoding='utf-8' ) file_handler.setLevel(getattr(logging, log_level.upper())) file_handler.setFormatter(formatter) logger.addHandler(file_handler) # Prevent duplicate logs logger.propagate = False return logger def get_logger(name: str) -> logging.Logger: """Get a child logger with the specified name""" return logging.getLogger(f"recipe_bot.{name}") # Default logger setup def setup_default_logging(): """Setup default logging configuration""" return setup_logging( log_level="INFO", log_file="./logs/recipe_bot.log", enable_console=True )