优化日志和配置

This commit is contained in:
mark.tian
2025-12-11 18:08:20 +08:00
parent 06aa1cbc17
commit 1edae9f5f5
2 changed files with 78 additions and 24 deletions

View File

@@ -54,14 +54,7 @@ class Settings(BaseSettings):
log_date_format: str = "%Y-%m-%d %H:%M:%S" log_date_format: str = "%Y-%m-%d %H:%M:%S"
# API配置 # API配置
_api_authorization_token: str = "" # 内部存储API Authorization Token api_authorization_token: str = "" # API Authorization Token
@property
def api_authorization_token(self) -> str:
"""API Authorization Token - 只在生产环境下返回"""
if self.environment.lower() == "production":
return self._api_authorization_token
return ""
# 应用配置 # 应用配置
app_name: str = "AI Talk Callback API" app_name: str = "AI Talk Callback API"

View File

@@ -2,10 +2,57 @@ import logging
import logging.handlers import logging.handlers
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
import time
from datetime import datetime, timedelta
from app.config import settings from app.config import settings
class CustomTimedRotatingFileHandler(logging.handlers.TimedRotatingFileHandler):
"""自定义时间轮转文件处理器,支持指定轮转时间"""
def __init__(self, filename, hour=17, minute=36, when='midnight', interval=1, backupCount=7, encoding='utf-8'):
self.target_hour = hour
self.target_minute = minute
self.target_when = when
self.target_interval = interval
# 先调用父类初始化
super().__init__(filename, when=when, interval=interval, backupCount=backupCount, encoding=encoding)
# 重新计算轮转时间
self.computeRollover()
def computeRollover(self, currentTime=None):
"""计算下一次轮转时间,设置为每天的指定时间"""
if currentTime is None:
currentTime = time.time()
# 获取当前时间
current_time = datetime.fromtimestamp(currentTime)
# 创建今天的目标时间
target_time = current_time.replace(hour=self.target_hour, minute=self.target_minute, second=0, microsecond=0)
# 如果今天的目标时间已过,设置为明天
if current_time >= target_time:
target_time += timedelta(days=1)
# 转换为时间戳
self.rolloverAt = target_time.timestamp()
def doRollover(self):
# 调用父类轮转方法
super().doRollover()
# 重新计算下次轮转时间
self.computeRollover()
print(f"✅ 日志轮转完成,下次: {datetime.fromtimestamp(self.rolloverAt).strftime('%Y-%m-%d %H:%M:%S')}")
class LoggerManager: class LoggerManager:
"""日志管理器""" """日志管理器"""
@@ -40,10 +87,12 @@ class LoggerManager:
) )
console_handler.setFormatter(console_formatter) console_handler.setFormatter(console_formatter)
# 创建文件处理器(按时间轮转) # 创建文件处理器(按时间轮转,每天17:36)
file_handler = logging.handlers.TimedRotatingFileHandler( file_handler = CustomTimedRotatingFileHandler(
filename=settings.log_file, filename=settings.log_file,
when='midnight', # 每天午夜轮转 hour=17, # 17点
minute=36, # 36分
when='midnight', # 每天轮转
interval=1, # 每天一次 interval=1, # 每天一次
backupCount=settings.log_backup_count, backupCount=settings.log_backup_count,
encoding='utf-8', encoding='utf-8',
@@ -117,7 +166,7 @@ redis_logger = get_logger("redis")
# 通用文件日志器设置函数 # 通用文件日志器设置函数
def setup_celery_file_logger(logger_name: str, log_file: str, level: str = "INFO"): def setup_celery_file_logger(logger_name: str, log_file: str, level: str = "INFO"):
"""为Celery组件设置专用的文件日志器,同时保持控制台输出""" """为Celery组件设置专用的文件日志器,同时输出到控制台和文件"""
# 创建日志目录 # 创建日志目录
log_dir = Path(log_file).parent log_dir = Path(log_file).parent
log_dir.mkdir(parents=True, exist_ok=True) log_dir.mkdir(parents=True, exist_ok=True)
@@ -126,14 +175,25 @@ def setup_celery_file_logger(logger_name: str, log_file: str, level: str = "INFO
logger = get_logger(logger_name) logger = get_logger(logger_name)
logger.setLevel(getattr(logging, level.upper())) logger.setLevel(getattr(logging, level.upper()))
# 清除现有文件处理器(避免重复添加) # 清除现有处理器(避免重复添加)
for handler in logger.handlers[:]: logger.handlers.clear()
if isinstance(handler, logging.handlers.TimedRotatingFileHandler):
logger.removeHandler(handler) # 创建控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(getattr(logging, level.upper()))
# 控制台格式化器
console_formatter = logging.Formatter(
fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
datefmt='%H:%M:%S'
)
console_handler.setFormatter(console_formatter)
# 创建文件处理器 # 创建文件处理器
file_handler = logging.handlers.TimedRotatingFileHandler( file_handler = CustomTimedRotatingFileHandler(
filename=log_file, filename=log_file,
hour=17, # 17点
minute=36, # 36分
when='midnight', when='midnight',
interval=1, interval=1,
backupCount=7, backupCount=7,
@@ -142,16 +202,17 @@ def setup_celery_file_logger(logger_name: str, log_file: str, level: str = "INFO
file_handler.suffix = "%Y%m%d" file_handler.suffix = "%Y%m%d"
file_handler.setLevel(getattr(logging, level.upper())) file_handler.setLevel(getattr(logging, level.upper()))
# 格式化器 # 文件格式化器
formatter = logging.Formatter( file_formatter = logging.Formatter(
fmt='%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s', fmt='%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S' datefmt='%Y-%m-%d %H:%M:%S'
) )
file_handler.setFormatter(formatter) file_handler.setFormatter(file_formatter)
# 添加文件处理器 # 添加处理器(先控制台,后文件)
logger.addHandler(console_handler)
logger.addHandler(file_handler) logger.addHandler(file_handler)
logger.propagate = True logger.propagate = False # 防止重复输出到父日志器
return logger return logger
@@ -159,8 +220,8 @@ def setup_celery_file_logger(logger_name: str, log_file: str, level: str = "INFO
CELERY_LOGGERS = { CELERY_LOGGERS = {
"celery_tasks": ("logs/celery_tasks.log", "INFO"), "celery_tasks": ("logs/celery_tasks.log", "INFO"),
"celery": ("logs/celery_app.log", "INFO"), "celery": ("logs/celery_app.log", "INFO"),
"celery.beat": ("logs/celery_beat.log", "WARNING"), "celery.beat": ("logs/celery_app.log", "INFO"), # Beat日志输出到celery_app.log
"celery.worker": ("logs/celery_worker.log", "WARNING"), "celery.worker": ("logs/celery_app.log", "INFO"), # Worker日志输出到celery_app.log
} }
# 初始化所有Celery文件日志器 # 初始化所有Celery文件日志器