Loguru 全面教程:常用 API 串联与实战指南

19 阅读10分钟

大家好,我是jobleap.cn的小九。

Loguru 是 Python 中一款简洁、强大且易用的日志库,核心优势是零配置启动、API 直观、功能全面(支持日志轮转、过滤、格式化、异常捕获等),无需像标准库 logging 那样繁琐配置。本文将从基础到进阶,串联所有常用 API,结合实战示例帮你彻底掌握 Loguru 的用法。

一、准备工作:安装 Loguru

首先通过 pip 安装(支持 Python 3.5+):

pip install loguru

核心特性:

  • 无需手动创建 logger 实例,直接导入即用
  • 默认输出彩色日志到控制台,格式清晰
  • 一行代码实现文件日志、轮转、压缩等高级功能
  • 内置异常捕获与堆栈追踪功能

二、基础用法:快速上手

Loguru 的核心是 logger 对象,直接导入即可使用,无需额外配置。

2.1 基本日志输出(默认控制台)

Loguru 定义了 7 个日志级别(从低到高):TRACE < DEBUG < INFO < SUCCESS < WARNING < ERROR < CRITICAL,对应 7 个常用方法:

from loguru import logger

# 不同级别日志输出
logger.trace("最详细的调试信息(默认不显示)")
logger.debug("调试信息")
logger.info("普通业务信息")
logger.success("操作成功")  # Loguru 独有的 SUCCESS 级别
logger.warning("警告信息")
logger.error("错误信息")
logger.critical("严重错误(如程序崩溃)")

运行结果(控制台彩色输出):

2025-11-26 10:00:00.123 | DEBUG    | __main__:<module>:4 - 调试信息
2025-11-26 10:00:00.124 | INFO     | __main__:<module>:5 - 普通业务信息
2025-11-26 10:00:00.124 | SUCCESS  | __main__:<module>:6 - 操作成功
2025-11-26 10:00:00.124 | WARNING  | __main__:<module>:7 - 警告信息
2025-11-26 10:00:00.124 | ERROR    | __main__:<module>:8 - 错误信息
2025-11-26 10:00:00.125 | CRITICAL | __main__:<module>:9 - 严重错误(如程序崩溃)
  • 默认不显示 TRACE 级别(需手动开启)
  • 日志格式默认包含:时间、级别、模块名、函数名、行号、日志信息

2.2 核心 API:logger.add() 详解(日志写入文件)

add() 是 Loguru 最核心的 API,用于添加日志输出目标(文件、网络、自定义 sink 等),支持所有高级功能。其常用参数如下:

参数作用
sink输出目标(文件路径字符串、文件对象、自定义函数/类)
level日志级别阈值(低于该级别的日志不输出)
format自定义日志格式
rotation日志轮转规则(按大小、时间、文件数)
retention日志保留策略(保留天数、文件数)
compression日志压缩格式(zip/gz/bz2/xz)
filter日志过滤规则(函数/字典)
encoding文件编码(如 "utf-8")

示例 1:基本文件日志(无轮转)

from loguru import logger

# 添加文件输出(所有级别≥DEBUG的日志写入文件)
logger.add(
    sink="app.log",          # 日志文件路径
    level="DEBUG",           # 日志级别阈值
    format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}",  # 自定义格式
    encoding="utf-8"         # 避免中文乱码
)

# 测试日志
logger.debug("写入文件的调试信息")
logger.error("写入文件的错误信息")

示例 2:日志轮转(生产环境必备)

解决单文件过大问题,支持 3 种轮转方式:

from loguru import logger

# 方式 1:按文件大小轮转(每个文件最大 500MB,自动创建新文件)
logger.add("app_size.log", rotation="500 MB")

# 方式 2:按时间轮转(每天凌晨 00:00 新建文件)
logger.add("app_daily.log", rotation="00:00")

# 方式 3:按时间间隔轮转(每 1 周新建文件)
logger.add("app_weekly.log", rotation="1 week")

# 方式 4:限制文件数量(最多保留 10 个文件,超量自动删除最旧的)
logger.add("app_limit.log", rotation="500 MB", retention=10)

# 方式 5:保留指定天数(最多保留 7 天的日志)
logger.add("app_retention.log", rotation="00:00", retention="7 days")

# 方式 6:轮转后自动压缩(节省磁盘空间)
logger.add("app_compress.log", rotation="500 MB", compression="zip")

三、进阶用法:串联核心 API

3.1 自定义日志格式

通过 format 参数自定义日志字段,支持 Loguru 内置变量(完整变量列表见官方文档),常用变量:

  • {time}:日志时间(可指定格式,如 {time:YYYY-MM-DD HH:mm:ss.SSS}
  • {level}:日志级别(可显示颜色 {level: <8} 左对齐)
  • {message}:日志内容
  • {name}:模块名
  • {function}:函数名
  • {line}:代码行号
  • {extra}:通过 bind() 绑定的额外上下文信息
from loguru import logger

# 自定义格式(包含模块、函数、行号和上下文信息)
logger.add(
    "custom_format.log",
    format="""{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | 
              模块:{name} | 函数:{function} | 行号:{line} | 
              信息:{message} | 上下文:{extra[user_id]}""",
    level="INFO"
)

# 绑定上下文信息(通过 bind() 添加 extra 字段)
logger.bind(user_id=1001).info("用户登录成功")
logger.bind(user_id=1002).error("用户支付失败")

输出效果:

2025-11-26 10:30:00.123 | INFO     | 模块:__main__ | 函数:<module> | 行号:12 | 信息:用户登录成功 | 上下文:1001
2025-11-26 10:30:00.124 | ERROR    | 模块:__main__ | 函数:<module> | 行号:13 | 信息:用户支付失败 | 上下文:1002

3.2 日志过滤:filter 参数

通过 filter 筛选需要输出的日志,支持 2 种用法:

用法 1:按级别/模块过滤(字典格式)

from loguru import logger

# 只输出 ERROR 级别且模块名为 "payment" 的日志
logger.add(
    "filtered.log",
    filter={"level": "ERROR", "name": "payment"}
)

用法 2:自定义过滤函数(灵活控制)

from loguru import logger

# 过滤规则:只保留 user_id=1001 或级别≥ERROR 的日志
def filter_log(record):
    user_id = record["extra"].get("user_id")
    return user_id == 1001 or record["level"].no >= logger.level("ERROR").no

# 添加带过滤的文件输出
logger.add("custom_filter.log", filter=filter_log)

# 测试:只有 user_id=1001 和 ERROR 日志会被写入
logger.bind(user_id=1001).info("用户1001的信息")
logger.bind(user_id=1002).info("用户1002的信息(被过滤)")
logger.error("错误日志(不被过滤)")

3.3 异常捕获:logger.exception()@logger.catch

Loguru 简化了异常日志记录,无需手动拼接堆栈信息。

用法 1:logger.exception()(捕获显式异常)

try-except 中使用,自动记录完整堆栈:

from loguru import logger

logger.add("exception.log", level="DEBUG")

try:
    1 / 0  # 触发除零错误
except Exception as e:
    # 自动记录异常类型、消息和完整堆栈
    logger.exception("除零错误发生:{}", e)

用法 2:@logger.catch(捕获函数内所有异常)

装饰器形式,自动捕获函数执行过程中的所有未处理异常:

from loguru import logger

logger.add("catch_exception.log", level="DEBUG")

# 装饰器:自动捕获函数内的异常并记录
@logger.catch
def calculate(a, b):
    return a / b

# 调用函数(触发异常,自动记录)
calculate(1, 0)

日志输出(包含完整堆栈追踪):

2025-11-26 11:00:00.123 | ERROR    | __main__:calculate:8 - An error has been caught in function 'calculate', process 'MainProcess' (1234), thread 'MainThread' (5678)
Traceback (most recent call last):
  File "test.py", line 11, in <module>
    calculate(1, 0)
  File "test.py", line 8, in calculate
    return a / b
ZeroDivisionError: division by zero

3.4 上下文绑定:logger.bind()logger.patch()

用于添加固定上下文信息(如用户 ID、请求 ID、服务器 IP 等),避免重复写入。

用法 1:logger.bind()(静态绑定)

绑定后返回新的 logger 实例,后续调用该实例会携带上下文:

from loguru import logger

logger.add("context.log", format="{time} | {level} | user_id:{extra[user_id]} | {message}")

# 绑定 user_id=1001,返回新 logger
user_logger = logger.bind(user_id=1001)
user_logger.info("登录系统")
user_logger.warning("密码即将过期")

# 绑定新的上下文(不影响原实例)
admin_logger = logger.bind(user_id=9999, role="admin")
admin_logger.success("执行管理员操作")

用法 2:logger.patch()(动态绑定)

通过函数动态生成上下文信息(如请求 ID 每次不同):

from loguru import logger
import uuid

logger.add("dynamic_context.log", format="{time} | req_id:{extra[req_id]} | {message}")

# 动态生成请求 ID(每次调用日志方法时执行)
def generate_req_id(record):
    record["extra"]["req_id"] = str(uuid.uuid4())[:8]  # 生成 8 位随机 ID

# 绑定动态上下文
req_logger = logger.patch(generate_req_id)

# 每次调用都会生成新的 req_id
req_logger.info("处理用户请求")
req_logger.error("请求参数错误")

3.5 日志移除:logger.remove()

logger.add() 会返回一个唯一 ID,通过该 ID 可移除对应的输出目标(如关闭文件日志):

from loguru import logger

# 添加文件日志,获取 ID
file_log_id = logger.add("temp.log", level="INFO")

# 输出日志(会写入文件)
logger.info("测试移除前的日志")

# 移除文件日志(后续日志不再写入 temp.log)
logger.remove(file_log_id)

# 后续日志只输出到控制台
logger.info("测试移除后的日志")

# 移除所有输出目标(谨慎使用!后续无日志输出)
# logger.remove()

3.6 全局配置:logger.configure()

批量配置 logger 的输出目标、格式等,适合统一管理:

from loguru import logger

# 批量配置:同时输出到控制台和文件
logger.configure(
    handlers=[
        # 控制台输出(彩色、INFO级别以上)
        {
            "sink": sys.stderr,
            "level": "INFO",
            "format": "<green>{time}</green> | <level>{message}</level>"
        },
        # 文件输出(轮转、压缩、保留7天)
        {
            "sink": "app_config.log",
            "level": "DEBUG",
            "format": "{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}",
            "rotation": "1 day",
            "retention": "7 days",
            "compression": "gz"
        }
    ]
)

logger.debug("配置后的调试日志(仅文件输出)")
logger.info("配置后的信息日志(控制台+文件输出)")

3.7 自定义 Sink:扩展输出目标

sink 不仅支持文件路径,还可以是函数类实例,实现日志转发到数据库、消息队列等自定义场景。

示例:自定义 Sink 函数(日志写入数据库)

from loguru import logger
import sqlite3

# 初始化数据库
conn = sqlite3.connect("log.db")
cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS logs (time TEXT, level TEXT, message TEXT)")
conn.commit()

# 自定义 sink 函数:将日志写入 SQLite
def db_sink(record):
    time = record["time"].strftime("%Y-%m-%d %H:%M:%S")
    level = record["level"].name
    message = record["message"]
    # 插入数据库
    cursor.execute("INSERT INTO logs (time, level, message) VALUES (?, ?, ?)", (time, level, message))
    conn.commit()

# 添加自定义 sink
logger.add(db_sink, level="INFO")

# 测试:日志会同时输出到控制台和数据库
logger.info("数据库日志测试")
logger.error("数据库错误日志")

四、综合实战:生产环境日志配置

下面整合所有常用 API,实现一个生产级别的日志配置:

from loguru import logger
import sys

# 移除默认控制台输出(可选,重新自定义)
logger.remove()

# 配置日志:控制台 + 文件轮转 + 过滤 + 格式化
def setup_logger():
    # 1. 控制台输出(彩色、INFO级别以上)
    logger.add(
        sink=sys.stderr,
        level="INFO",
        format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
               "<level>{level: <8}</level> | "
               "<cyan>{name}</cyan>:<cyan>{line}</cyan> - "
               "<level>{message}</level>",
        colorize=True  # 启用彩色输出
    )

    # 2. 文件输出(按大小轮转、压缩、保留15天、过滤ERROR以上日志)
    logger.add(
        sink="logs/app_{time:YYYY-MM-DD}.log",  # 文件名包含日期
        level="DEBUG",
        format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {name}:{function}:{line} | {extra[req_id]} | {message}",
        rotation="100 MB",  # 每100MB轮转
        retention="15 days",  # 保留15天
        compression="gz",  # 压缩为gz格式
        encoding="utf-8",
        filter=lambda record: record["level"].no >= logger.level("DEBUG").no  # 只保留DEBUG以上
    )

    # 3. 错误日志单独文件(仅记录ERROR以上级别)
    logger.add(
        sink="logs/error_{time:YYYY-MM-DD}.log",
        level="ERROR",
        format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level} | {name}:{function}:{line} | {extra[req_id]} | {message}\n{exception}",
        rotation="1 day",
        retention="30 days",
        compression="zip"
    )

# 初始化日志配置
setup_logger()

# 模拟 Web 请求场景:绑定请求 ID
def handle_request(user_id, req_id):
    # 绑定上下文(req_id 和 user_id)
    req_logger = logger.bind(req_id=req_id, user_id=user_id)
    req_logger.info("开始处理用户请求")
    try:
        # 模拟业务逻辑
        if user_id == 0:
            raise ValueError("用户ID不能为0")
        req_logger.success("请求处理完成")
    except Exception as e:
        req_logger.exception("请求处理失败:{}", e)

# 测试
if __name__ == "__main__":
    handle_request(user_id=1001, req_id="req-20251126-001")
    handle_request(user_id=0, req_id="req-20251126-002")  # 触发异常

五、关键 API 总结

API用途核心场景
logger.<level>()输出对应级别日志日常日志记录
logger.add()添加日志输出目标(文件/自定义sink)文件日志、轮转、压缩
logger.remove()移除输出目标关闭文件日志、动态调整
logger.bind()绑定上下文信息携带用户ID、请求ID
logger.patch()动态生成上下文信息随机请求ID、动态环境变量
logger.exception()记录异常及堆栈显式异常捕获
@logger.catch自动捕获函数异常批量异常监控(如接口、任务)
logger.configure()全局批量配置日志统一管理输出目标和格式

六、常见问题

  1. 中文乱码:在 add() 中指定 encoding="utf-8"
  2. 默认控制台不显示 TRACE 级别:添加 logger.add(sys.stderr, level="TRACE") 手动开启。
  3. 日志轮转不生效:检查 rotation 参数格式(如 "500 MB" 带空格,"00:00" 是字符串)。
  4. 异常日志没有堆栈:使用 logger.exception() 而非 logger.error()

通过以上教程,你已经掌握了 Loguru 的所有常用 API 和实战场景。Loguru 的设计哲学是“简洁而不简单”,日常开发中可直接套用本文的生产级配置,无需额外复杂操作。更多高级功能可参考 Loguru 官方文档