第三方 Python 库 Loguru 的基础使用
第三方 Python 库 Loguru 的基础使用
Python logging made (stupidly) simple —— 让日志记录简单到"愚蠢"。
本文是 Loguru 系列的第一篇,带你从零认识 Loguru,掌握日常开发中最常用的基础功能。读完这篇,你就能把
print()扔掉,用上正经的日志了。
系列文章导航:
- 【上篇】第三方 Python 库 Loguru 的基础使用(本文)
- 【下篇】第三方 Python 库 Loguru 的进阶实战
一、背景:为什么每个 Python 开发者都该重视日志?
做开发的朋友应该都有过这样的经历:程序跑着跑着出了问题,你一脸懵地盯着屏幕,心里想"到底是哪里炸了?"。这时候,如果你的代码里有完善的日志记录,翻一翻日志文件就能快速定位问题;如果没有……那就只能靠祈祷了。
日志就像是飞机的"黑匣子",它忠实地记录着程序运行过程中发生的一切。在正确的时间看到正确的日志,可能就是"5 分钟修好 bug"和"通宵排查到天亮"的区别。
但现实是,很多 Python 开发者(尤其是初学者)在调试时更习惯用 print()。不是不知道日志重要,而是标准库 logging 用起来太麻烦了。
来看一个最简单的例子,用标准 logging 输出一条日志:
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
logger.info("Hello, logging!")
看起来还行?但当你需要把日志同时输出到控制台和文件、按大小轮转、自动压缩、加点颜色……配置代码就会像滚雪球一样越写越多。很多团队甚至会专门封装一个 log_helper.py 来处理这些事情。
所以,有没有一种方案,能让我们开箱即用,一行代码搞定日志?
有的,它就是今天的主角——Loguru。
二、Loguru 是什么?
Loguru 是一个第三方 Python 日志库,GitHub 上有超过 23k 的 Star,可以说是目前最流行的 Python 日志方案之一。
它的设计理念很简单:日志记录不应该是一件痛苦的事。 你不需要配置 Handler、Formatter、Filter 这些东西,一行 from loguru import logger 就能开始干活。
官方的原话是这么说的:
Did you ever feel lazy about configuring a logger and used
print()instead? I did, yet logging is fundamental to every application. Using Loguru you have no excuse not to use logging from the start.
翻译过来就是:你有没有因为懒得配置 logger 而直接用 print()?凶手就是我。但有了 Loguru,你再也没有借口不写日志了。
Loguru 的核心特性
- 开箱即用:不需要任何配置,导入就能用
- 一个函数搞定一切:
add()代替了 Handler、Formatter、Filter 三件套 - 内置日志管理:轮转、保留、压缩,一个参数搞定
- 彩色输出:终端自动带颜色,不同级别一目了然
- 增强的异常追踪:比标准
logging多显示变量值,堪比调试器 - 线程安全、多进程安全:不用担心并发问题
- 兼容标准 logging:可以和已有的 logging 配置共存
三、Loguru vs 标准 logging:一张表看懂差异
在深入用法之前,我们先来对比一下两者的核心差异:
| 特性 | 标准 logging | Loguru |
|---|---|---|
| 上手难度 | 需要配置 Handler/Formatter/Filter | 一行导入,开箱即用 |
| 输出到文件 | 需要手动添加 FileHandler | 直接传文件路径字符串 |
| 日志轮转 | 需要 RotatingFileHandler | rotation="500 MB" 一个参数 |
| 日志保留 | 需要自己写清理逻辑 | retention="10 days" 自动清理 |
| 日志压缩 | 不支持,需要额外处理 | compression="zip" 自动压缩 |
| 彩色输出 | 不支持 | 终端自动彩色 |
| 异常追踪 | 默认信息较少 | 显示完整变量值 |
| 字符串格式化 | %s 或 %d |
{} 花括号风格,更现代 |
| 日志级别 | 5 个 | 7 个(多了 TRACE 和 SUCCESS) |
简单来说,Loguru 把你在标准 logging 里需要写几十行才能搞定的事情,压缩到了一两行。这不是魔法,这是好的 API 设计。
四、安装
pip install loguru
就这一行,没有额外依赖。支持 Python 3.5 及以上版本。
安装完可以验证一下:
from loguru import logger
print(logger)
# <loguru.logger handlers=[(id=0, level=10, sink=<stderr>)]>
看到类似输出,说明安装成功了。注意这里有一个默认的 handler,它会把日志输出到 stderr(标准错误流),这就是为什么你什么都不配置也能看到日志。
五、快速上手:第一个 Loguru 程序
5.1 基本日志输出
from loguru import logger
logger.debug("这是一条调试日志")
logger.info("这是一条信息日志")
logger.success("这是一条成功日志")
logger.warning("这是一条警告日志")
logger.error("这是一条错误日志")
logger.critical("这是一条严重错误日志")
运行后你会看到类似这样的输出(带颜色的):
2026-06-08 10:30:15.123 | DEBUG | __main__:<module>:3 - 这是一条调试日志
2026-06-08 10:30:15.123 | INFO | __main__:<module>:4 - 这是一条信息日志
2026-06-08 10:30:15.123 | SUCCESS | __main__:<module>:5 - 这是一条成功日志
2026-06-08 10:30:15.123 | WARNING | __main__:<module>:6 - 这是一条警告日志
2026-06-08 10:30:15.123 | ERROR | __main__:<module>:7 - 这是一条错误日志
2026-06-08 10:30:15.123 | CRITICAL | __main__:<module>:8 - 这是一条严重错误日志
注意看,每条日志自动包含了时间戳、日志级别、文件名、函数名、行号,这些信息在排查问题时非常有用。而且 SUCCESS 这个级别是 Loguru 独有的,标准 logging 里没有。
5.2 日志级别一览
Loguru 提供了 7 个内置日志级别,从低到高排列:
| 级别 | 数值 | 用途 | 颜色 |
|---|---|---|---|
TRACE |
5 | 比 DEBUG 更细粒度的追踪 | |
DEBUG |
10 | 调试信息,开发时用 | |
INFO |
20 | 常规运行信息 | |
SUCCESS |
25 | 操作成功(Loguru 独有) | 绿色 |
WARNING |
30 | 警告,可能有问题 | 黄色 |
ERROR |
40 | 错误,部分功能失败 | 红色 |
CRITICAL |
50 | 严重错误,程序可能无法继续 | 红色 |
默认情况下,TRACE 级别的日志不会显示。如果需要开启,可以手动设置:
logger.add(sys.stderr, level="TRACE")
5.3 字符串格式化
标准 logging 用 %s、%d 来格式化,Loguru 用更现代的花括号风格,和 Python 的 f-string 一样自然:
from loguru import logger
name = "张三"
age = 25
# 花括号风格
logger.info("用户 {} 今年 {} 岁", name, age)
# 关键字参数
logger.info("用户 {name} 今年 {age} 岁", name=name, age=age)
# 混合使用
logger.info("Python {},当然要用 {feature}!", 3.12, feature="f-strings")
这种方式比 %s 直观多了,而且不会出现 %s 和 %d 搞混的问题。
六、日志输出到文件
用标准 logging 输出到文件,你需要创建 FileHandler、设置 Formatter、添加到 Logger……用 Loguru 的话:
from loguru import logger
logger.add("app.log")
logger.info("这条日志会同时输出到控制台和 app.log 文件")
对,就这么简单。传一个文件路径字符串就行。而且注意,控制台的输出还在,add() 是"添加"一个新的输出目标,不是"替换"。
七、日志轮转、保留与压缩
这是 Loguru 最实用的功能之一,也是很多人从标准 logging 转过来的主要原因。
7.1 日志轮转(Rotation)
想象一下,你的服务跑了三个月,日志文件涨到了 50G,磁盘直接爆了。有了轮转机制,日志文件到了指定大小或时间就会自动"翻篇"。
from loguru import logger
# 按大小轮转:文件超过 500MB 就创建新文件
logger.add("app.log", rotation="500 MB")
# 按时间轮转:每天中午 12 点创建新文件
logger.add("app.log", rotation="12:00")
# 按时间间隔轮转:每周轮转一次
logger.add("app.log", rotation="1 week")
你也可以自定义轮转函数:
def should_rotate(message, file):
"""文件超过 10MB 就轮转"""
file.seek(0, 2) # 移到文件末尾
return file.tell() + len(message) > 10 * 1024 * 1024
logger.add("app.log", rotation=should_rotate)
7.2 日志保留(Retention)
磁盘空间是有限的,老的日志终究要清理。retention 参数帮你自动做这件事:
from loguru import logger
# 只保留最近 10 天的日志,超过的自动删除
logger.add("app.log", retention="10 days")
# 只保留最近 10 个日志文件
logger.add("app.log", retention=10)
再也不用写 cron 脚本去定时清理日志了,Loguru 帮你搞定。
7.3 日志压缩(Compression)
旧日志删掉可惜,留着又占空间?压缩一下:
from loguru import logger
# 轮转后的日志自动压缩为 zip 格式
logger.add("app.log", compression="zip")
# 也支持 gzip
logger.add("app.log", compression="gz")
7.4 三件套组合
rotation + retention + compression 组合起来,就是一个完整的日志生命周期管理方案:
logger.add(
"logs/app_{time:YYYY-MM-DD}.log",
rotation="00:00", # 每天零点轮转
retention="30 days", # 保留 30 天
compression="zip", # 旧日志压缩
encoding="utf-8", # 编码格式
)
这一行代码就实现了:每天自动创建新日志文件、自动清理 30 天前的旧文件、旧文件自动压缩。用标准 logging 实现同样的功能,至少得写几十行。
八、自定义日志格式
Loguru 默认的格式已经很好了,但你当然可以自定义:
from loguru import logger
import sys
# 先移除默认的控制台输出
logger.remove()
# 添加自定义格式的输出
logger.add(
sys.stdout,
format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | "
"<level>{level: <8}</level> | "
"<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> | "
"<level>{message}</level>",
colorize=True
)
logger.info("自定义格式的日志")
格式里常用的占位符:
| 占位符 | 含义 |
|---|---|
{time} |
时间戳,可指定格式如 {time:YYYY-MM-DD HH:mm:ss} |
{level} |
日志级别 |
{message} |
日志内容 |
{name} |
模块名 |
{function} |
函数名 |
{line} |
行号 |
{extra} |
通过 bind() 绑定的额外信息 |
颜色标签用 <green>、<red>、<cyan> 等,<level> 会根据日志级别自动变色。
注意: 如果 format 里没有颜色标签,就算设置 colorize=True 也没效果。另外,如果你不先 logger.remove(),控制台会出现两条重复的日志(默认的一条 + 你新加的一条)。
九、日志过滤
有时候你不想看到所有模块的日志,只想看某个模块的,或者只看某个级别以上的:
from loguru import logger
# 只记录 my_module 模块的日志
logger.add("app.log", filter="my_module", level="INFO")
# 用字典过滤:指定模块的日志级别
logger.add("app.log", filter={"my_module": "INFO", "other_module": "WARNING"})
# 用函数做更灵活的过滤
logger.add("special.log", filter=lambda record: "special" in record["extra"])
logger.bind(special=True).info("这条会写入 special.log")
logger.debug("这条不会")
十、异常捕获
10.1 基本用法:logger.exception()
在 try-except 中使用,自动记录完整堆栈:
from loguru import logger
try:
result = 1 / 0
except ZeroDivisionError:
logger.exception("除零错误")
10.2 增强的异常追踪
这是 Loguru 的"杀手级"功能。标准 logging 的异常追踪信息很简陋,Loguru 则会把变量的值都打出来,堪比调试器:
from loguru import logger
logger.add("error.log", backtrace=True, diagnose=True)
def func(a, b):
return a / b
def nested(c):
try:
func(5, c)
except ZeroDivisionError:
logger.exception("What?!")
nested(0)
输出的异常追踪信息长这样:
2026-06-08 10:30:15.123 | ERROR | __main__:nested:10 - What?!
Traceback (most recent call last):
File "test.py", line 12, in <module>
nested(0)
└ <function nested at 0x7f5c755322f0>
> File "test.py", line 8, in nested
func(5, c)
│ └ 0
└ <function func at 0x7f5c79fc2e18>
File "test.py", line 4, in func
return a / b
│ └ 0
└ 5
ZeroDivisionError: division by zero
看到了吗?变量 c 的值是 0,a 的值是 5,一目了然。这在排查复杂调用链的问题时简直是神器。
注意: diagnose=True 会把变量值打到日志里,生产环境要注意敏感数据泄露的风险。建议开发环境开启,生产环境关闭。
10.3 @logger.catch 装饰器
对于异常捕获,Loguru 还提供了一个更优雅的方式——用装饰器:
from loguru import logger
@logger.catch
def my_function(x, y, z):
return 1 / (x + y + z)
# 即使这里抛出 ZeroDivisionError,也会被 Loguru 捕获并记录
my_function(0, 0, 0)
用 @logger.catch 包一下,函数里的任何异常都会被自动捕获并输出详细的追踪信息。你再也不用到处写 try...except 了。
它也可以当上下文管理器用:
with logger.catch():
# 这段代码里的任何异常都会被捕获
do_something()
do_something_else()
十一、移除日志处理器
logger.add() 会返回一个 ID,你可以用这个 ID 来移除对应的处理器:
from loguru import logger
# 添加一个文件日志,获取 ID
file_id = logger.add("temp.log", level="INFO")
logger.info("这条会写入 temp.log")
# 移除这个文件日志
logger.remove(file_id)
logger.info("这条不会写入 temp.log 了")
# 不带参数的 remove() 会移除所有处理器(包括默认的 stderr)
# logger.remove() # 谨慎使用!移除后就没有日志输出了
这个功能在需要动态调整日志配置时很有用。比如在测试环境中,你可能想移除默认的控制台输出,换成自己的格式。
十二、自定义日志级别
Loguru 的 7 个内置级别通常够用了,但如果你有特殊需求,也可以自定义:
from loguru import logger
# 自定义一个 SNAKY 级别(数值 38,介于 WARNING 和 ERROR 之间)
logger.level("SNAKY", no=38, color="<yellow>", icon="🐍")
logger.log("SNAKY", "Here we go!")
自定义级别需要指定:
no:级别数值,决定了它在日志体系中的位置color:在终端中显示的颜色icon:在日志中显示的图标
十三、通过环境变量配置
不想改代码?Loguru 支持通过环境变量来调整默认行为:
# Linux / macOS
export LOGURU_LEVEL="DEBUG"
export LOGURU_FORMAT="{time} | <lvl>{message}</lvl>"
# Windows
set LOGURU_LEVEL=DEBUG
set LOGURU_FORMAT={time} | <lvl>{message}</lvl>
环境变量的名字和 logger.add() 的参数一一对应,非常直观。常用的环境变量:
LOGURU_LEVEL:默认日志级别LOGURU_FORMAT:默认日志格式LOGURU_DEBUG_COLOR:DEBUG 级别的颜色NO_COLOR:禁用颜色输出FORCE_COLOR:强制启用颜色输出
十四、小结
到这里,你已经掌握了 Loguru 最常用的基础功能:
- 一行导入:
from loguru import logger - 7 个日志级别:
trace、debug、info、success、warning、error、critical - 输出到文件:
logger.add("file.log") - 日志轮转:
rotation="500 MB"或rotation="00:00" - 日志保留:
retention="10 days" - 日志压缩:
compression="zip" - 自定义格式:
format=...,支持颜色标签 - 异常捕获:
logger.exception()或@logger.catch - 环境变量配置:
LOGURU_LEVEL、LOGURU_FORMAT等
这些功能已经能覆盖日常开发 80% 的需求了。如果你还想了解更多高级用法——比如结构化日志、上下文绑定、懒求值、与标准 logging 互操作、多进程安全等——请继续阅读本系列的第二篇:《第三方 Python 库 Loguru 的进阶实战》。
延伸阅读
- Loguru 官方文档 —— 最权威的参考资料
- Loguru GitHub 仓库 —— 源码和 Issue 都值得看
- Loguru API Reference —— 完整的 API 说明
更多推荐
所有评论(0)