""" Logging configuration for the Aniworld application. This module provides a centralized logging setup with both console and file logging, following Python logging best practices. """ import logging import sys from pathlib import Path from typing import Optional from src.config.settings import settings def setup_logging( log_file: Optional[str] = None, log_level: Optional[str] = None, log_dir: Optional[Path] = None ) -> logging.Logger: """ Configure application logging with console and file handlers. Args: log_file: Name of the log file (default: "fastapi_app.log") log_level: Logging level (default: from settings or "INFO") log_dir: Directory for log files (default: "logs" in project root) Returns: Configured logger instance """ # Determine log level level_name = log_level or settings.log_level or "INFO" level = getattr(logging, level_name.upper(), logging.INFO) # Determine log directory and file if log_dir is None: # Default to logs directory in project root log_dir = Path(__file__).parent.parent.parent.parent / "logs" log_dir.mkdir(parents=True, exist_ok=True) if log_file is None: log_file = "fastapi_app.log" log_path = log_dir / log_file # Create formatters detailed_formatter = logging.Formatter( fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S" ) console_formatter = logging.Formatter( fmt="%(levelname)s: %(message)s" ) # Configure root logger root_logger = logging.getLogger() root_logger.setLevel(level) # Remove existing handlers to avoid duplicates root_logger.handlers.clear() # Console handler (stdout) console_handler = logging.StreamHandler(sys.stdout) console_handler.setLevel(level) console_handler.setFormatter(console_formatter) root_logger.addHandler(console_handler) # File handler file_handler = logging.FileHandler(log_path, mode='a', encoding='utf-8') file_handler.setLevel(level) file_handler.setFormatter(detailed_formatter) root_logger.addHandler(file_handler) # Create application logger logger = logging.getLogger("aniworld") logger.setLevel(level) # Log startup information logger.info("=" * 60) logger.info("Logging configured successfully") logger.info("Log level: %s", level_name.upper()) logger.info("Log file: %s", log_path) logger.info("=" * 60) return logger def get_logger(name: str) -> logging.Logger: """ Get a logger instance for a specific module. Args: name: Name of the logger (typically __name__) Returns: Logger instance """ return logging.getLogger(name)