Skip to content

日志系统

说明

通过 Python 标准库 logging 实现结构化日志,支持控制台 + 文件双输出,日志文件按大小自动轮转。配置入口位于 src/core/logger.py

配置入口

日志配置位于 src/core/logger.py

python
import logging
import sys
from logging.handlers import RotatingFileHandler
from pathlib import Path

# 日志目录
LOG_DIR = Path(__file__).resolve().parents[2] / "logs"
LOG_DIR.mkdir(parents=True, exist_ok=True)

# 日志格式
_FORMAT = "%(asctime)s | %(levelname)-7s | %(name)s | %(message)s"

# 轮转配置
LOG_MAX_BYTES = 10 * 1024 * 1024 # 10MB
LOG_BACKUP_COUNT = 5

setup_logging()

python
def setup_logging(level: int = logging.INFO, log_file: str = "app.log") -> None:
    """
    配置全局日志:root logger 输出到控制台与文件

    Args:
        level: 日志级别(默认 INFO)
        log_file: 日志文件名(位于 logs/ 目录下)
    """

控制台输出

python
console = logging.StreamHandler(sys.stdout)
console.setFormatter(formatter)
root.addHandler(console)

文件输出(按大小轮转)

python
file_handler = RotatingFileHandler(
    LOG_DIR / log_file,
    maxBytes=LOG_MAX_BYTES,      # 单文件上限 10MB
    backupCount=LOG_BACKUP_COUNT, # 保留 5 份备份
    encoding="utf-8",
)

日志轮转

当日志文件达到 10MB 时自动轮转:

logs/app.log ← 当前日志
logs/app.log.1 ← 最近一次轮转
logs/app.log.2 ← 倒数第二次
logs/app.log.3
logs/app.log.4
logs/app.log.5 ← 最早的备份(超过自动删除)

日志格式

2025-03-06 14:30:25,123 | INFO | modules.system.user.service | 用户登录成功

格式说明:

字段说明
asctime时间戳
levelname日志级别(右对齐7字符)
name模块名称
message日志内容

使用方式

在各模块中获取 logger:

python
import logging

logger = logging.getLogger(__name__)

logger.info("操作成功")
logger.warning("配置缺失")
logger.error(f"异常信息: {str(e)}")

框架日志集成

uvicorn 和 fastapi 的默认日志统一走 root logger:

python
for name in ("uvicorn", "fastapi"):
 lg = logging.getLogger(name)
 lg.handlers.clear()
 lg.propagate = True

温馨提示

setup_logging() 会检查是否已添加 handler(通过 _djangoadmin 标记),避免重复添加。可在应用启动时调用一次。

操作日志

除了应用日志外,还通过 src/middleware/operation_log.py 中间件自动记录用户的写操作日志,存储到数据库 fastapi_operation_log 表中。详见 操作日志 章节。

总结

日志系统通过 RotatingFileHandler 实现按大小轮转,单文件上限 10MB 保留 5 份备份,防止日志无限增长撑爆磁盘。控制台和文件双输出,格式统一包含时间戳、级别、模块名和消息内容。

小蚂蚁云团队 · 提供技术支持