Skip to content

Commit bf5fe21

Browse files
committed
补充提交:日志配置模块
1 parent 0e8c398 commit bf5fe21

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

backend/log_config.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
"""
2+
改进的日志配置 - 解决QueryGPT日志文件暴涨问题
3+
包含日志轮转、大小限制和性能优化
4+
"""
5+
import logging
6+
import logging.handlers
7+
import os
8+
from pathlib import Path
9+
10+
def setup_logging(app_name="querygpt", log_dir=None):
11+
"""设置日志系统,包含轮转和大小限制"""
12+
13+
# 确定日志目录
14+
if log_dir is None:
15+
log_dir = Path(__file__).parent.parent / "logs"
16+
else:
17+
log_dir = Path(log_dir)
18+
19+
# 创建日志目录
20+
log_dir.mkdir(exist_ok=True)
21+
22+
# 日志文件路径
23+
log_file = log_dir / f"{app_name}.log"
24+
25+
# 创建格式化器
26+
formatter = logging.Formatter(
27+
'%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s'
28+
)
29+
30+
# 创建轮转文件处理器(每个文件最大10MB,保留5个备份)
31+
file_handler = logging.handlers.RotatingFileHandler(
32+
log_file,
33+
maxBytes=10*1024*1024, # 10MB
34+
backupCount=5,
35+
encoding='utf-8'
36+
)
37+
file_handler.setFormatter(formatter)
38+
file_handler.setLevel(logging.INFO) # 文件只记录INFO及以上
39+
40+
# 创建控制台处理器
41+
console_handler = logging.StreamHandler()
42+
console_handler.setFormatter(formatter)
43+
console_handler.setLevel(logging.WARNING) # 控制台只显示WARNING及以上
44+
45+
# 配置根日志器
46+
root_logger = logging.getLogger()
47+
root_logger.setLevel(logging.INFO)
48+
49+
# 清除现有处理器
50+
root_logger.handlers.clear()
51+
52+
# 添加处理器
53+
root_logger.addHandler(file_handler)
54+
root_logger.addHandler(console_handler)
55+
56+
# 降低第三方库的日志级别(这些是造成日志暴涨的主要原因)
57+
third_party_loggers = [
58+
'urllib3',
59+
'werkzeug',
60+
'litellm',
61+
'httpx',
62+
'openai',
63+
'httpcore',
64+
'requests',
65+
'transformers',
66+
'tensorflow',
67+
'torch',
68+
'sqlalchemy',
69+
'alembic',
70+
'PIL',
71+
'matplotlib',
72+
'numpy',
73+
'pandas',
74+
'selenium',
75+
'uvicorn',
76+
'fastapi'
77+
]
78+
79+
for logger_name in third_party_loggers:
80+
logging.getLogger(logger_name).setLevel(logging.WARNING)
81+
82+
# 特别处理LiteLLM(这个库的日志特别多)
83+
logging.getLogger('LiteLLM').setLevel(logging.ERROR)
84+
logging.getLogger('litellm.utils').setLevel(logging.ERROR)
85+
logging.getLogger('litellm.litellm_core_utils').setLevel(logging.ERROR)
86+
logging.getLogger('litellm.proxy').setLevel(logging.ERROR)
87+
88+
return root_logger
89+
90+
def clean_old_logs(log_dir=None, days=7):
91+
"""清理旧日志文件"""
92+
if log_dir is None:
93+
log_dir = Path(__file__).parent.parent / "logs"
94+
else:
95+
log_dir = Path(log_dir)
96+
97+
if not log_dir.exists():
98+
return
99+
100+
from datetime import datetime, timedelta
101+
102+
cutoff_time = datetime.now() - timedelta(days=days)
103+
104+
for log_file in log_dir.glob("*.log*"):
105+
try:
106+
mtime = datetime.fromtimestamp(log_file.stat().st_mtime)
107+
if mtime < cutoff_time:
108+
log_file.unlink()
109+
print(f"删除旧日志: {log_file}")
110+
except Exception as e:
111+
print(f"无法删除 {log_file}: {e}")
112+
113+
def setup_request_logging():
114+
"""设置请求日志的特殊处理"""
115+
import logging
116+
117+
class RequestFilter(logging.Filter):
118+
"""过滤器:减少请求日志的冗余信息"""
119+
def filter(self, record):
120+
# 过滤掉某些不必要的日志
121+
if record.name == 'werkzeug':
122+
# 只保留错误和警告
123+
return record.levelno >= logging.WARNING
124+
125+
# 过滤掉健康检查的日志
126+
if hasattr(record, 'getMessage'):
127+
msg = record.getMessage()
128+
if '/health' in msg or '/ping' in msg:
129+
return False
130+
131+
return True
132+
133+
# 添加过滤器到根日志器
134+
for handler in logging.getLogger().handlers:
135+
handler.addFilter(RequestFilter())

0 commit comments

Comments
 (0)