loguru 实测:Python 日志零配置开箱,rotation、catch、JSON 序列化等六个场景全流程记录

举报
岚枫 发表于 2026/10/18 11:45:46 2026/10/18
【摘要】 loguru 是 GitHub 约 2.4 万星的 Python 日志库,一个 logger 免配置。本文在 Windows + Python 3.13.12 下从安装开始,实测默认输出、文件轮转、异常捕获、JSON 序列化、多进程队列与拦截标准 logging 六个场景,代码与输出全部为实跑记录,并验证 Windows 控制台中文与 emoji 无乱码。

loguru 实测:Python 日志零配置开箱,rotation、catch、JSON 序列化六个场景全流程记录

Python 自带 logging 模块的能力没问题,问题是每次开新项目都要重复配置 Formatter、Handler、Filter,轮转配置繁琐、压缩要自己接。loguru 把这个过程压缩成一行 from loguru import logger,它在 GitHub 有约 2.4 万星。本文在 Windows 11 + Python 3.13.12 环境把它从安装到六个常用场景完整跑了一遍,所有输出都是实跑记录。

环境与安装

实测环境:Windows 11、Python 3.13.12,装在 venv 里隔离。安装一行:

pip install loguru

装完 0.7.3,纯 Python 包,Windows 上不需要编译工具链,也没有平台特定的二进制依赖。

场景一:默认输出,开箱即用

不写任何配置,一个脚本跑完六个级别:

import sys
from loguru import logger

print("=== 1. 默认输出 ===")
logger.remove()
logger.add(sys.stderr, level="DEBUG")
logger.trace("trace 消息")
logger.debug("debug 消息")
logger.info("普通信息")
logger.success("成功消息")

stderr 直接输出带时间戳、级别、模块名和行号的彩色日志(行号对应上面脚本,print 行输出从略):

2026-10-18 09:55:55.649 | DEBUG    | __main__:<module>:8 - debug 消息
2026-10-18 09:55:55.650 | INFO     | __main__:<module>:9 - 普通信息
2026-10-18 09:55:55.650 | SUCCESS  | __main__:<module>:10 - 成功消息

TRACE(第 7 行)没出现,因为默认最低级别是 DEBUG,想看到就再 add 一个 level="TRACE" 的 sink,先 remove() 掉默认 sink,不然 DEBUG 以上的日志会被两个 sink 重复输出。SUCCESS 是 loguru 独有的级别,夹在 INFO 和 WARNING 之间,用来标记操作成功完成。

Python 3.13 的 Windows 控制台下中文和 emoji 都直接正常输出,未做额外处理。

场景二:写文件,rotation 与 retention

logger.add("app.log", rotation="10 KB", retention=3, encoding="utf-8")

实测灌入 300 条中文业务日志,按 10 KB 阈值切出 3 个文件,文件名带切分时间戳和微秒:

app.2026-10-18_09-55-55_653725.log
app.2026-10-18_09-55-55_676354.log
app.2026-10-18_09-55-55_694411.log
app.log(当前写入中)

retention=3 表示只保留最近 3 个轮转文件,旧文件自动清理。rotation 还支持 "00:00"(每天零点)、"1 week" 这类写法,比 logging.handlers.TimedRotatingFileHandler 的配置短很多。

场景三:@logger.catch 自动兜异常

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

ZeroDivisionError 连完整堆栈和出错时的变量值一起进日志,程序不中断(末尾省略部分帧):

2026-10-18 10:58:49.845 | ERROR | __main__:<module>:10 - An error has been caught in function '<module>', process 'MainProcess' (17936), thread 'MainThread' (13028):
Traceback (most recent call last):
  File "E://gif-work//demo2.py", line 10, in <module>
    boom(0)
    └ <function boom at 0x000001EDEBF11300>
  File "E://gif-work//demo2.py", line 9, in boom
    return 1 / x
               └ 0
ZeroDivisionError: division by zero

堆栈里直接标出变量当时的值(└ 0),排查时不用猜。一个装饰器搞定全局兜底,适合脚本类程序保命,比层层 try/except 省事。

场景四:serialize 直接出 JSON

logger.add("json.log", serialize=True)
logger.bind(user="张三", order_id="A1001").info("订单创建")

每条日志输出成单行 JSON,bind 的字段落在 record.extra 里,时间、级别、异常都是标准字段(中间字段已省略):

{"text": "2026-10-18 09:55:55.719 | INFO | __main__:<module>:38 - 订单创建\n",
 "record": {"exception": null, "extra": {"user": "张三", "order_id": "A1001"},
 "level": {"name": "INFO", "no": 20}, "line": 38, "message": "订单创建",
 "process": {"id": 33584, "name": "MainProcess"}, "time": {"repr": "2026-10-18 09:55:55.719264+08:00"}}}

可以直接喂给日志采集系统,不用自己写 JSON formatter。中文按原样输出,不做 unicode 转义。

场景五:enqueue 多进程安全

logger.add("enq.log", enqueue=True)

enqueue=True 之后写文件走 multiprocessing-safe 队列,多进程同时写不会交错,一个参数解决 logging 下要么自己搭 QueueHandler、要么忍受行交错的问题。

实测落盘内容:

2026-10-18 09:55:55.856 | INFO     | __main__:<module>:42 - 多进程安全写入

两个实践注脚:enqueue 之后日志调用变为非阻塞,进程退出前调 logger.complete() 冲刷队列,否则队尾日志可能丢失;spawn 启动的子进程不继承 sink,需要自行 add。

场景六:拦截标准 logging

老项目或第三方库还在用 logging 的话,挂一个 handler 就能把它们的日志统一收进 loguru。实测代码(depth 动态计算,避免硬编码在模块级调用下定位错帧):

import sys
import logging
from loguru import logger

class InterceptHandler(logging.Handler):
    def emit(self, record):
        try:
            level = logger.level(record.levelname).name
        except ValueError:
            level = record.levelno
        frame, depth = sys._getframe(1), 1
        while frame is not None and frame.f_code.co_filename == logging.__file__:
            frame = frame.f_back
            depth += 1
        logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())

logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
logging.getLogger("third_party_lib").warning("来自第三方库的日志")
logging.info("标准库 logging 的消息被拦进 loguru")

实跑输出,标准库的消息换上了 loguru 的格式,源码位置也准:

2026-10-18 10:58:49.848 | WARNING | __main__:<module>:26 - 来自第三方库的日志
2026-10-18 10:58:49.848 | INFO    | __main__:<module>:27 - 标准库 logging 的消息被拦进 loguru

迁移期不用一次性改完所有调用点。两个细节:record.levelname 不在 loguru 已注册级别时回退用 levelno,否则 logger.log() 会抛 ValueError;basicConfig 加 force=True,root 已有 handler 时它默认是静默 no-op。

适合与不适合

适合:脚本、中小型服务、需要快速搭结构化日志的场景。安装即用、配置一行,轮转、压缩、序列化、多进程都在。

不适合:重度依赖 logging 生态现成 Handler(SysLog、SMTP、NTEventLog 等)的大型项目,这些在 loguru 里要自己包一层,迁移前先评估依赖面。

实测全部可复现:Windows 11 + Python 3.13.12 + loguru 0.7.3。

参考与协议:loguru 开源仓库 https://github.com/Delgan/loguru ,MIT 协议,部分用法示例参考官方 README。本文为原创实测记录,文中代码与输出均为 2026-10-18 实跑产生。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。