Become a sponsor

说明
通过 Python 标准库 logging 实现结构化日志,支持控制台 + 文件双输出,日志文件按大小自动轮转。配置入口位于 src/core/logger.py。
日志配置位于 src/core/logger.py:
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 = 5def setup_logging(level: int = logging.INFO, log_file: str = "app.log") -> None:
"""
配置全局日志:root logger 输出到控制台与文件
Args:
level: 日志级别(默认 INFO)
log_file: 日志文件名(位于 logs/ 目录下)
"""console = logging.StreamHandler(sys.stdout)
console.setFormatter(formatter)
root.addHandler(console)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:
import logging
logger = logging.getLogger(__name__)
logger.info("操作成功")
logger.warning("配置缺失")
logger.error(f"异常信息: {str(e)}")uvicorn 和 fastapi 的默认日志统一走 root logger:
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 份备份,防止日志无限增长撑爆磁盘。控制台和文件双输出,格式统一包含时间戳、级别、模块名和消息内容。