作者:WangQiaomei版本:1.0 

发布时间:2026-03-27

适用场景:Python 后端、FastAPI/Uvicorn 服务、日志统一格式化、多文件分级存储


🍋 前言:你是否被 Python 日志割裂问题搞疯?

做 Python 后端开发(尤其是FastAPI/Uvicorn)的同学一定踩过坑:

  • 项目里用loguru优雅打日志,格式好看、功能强
  • 但 Uvicorn、FastAPI 底层偏偏用标准 logging,日志格式混乱、两套体系
  • 日志分级、文件切割、过期清理还要分别配置,维护成本拉满

👉 本文带来终极解决方案标准 logging 全局拦截 + 无缝转发 loguru,一套配置统一所有日志,分级文件存储 + 自动轮转,源码直接复制即用!


🚀 方案核心优势

  1. 全日志统一:拦截所有标准 logging 日志(uvicorn/fastapi/ 第三方库),全部归 loguru 管理
  2. 分级存储:INFO/ERROR 日志分离文件,按天轮转、自动过期清理
  3. 精准溯源:日志行号 / 文件名精准指向真实调用处,无偏差
  4. 开箱即用:单模块封装,一行初始化,全局复用


🧩 核心组件详解

表格

组件核心作用
InterceptHandlerlogging→loguru 桥接器,全局拦截标准日志并转发
setup_logging()日志初始化入口,配置输出、轮转、保留策略
logger导出 loguru 实例,全项目统一调用

📂 日志文件落地策略

表格

日志文件输出级别轮转规则保留周期
logs/app_*.logINFO 及以上按天切割保留 30 天
logs/error_*.logERROR 及以上按天切割保留 90 天

❓ 为什么要做 logging 桥接?

Uvicorn/FastAPI 底层强制依赖标准 logging,直接使用会出现:

python

运行

# 原生logging输出(丑、格式乱)
logging.info("Request received")

# 桥接后统一loguru格式(整洁、可追踪)
# 2026-03-24 17:30:00 | INFO | uvicorn:serve:123 - Request received

桥接后:所有日志(自研 + 第三方库)格式、级别、输出完全统一,再也没有两套日志体系!


💻 核心代码(logging.py)

python

运行

# -*- coding: utf-8 -*-
"""
日志配置模块
核心功能:拦截所有标准logging日志,转发至loguru统一处理
作者:WangQiaomei
版本:1.0(2026/3/27)
"""
import sys
import logging
from loguru import logger

# ============================================================
# 日志桥接器:标准logging → loguru
# ============================================================
class InterceptHandler(logging.Handler):
    """
    全局桥接器:拦截标准logging所有日志,转发给loguru处理
    解决FastAPI/Uvicorn底层logging与loguru格式割裂问题
    """
    def emit(self, record: logging.LogRecord) -> None:
        # 日志级别映射
        try:
            level = logger.level(record.levelname).name
        except ValueError:
            level = record.levelno

        # 追溯真实调用栈(跳过logging内部帧,保证行号精准)
        frame, depth = sys._getframe(6), 6
        while frame and frame.f_code.co_filename == logging.__file__:
            frame = frame.f_back
            depth += 1

        # 转发至loguru记录
        logger.opt(depth=depth, exception=record.exc_info).log(
            level, record.getMessage()
        )

# ============================================================
# 日志全局初始化配置
# ============================================================
def setup_logging() -> None:
    # 禁用标准logging默认处理器,防止重复输出
    logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
    
    # 屏蔽无关第三方库冗余日志
    for logger_name in [
        "uvicorn", "uvicorn.access", "uvicorn.error",
        "fastapi", "urllib3", "requests"
    ]:
        logging.getLogger(logger_name).handlers = [InterceptHandler()]
        logging.getLogger(logger_name).propagate = False

    # 清空loguru默认配置
    logger.remove()

    # 1. INFO级别日志:文件输出,按天轮转,保留30天
    logger.add(
        sink="logs/app_{time:YYYY-MM-DD}.log",
        level="INFO",
        rotation="00:00",  # 每日零点切割
        retention=30,      # 保留30天
        encoding="utf-8",
        format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {name}:{function}:{line} - {message}"
    )

    # 2. ERROR级别日志:单独文件,按天轮转,保留90天
    logger.add(
        sink="logs/error_{time:YYYY-MM-DD}.log",
        level="ERROR",
        rotation="00:00",
        retention=90,
        encoding="utf-8",
        format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {name}:{function}:{line} - {message}"
    )

    # 3. 控制台输出(开发调试用)
    logger.add(
        sink=sys.stdout,
        level="INFO",
        colorize=True,
        format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level}</level> | <cyan>{name}:{function}:{line}</cyan> - <message>{message}</message>"
    )

# 导出loguru实例,全项目统一调用
__all__ = ["setup_logging", "logger"]

🔧 一行接入全项目

在项目入口文件(main.py仅需一行初始化

python

运行

from core.logging import setup_logging

# 初始化全局日志
setup_logging()

# 后续全项目使用
from core.logging import logger

logger.info("业务日志测试")
logger.error("异常日志测试")

🎯 最终效果展示

控制台输出(彩色、带行号)

plaintext

2026-03-24 17:30:00 | INFO | main:<module>:10 - 业务日志测试
2026-03-24 17:30:01 | ERROR | main:<module>:11 - 异常日志测试

文件输出(分级存储、自动切割)

plaintext

logs/
├─ app_2026-03-24.log    # INFO+日志,保留30天
└─ error_2026-03-24.log  # ERROR+日志,保留90天

Uvicorn 底层日志也被统一接管

plaintext

2026-03-24 17:35:22 | INFO | uvicorn.server:serve:77 - Uvicorn running on http://127.0.0.1:8000

📌 总结

这套logging→loguru 桥接方案,完美解决 Python 后端日志割裂问题,分级存储、自动轮转、全局统一,适配 FastAPI/Uvicorn 等主流框架,生产环境直接落地!

源码高度封装、无侵入性,复制即用,再也不用为两套日志体系头疼~

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐