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

日志系统迁移 - 阶段 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.py
  • app/services/payment/wechat_payment.py
  • app/services/payment/alipay_payment.py
  • app/services/recharge_service.py
  • app/services/attachment_service.py

预计时间: 3 小时

相关文档


阶段 1 状态: 完成
下一阶段: 阶段 2 - 服务层