Loguru 实战指南:一个 add() 搞定的 Python 日志
Loguru 是 Python 最受欢迎的第三方日志库,开箱即用、零配置。本文讲解 Loguru 的 add() 配置、serialize JSON 输出、bind/contextualize 上下文、自动轮转与压缩、@catch 异常捕获,以及接入观测云集中分析的路径。
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 实战指南