import logging import logging.handlers from pathlib import Path from typing import Optional from app.config import settings class LoggerManager: """日志管理器""" _loggers = {} _initialized = False @classmethod def setup_logging(cls): """设置日志系统""" if cls._initialized: return # 创建日志目录 log_dir = Path(settings.log_file).parent log_dir.mkdir(parents=True, exist_ok=True) # 配置根日志器 root_logger = logging.getLogger() root_logger.setLevel(getattr(logging, settings.log_level.upper())) # 清除现有处理器 root_logger.handlers.clear() # 创建控制台处理器 console_handler = logging.StreamHandler() console_handler.setLevel(getattr(logging, settings.log_level.upper())) # 控制台使用普通格式化器 console_formatter = logging.Formatter( fmt=settings.log_format, datefmt=settings.log_date_format ) console_handler.setFormatter(console_formatter) # 创建文件处理器(按时间轮转) file_handler = logging.handlers.TimedRotatingFileHandler( filename=settings.log_file, when='midnight', # 每天午夜轮转 interval=1, # 每天一次 backupCount=settings.log_backup_count, encoding='utf-8', ) # 创建后设置 suffix 属性 file_handler.suffix = "%Y%m%d" # 设置文件后缀格式,如 app.log.20231215 file_handler.setLevel(settings.log_level) # 文件记录所有级别 # 文件使用普通格式化器 file_formatter = logging.Formatter( fmt=settings.log_format, datefmt=settings.log_date_format ) file_handler.setFormatter(file_formatter) # 添加处理器到根日志器 root_logger.addHandler(console_handler) root_logger.addHandler(file_handler) # 设置第三方库的日志级别 logging.getLogger("uvicorn").setLevel(logging.INFO) logging.getLogger("uvicorn.access").setLevel(logging.WARNING) logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING) logging.getLogger("httpx").setLevel(logging.WARNING) logging.getLogger("watchfiles").setLevel(logging.WARNING) cls._initialized = True # 记录日志系统启动 logger = cls.get_logger("LoggerManager") logger.info("🚀 日志系统初始化完成") logger.info(f"📁 日志文件: {settings.log_file}") logger.info(f"📊 日志级别: {settings.log_level}") @classmethod def get_logger(cls, name: str) -> logging.Logger: """获取指定名称的日志器""" if not cls._initialized: cls.setup_logging() if name not in cls._loggers: cls._loggers[name] = logging.getLogger(name) return cls._loggers[name] def get_logger(name: Optional[str] = None) -> logging.Logger: """获取日志器的便捷函数""" if name is None: # 自动获取调用者的模块名 import inspect frame = inspect.currentframe().f_back name = frame.f_globals.get('__name__', 'unknown') return LoggerManager.get_logger(name) # 预定义的日志器 app_logger = get_logger("app") api_logger = get_logger("api") db_logger = get_logger("database") external_api_logger = get_logger("external_api") # 各模块专用日志器 main_logger = get_logger("main") routes_logger = get_logger("routes") celery_logger = get_logger("celery") celery_tasks_logger = get_logger("celery_tasks") callback_service_logger = get_logger("callback_service") redis_logger = get_logger("redis") # 向后兼容的默认日志器 logger = app_logger # 便捷获取各模块日志器的函数 def get_main_logger(): """获取main模块日志器""" return main_logger def get_routes_logger(): """获取routes模块日志器""" return routes_logger def get_celery_logger(): """获取celery模块日志器""" return celery_logger def get_celery_tasks_logger(): """获取celery_tasks模块日志器""" return celery_tasks_logger def get_callback_service_logger(): """获取callback_service模块日志器""" return callback_service_logger def get_redis_logger(): """获取redis模块日志器""" return redis_logger