You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.5 KiB
5.5 KiB
日志系统迁移 - 阶段 1:核心模块完成
日期: 2026-01-29
类型: 重构
影响范围: 核心模块(4 个文件)
概述
完成日志系统迁移的阶段 1,将核心模块从 loguru 迁移到 Python 标准库 logging。
迁移文件
1. app/core/logging.py ✅
变更类型: 完全重写
主要变更:
- ✅ 移除
loguru依赖 - ✅ 实现
ColoredFormatter类(开发环境彩色输出) - ✅ 实现
StructuredFormatter类(生产环境结构化日志) - ✅ 重写
setup_logging()函数- 支持控制台输出(彩色/非彩色)
- 支持文件输出(按时间轮转 + 按大小轮转)
- 自动检测测试环境
- 配置第三方库日志级别
- ✅ 新增
get_logger(name)函数
新功能:
# 彩色输出(开发环境)
ColoredFormatter - 支持 5 种颜色(DEBUG/INFO/WARNING/ERROR/CRITICAL)
# 结构化日志(生产环境)
StructuredFormatter - 支持 request_id, user_id 字段
# 日志轮转
- 按时间:每天午夜轮转,保留 30 天(应用日志)/ 90 天(错误日志)
- 按大小:单文件最大 100MB,保留 5 个备份
2. app/core/database.py ✅
变更类型: 日志调用替换
变更内容:
# Before
from loguru import logger
logger.info("✅ Database migration completed")
logger.debug(f"Migration output: {result.stdout}")
logger.error(f"❌ Database migration failed: {e.stderr}")
# After
import logging
logger = logging.getLogger(__name__)
logger.info("✅ Database migration completed")
logger.debug("Migration output: %s", result.stdout)
logger.error("❌ Database migration failed: %s", e.stderr, exc_info=True)
关键改进:
- ✅ 使用
%-formatting而非 f-string - ✅ 错误日志添加
exc_info=True显示堆栈跟踪
3. app/core/cache.py ✅
变更类型: 日志调用替换
变更内容:
# Before
from loguru import logger
logger.info("✅ Redis 连接成功")
logger.error(f"❌ Redis 连接失败: {e}")
logger.info(f"清除缓存: {len(keys)} 个键")
# After
import logging
logger = logging.getLogger(__name__)
logger.info("✅ Redis 连接成功")
logger.error("❌ Redis 连接失败", exc_info=True)
logger.info("清除缓存: %d 个键", len(keys))
4. app/middleware/logging.py ✅
变更类型: 日志调用替换
变更内容:
# Before
from loguru import logger
logger.info(f"[{request_id}] {request.method} {request.url.path} started")
logger.error(f"[{request_id}] {request.method} {request.url.path} failed after {process_time:.2f}ms: {str(e)}")
# After
import logging
logger = logging.getLogger(__name__)
logger.info("[%s] %s %s started", request_id, request.method, request.url.path)
logger.error("[%s] %s %s failed after %.2fms", request_id, request.method, request.url.path, process_time, exc_info=True)
技术亮点
1. 彩色输出保留
开发环境仍然支持彩色日志输出,提升开发体验:
class ColoredFormatter(logging.Formatter):
COLORS = {
'DEBUG': '\033[36m', # 青色
'INFO': '\033[32m', # 绿色
'WARNING': '\033[33m', # 黄色
'ERROR': '\033[31m', # 红色
'CRITICAL': '\033[35m', # 紫色
}
2. 结构化日志支持
生产环境支持结构化日志,便于日志聚合和分析:
class StructuredFormatter(logging.Formatter):
def format(self, record):
if not hasattr(record, 'request_id'):
record.request_id = '-'
if not hasattr(record, 'user_id'):
record.user_id = '-'
return super().format(record)
3. 智能环境检测
自动检测测试环境,避免测试时生成日志文件:
is_testing = (
os.getenv("PYTEST_CURRENT_TEST") is not None or
"pytest" in sys.modules or
any("pytest" in arg for arg in sys.argv)
)
4. 第三方库日志控制
合理设置第三方库日志级别,减少噪音:
logging.getLogger("uvicorn").setLevel(logging.INFO)
logging.getLogger("sqlalchemy").setLevel(logging.WARNING)
logging.getLogger("asyncpg").setLevel(logging.WARNING)
logging.getLogger("celery").setLevel(logging.INFO)
测试验证
手动测试
# 1. 检查语法错误
docker exec jointo-server-app python -m py_compile app/core/logging.py
docker exec jointo-server-app python -m py_compile app/core/database.py
docker exec jointo-server-app python -m py_compile app/core/cache.py
docker exec jointo-server-app python -m py_compile app/middleware/logging.py
# 2. 测试日志输出
docker exec jointo-server-app python -c "
from app.core.logging import get_logger
logger = get_logger('test')
logger.debug('Debug message')
logger.info('Info message')
logger.warning('Warning message')
logger.error('Error message')
"
# 3. 检查日志文件生成
docker exec jointo-server-app ls -lh logs/
性能影响
- ✅ 内存占用: 无明显变化
- ✅ CPU 使用: 无明显变化
- ✅ 日志写入: 使用异步处理器,不阻塞主线程
后续工作
阶段 2: 服务层(下一步)
需要迁移的文件:
app/services/payment_service.pyapp/services/payment/wechat_payment.pyapp/services/payment/alipay_payment.pyapp/services/recharge_service.pyapp/services/attachment_service.py
预计时间: 3 小时
相关文档
阶段 1 状态: ✅ 完成
下一阶段: 阶段 2 - 服务层