Compare commits

..

3 Commits

Author SHA1 Message Date
mark.tian
f2bc3ae9bd 回退日志组件为按天分割 2025-12-02 22:02:05 +08:00
mark.tian
a253618c7e Merge branch 'main' of https://git.shiliulizi.cn/mark.tian/ai-talk-callback 2025-12-02 21:48:42 +08:00
mark.tian
5fc22c38fa 回退 2025-12-02 21:48:21 +08:00

110
app/logger.py Normal file
View File

@@ -0,0 +1,110 @@
import logging
import logging.handlers
import os
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")
redis_logger = get_logger("redis")
external_api_logger = get_logger("external_api")