from __future__ import annotations import logging import os from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler from typing import Tuple from app.config.settings import get_settings def _build_file_handler( log_path: str, rotation: str, max_bytes: int, backup_count: int ) -> logging.Handler: if rotation.lower() == "time": handler: logging.Handler = TimedRotatingFileHandler( log_path, when="D", backupCount=backup_count, encoding="utf-8" ) else: handler = RotatingFileHandler( log_path, maxBytes=max_bytes, backupCount=backup_count, encoding="utf-8" ) return handler def _build_formatters() -> Tuple[logging.Formatter, logging.Formatter]: base_format = "%(asctime)s | %(levelname)s | %(name)s | %(message)s" access_format = ( "%(asctime)s | %(levelname)s | access | %(message)s" ) return ( logging.Formatter(base_format, datefmt="%Y-%m-%d %H:%M:%S"), logging.Formatter(access_format, datefmt="%Y-%m-%d %H:%M:%S"), ) def setup_logging(log_dir: str) -> None: settings = get_settings() os.makedirs(log_dir, exist_ok=True) app_log = os.path.join(log_dir, "app.log") error_log = os.path.join(log_dir, "error.log") access_log = os.path.join(log_dir, "access.log") formatter, access_formatter = _build_formatters() app_handler = _build_file_handler( app_log, settings.log_rotation, settings.log_max_bytes, settings.log_backup_count ) app_handler.setFormatter(formatter) error_handler = _build_file_handler( error_log, settings.log_rotation, settings.log_max_bytes, settings.log_backup_count ) error_handler.setLevel(logging.ERROR) error_handler.setFormatter(formatter) access_handler = _build_file_handler( access_log, settings.log_rotation, settings.log_max_bytes, settings.log_backup_count ) access_handler.setFormatter(access_formatter) root = logging.getLogger() root.setLevel(settings.log_level.upper() or "INFO") root.handlers = [] root.addHandler(app_handler) root.addHandler(error_handler) access_logger = logging.getLogger("access") access_logger.setLevel(settings.log_level.upper() or "INFO") access_logger.handlers = [] access_logger.propagate = False access_logger.addHandler(access_handler)