""" Centralized logging configuration for Medical Transcriber application. Provides consistent logging across all modules with file and console output. """ import logging import logging.handlers from pathlib import Path from datetime import datetime from typing import Optional from .constants import LoggingConfig, PROJECT_ROOT, LOGS_DIR class LoggerSetup: """Centralized logger configuration.""" _initialized = False @classmethod def setup(cls, log_file: Optional[str] = None, level: str = LoggingConfig.LOG_LEVEL) -> None: """ Initialize logging configuration for the entire application. Args: log_file: Optional custom log file name. If None, uses auto-generated name. level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL) """ if cls._initialized: return # Create logs directory if it doesn't exist LOGS_DIR.mkdir(parents=True, exist_ok=True) # Generate log file path if log_file is None: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") log_file = f"transcription_{timestamp}.log" log_path = LOGS_DIR / log_file # Create root logger root_logger = logging.getLogger() root_logger.setLevel(getattr(logging, level)) # File handler file_handler = logging.handlers.RotatingFileHandler( log_path, maxBytes=10 * 1024 * 1024, # 10 MB backupCount=5, encoding='utf-8' ) file_handler.setLevel(getattr(logging, level)) # Console handler console_handler = logging.StreamHandler() console_handler.setLevel(getattr(logging, level)) # Formatter formatter = logging.Formatter( LoggingConfig.LOG_FORMAT, datefmt=LoggingConfig.LOG_DATE_FORMAT ) file_handler.setFormatter(formatter) console_handler.setFormatter(formatter) # Add handlers to root logger root_logger.addHandler(file_handler) root_logger.addHandler(console_handler) cls._initialized = True root_logger.info(f"Logging initialized. Log file: {log_path}") @classmethod def get_logger(cls, name: str) -> logging.Logger: """ Get logger instance for a module. Args: name: Module name (usually __name__) Returns: Configured logger instance """ if not cls._initialized: cls.setup() return logging.getLogger(name) def configure_logging( log_file: Optional[str] = None, level: str = LoggingConfig.LOG_LEVEL ) -> None: """ Configure logging for the application. Args: log_file: Optional custom log file name level: Logging level """ LoggerSetup.setup(log_file, level) def get_logger(name: str) -> logging.Logger: """ Get a logger instance. Args: name: Logger name (usually __name__) Returns: Configured logger instance """ return LoggerSetup.get_logger(name)