Files
ai-talk-callback/app/logger.py
2025-12-08 13:37:04 +08:00

144 lines
4.5 KiB
Python

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