fastapi: 第十一章:用loguru记录日志

一,官网:

https://loguru.org/

Loguru的优点是有哪些?

相比 Python 原生自带的 logging 模块,Loguru 在企业级项目(如 FastAPI)的日志写入上具有压倒性的优势,主要体现在以下几个核心技术点:
1. 真正的“线程安全”与“异步写入”(非阻塞)
  • 原生问题:Python 自带的 logging 在高并发下写入文件时,可能会因为文件锁导致请求线程阻塞,影响接口响应速度。
  • Loguru 优势:只需在 logger.add() 中加入 enqueue=True 选项,Loguru 就会自动启动一个底层的线程安全队列
    所有的日志写入操作都会变成异步非阻塞的,日志先进入内存队列,再由后台线程写入磁盘,这确保了 FastAPI 高并发接口的极致性能。
2. 开箱即用的“日志轮转(Rotation)”与“自动清理(Retention)”
在企业级运维中,日志文件的管理最让人头疼。Loguru 将其简化到了极致:
  • 按时间/大小滚动:可以指定 rotation="500 MB"rotation="00:00"(每天午夜)或 rotation="1 week"
  • 自动过期清理:设置 retention="30 days",它会自动帮你删掉 30 天前的旧日志,防止磁盘被撑爆。
  • 自动压缩:设置 compression="zip""gz",过期的历史日志会自动被压缩存档,极大地节省磁盘空间。
  • 对比原生:原生 logging 需要繁琐地配置 TimedRotatingFileHandler,且不支持自动压缩功能。
3. 无与伦比的异常堆栈深度捕获(Catch 与 Exception)
  • 诊断神器:当使用 logger.exception()@logger.catch 装饰器时,Loguru 打印的报错信息不仅包含传统的 Traceback,还会把崩溃那一行代码中,所有相关变量的当前数值(Value)直接打印出来!
  • 示例
    python
    @logger.catch
    def my_function(x, y):
        return x / y
    
    my_function(10, 0)
    Loguru 在日志里会直接告诉你:x = 10, y = 0,导致了 ZeroDivisionError。你连断点都不用打,看一眼日志就能瞬间定位 Bug
4. 彻底抛弃繁琐的 Handler 与 Formatter 配置
  • 原生痛点:原生 logging 需要分别创建 LoggerHandlerFormatter,再一级级 addHandler,配置复杂且容易漏掉。
  • Loguru 简化:全面采用“全局单例(Single Object)”设计理念。不需要 getLogger(__name__),整个项目任何地方都只需要 from loguru import logger
  • 增加一个输出渠道(控制台、文件、甚至钉钉机器人),只需要调用一次 logger.add() 即可,API 极其人性化。
5. 自带高颜值且现代化的色彩高亮
  • 在开发阶段,Loguru 的控制台输出会根据日志级别(INFO 绿、WARNING 黄、ERROR 红)自动渲染出非常现代化的色彩,并且时间、文件名、行号都清晰可见。
  • 在写入文件时,它会自动剥离这些颜色代码,保持纯文本格式,方便 Linux 下使用 grep 或对接 ELK 日志搜集系统。

二,安装第三方库:

pip install loguru

三,配置loguru日志

# app/core/logger.py
import os
import sys
from loguru import logger

# 确定日志存放目录
LOG_DIR = os.path.join(os.getcwd(), "logs")
os.makedirs(LOG_DIR, exist_ok=True)

# 1. 清除 Loguru 默认的控制台处理器
logger.remove()

# 2. 添加带颜色的控制台输出(开发环境)
logger.add(
    sys.stdout,
    level="INFO",
    format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
)

# 3. 添加文件输出(生产环境,按天轮转)
logger.add(
    os.path.join(LOG_DIR, "app_{time:YYYY-MM-DD}.log"),
    level="INFO",
    rotation="00:00",    # 每天午夜 0 点创建新日志
    retention="30 days", # 日志保留 30 天
    compression="zip",   # 历史日志自动压缩为 zip
    enqueue=True,        # 开启异步/线程安全写入
    format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}",
)

# 导出配置好的 logger
__all__ = ["logger"]

四,调用日志

# app/api/products.py
from fastapi import APIRouter

from app.core.logger import logger
from app.utils.response import success

router = APIRouter(prefix="/products", tags=["商品管理"])

@router.get("/one/{product_id}")
def get_product(product_id: int):
    logger.info("日志:An info message.")
    logger.success("日志:A success message.")
    logger.warning("日志:A warning message.")
    logger.error("日志:An error message.")
    logger.critical("日志:A critical message.")
    return {"id": product_id, "name": f"未知"}

五,查看效果

控制台:

image 

日志文件:

image

六,说明:

在生产环境中,日志的路径应该是在.env文件中指定,这个后面我们会演示这个配置

 

posted @ 2026-06-10 15:19  刘宏缔的架构森林  阅读(21)  评论(0)    收藏  举报