|
|
""" |
|
|
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 |
|
|
|
|
|
|
|
|
LOGS_DIR.mkdir(parents=True, exist_ok=True) |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
root_logger = logging.getLogger() |
|
|
root_logger.setLevel(getattr(logging, level)) |
|
|
|
|
|
|
|
|
file_handler = logging.handlers.RotatingFileHandler( |
|
|
log_path, |
|
|
maxBytes=10 * 1024 * 1024, |
|
|
backupCount=5, |
|
|
encoding='utf-8' |
|
|
) |
|
|
file_handler.setLevel(getattr(logging, level)) |
|
|
|
|
|
|
|
|
console_handler = logging.StreamHandler() |
|
|
console_handler.setLevel(getattr(logging, level)) |
|
|
|
|
|
|
|
|
formatter = logging.Formatter( |
|
|
LoggingConfig.LOG_FORMAT, |
|
|
datefmt=LoggingConfig.LOG_DATE_FORMAT |
|
|
) |
|
|
|
|
|
file_handler.setFormatter(formatter) |
|
|
console_handler.setFormatter(formatter) |
|
|
|
|
|
|
|
|
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) |
|
|
|