优化日志和配置
This commit is contained in:
@@ -54,14 +54,7 @@ class Settings(BaseSettings):
|
||||
log_date_format: str = "%Y-%m-%d %H:%M:%S"
|
||||
|
||||
# API配置
|
||||
_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 ""
|
||||
api_authorization_token: str = "" # API Authorization Token
|
||||
|
||||
# 应用配置
|
||||
app_name: str = "AI Talk Callback API"
|
||||
|
||||
@@ -2,10 +2,57 @@ import logging
|
||||
import logging.handlers
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
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:
|
||||
"""日志管理器"""
|
||||
|
||||
@@ -40,10 +87,12 @@ class LoggerManager:
|
||||
)
|
||||
console_handler.setFormatter(console_formatter)
|
||||
|
||||
# 创建文件处理器(按时间轮转)
|
||||
file_handler = logging.handlers.TimedRotatingFileHandler(
|
||||
# 创建文件处理器(按时间轮转,每天17:36)
|
||||
file_handler = CustomTimedRotatingFileHandler(
|
||||
filename=settings.log_file,
|
||||
when='midnight', # 每天午夜轮转
|
||||
hour=17, # 17点
|
||||
minute=36, # 36分
|
||||
when='midnight', # 每天轮转
|
||||
interval=1, # 每天一次
|
||||
backupCount=settings.log_backup_count,
|
||||
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"):
|
||||
"""为Celery组件设置专用的文件日志器,同时保持控制台输出"""
|
||||
"""为Celery组件设置专用的文件日志器,同时输出到控制台和文件"""
|
||||
# 创建日志目录
|
||||
log_dir = Path(log_file).parent
|
||||
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.setLevel(getattr(logging, level.upper()))
|
||||
|
||||
# 清除现有文件处理器(避免重复添加)
|
||||
for handler in logger.handlers[:]:
|
||||
if isinstance(handler, logging.handlers.TimedRotatingFileHandler):
|
||||
logger.removeHandler(handler)
|
||||
# 清除现有处理器(避免重复添加)
|
||||
logger.handlers.clear()
|
||||
|
||||
# 创建控制台处理器
|
||||
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,
|
||||
hour=17, # 17点
|
||||
minute=36, # 36分
|
||||
when='midnight',
|
||||
interval=1,
|
||||
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.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',
|
||||
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.propagate = True
|
||||
logger.propagate = False # 防止重复输出到父日志器
|
||||
|
||||
return logger
|
||||
|
||||
@@ -159,8 +220,8 @@ def setup_celery_file_logger(logger_name: str, log_file: str, level: str = "INFO
|
||||
CELERY_LOGGERS = {
|
||||
"celery_tasks": ("logs/celery_tasks.log", "INFO"),
|
||||
"celery": ("logs/celery_app.log", "INFO"),
|
||||
"celery.beat": ("logs/celery_beat.log", "WARNING"),
|
||||
"celery.worker": ("logs/celery_worker.log", "WARNING"),
|
||||
"celery.beat": ("logs/celery_app.log", "INFO"), # Beat日志输出到celery_app.log
|
||||
"celery.worker": ("logs/celery_app.log", "INFO"), # Worker日志输出到celery_app.log
|
||||
}
|
||||
|
||||
# 初始化所有Celery文件日志器
|
||||
|
||||
Reference in New Issue
Block a user