Loguru 实战指南:一个 add() 搞定的 Python 日志

Loguru 是 Python 最受欢迎的第三方日志库,开箱即用、零配置。本文讲解 Loguru 的 add() 配置、serialize JSON 输出、bind/contextualize 上下文、自动轮转与压缩、@catch 异常捕获,以及接入观测云集中分析的路径。

最佳实践
Loguru 实战指南:一个 add() 搞定的 Python 日志技术指南封面

Loguru 是 Python 生态中最受欢迎的第三方日志库,核心理念是"消灭配置样板代码"——一个预配置好的全局 logger,加一行 logger.add() 就能完成格式、轮转、压缩、级别的全部定制。 如果说标准库 logging 是手动挡,Loguru 就是自动挡。

核心要点速览

  • 开箱即用:from loguru import logger 直接开打,默认彩色输出到 stderr、级别 DEBUG;
  • 一切配置走 logger.add():目标、格式、级别、轮转(rotation)、保留(retention)、压缩一行搞定;
  • JSON 输出加 serialize=True;上下文用 bind()(永久绑定)或 contextualize()(作用域绑定);
  • 异常捕获有神器 @logger.catch:装饰器自动记录完整堆栈;
  • 生产推荐 JSON 到 stdout/文件,DataKit 采集进观测云统一分析告警。

快速上手

pip install loguru
from loguru import logger

logger.debug("调试信息")
logger.info("服务启动成功")
logger.success("任务完成")     # Loguru 独有的 SUCCESS 级别
logger.warning("配置缺失,使用默认值")
logger.error("数据库连接失败")

无需任何配置,输出即带时间戳、级别、模块、函数、行号的彩色记录。Loguru 在标准级别之外还提供更细的 TRACE(5)与 SUCCESS(25)。

add():一个方法管所有事

先移除默认 handler(logger.remove()),再按需添加:

import sys
from loguru import logger

logger.remove()
logger.add(sys.stdout, level="INFO", serialize=True)  # JSON 输出到 stdout
logger.add(
    "logs/app_{time}.log",
    level="DEBUG",
    rotation="100 MB",      # 按大小轮转,也支持 "1 day"、"12:00" 等
    retention="7 days",     # 保留 7 天
    compression="gz",       # 历史文件 gzip 压缩
    serialize=True,
)

文件轮转、保留、压缩全部内置——这是 Loguru 相比标准库最直观的生产力提升。

生产化 JSON:默认太长?自己定义

serialize=True 的默认 JSON 很详尽(含 elapsed、thread、file 等全部信息),想要精简格式可用 patch 自定义序列化:

import json

def serialize(record):
    subset = {
        "time": record["time"].strftime("%Y-%m-%dT%H:%M:%S%z"),
        "level": record["level"].name,
        "message": record["message"],
        **record["extra"],
    }
    record["extra"]["serialized"] = json.dumps(subset, ensure_ascii=False)
    return record

logger = logger.patch(serialize)
logger.remove()
logger.add(sys.stdout, format="{extra[serialized]}")

上下文:bind 与 contextualize

# bind:创建带固定字段的子 logger
req_logger = logger.bind(request_id="req-abc-123", user_id="USR-9")
req_logger.info("订单创建成功")   # 自动携带两个字段

# contextualize:作用域内全部日志自动带字段(中间件场景)
def logging_middleware(get_response):
    def middleware(request):
        with logger.contextualize(request_id=str(uuid.uuid4())):
            return get_response(request)
    return middleware

异常处理:@catch 装饰器

@logger.catch
def risky_operation():
    return 1 / 0

异常自动以 ERROR 记录并附完整堆栈(还会标注各帧局部变量,排障极其友好)。也可用 logger.exception() 手动记录。

一个要补的课:拦截标准库日志

第三方库(requests、uvicorn 等)大多用标准库 logging,默认不会进 Loguru 管道。需要加一个 InterceptHandler 把它们重定向过来:

import logging

class InterceptHandler(logging.Handler):
    def emit(self, record):
        logger_opt = logger.opt(depth=6, exception=record.exc_info)
        logger_opt.log(record.levelname, record.getMessage())

logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)

接入观测云

观测云落地:Loguru 输出 JSON 到 stdout(容器)或 logs/app_*.log(虚拟机),由 DataKit 采集上报 。注意 Loguru 的 JSON 中级别在 record.level.name、时间在 record.time——用上面的自定义序列化把 level/time 提到顶层,Pipeline 的标准字段(time/status)映射会更直接 。随后即可在日志查看器request_id 串起单请求全部日志、用聚类分析归并异常模式 ;**监控器(日志检测)**配置"ERROR/CRITICAL 出现即告警"推送钉钉/企业微信/飞书 。

总结

Loguru 的生产配置公式:remove() 清场 → add(stdout, serialize=True) 给平台采集 → add(文件, rotation+retention+compression) 本地兜底 → InterceptHandler 收编第三方库。四步到位,日志体系即达生产水位。

常见问题(FAQ)

Q:Loguru 适合大型项目吗?
适合。bind/contextualize 的上下文管理、异步安全(enqueue=True)、完善的轮转机制都能支撑大型项目;唯一要注意的是用 InterceptHandler 把标准库日志收编,保证出口统一。

Q:serialize=True 的 JSON 字段太多怎么办?
logger.patch() 自定义序列化函数,只保留 time/level/message/extra 等需要的字段;字段越少,采集与存储成本越低。

Q:多进程/异步环境 Loguru 安全吗?
enqueue=True 参数即可让日志先入队列再由子进程写出,多进程与 asyncio 场景都安全。

Q:从标准库 logging 迁移到 Loguru 麻烦吗?
官方提供迁移指南;平滑做法是先用 InterceptHandler 把标准库调用桥接进 Loguru,再逐步把业务代码改写为 Loguru 调用。


系列阅读:Python 日志模块详解Structlog 实战指南

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台