当前位置: 首页 > news >正文

loguru 日志库快速入门

1.loguru

1.1 loguru 介绍

    loguru是一个功能强大且非常容易使用的第三方开源Python日志管理库。它建立在Python标准库中的logging模块之上,并提供了更加简洁直观、功能丰富的接口。github仓库地址:https://github.com/Delgan/loguru

1.2 安装

    想要快速体验其功能,首先需要安装该库,安装命令如下所示:

$ pip install loguru

1.3 基本用法

    在安装完成,我们就可以来快速体验其功能了,如下所示:

1.3.1 快速使用

from loguru import loggerlogger.info("这是一条INFO信息")
logger.debug("这是一条DEBUG信息")
logger.warning("这是一条WARNING信息")
logger.error("这是一条ERROR信息")
logger.critical("这是一条CRITICAL信息")

    输出结果如下所示:

01-快速使用演示.png

    loguru 日志输出默认格式如下:

  • 时间戳:日志记录的具体时间,格式通常为年-月-日 时:分:秒.毫秒
  • 日志级别:当前这条日志的严重性级别
  • 模块名称:表示日志来自哪个模块
  • 函数或作用域范围:表示日志来自哪个函数或作用域范围
  • 行号:触发日志所在的行号
  • 日志消息:实际的日志内容

    每条日志被特定的分隔符分隔并显示,默认分隔符为 |。同时loguru 也支持 使用颜色 来区分不同的日志级别,使得日志输出更加直观。如果默认功能不能满足需求,也可以进行自定义。

    loguru 默认会将日志输出到 standard error stream (stderr),loguru这样做是为了把日志输出与你的应用程序日志分开。如果需要更复杂的日志配置,你也可以自定义配置,例如将日志存储到文件、发送到网络服务中等。

1.3.2 日志级别

1.3.2.1 日志级别介绍

    通过前面的快速使用,相信你已经对loguru有了一个基本的了解。为了更好的根据日志级别进行分类,loguru 根据其日志的重要性,定义了日志级别分类。如下所示:

级别 方法 数值 目的
TRACE logger.trace() 5 最详细的日志记录,常用于追踪代码执行过程
DEBUG logger.debug() 10 用于记录详细的程序调试信息,一般用于开发阶段
INFO logger.info() 20 用于记录常规消息记录
SUCCESS logger.success() 25 用于记录一些操作成功的消息记录
WARNING logger.warning() 30 用于记录一些可能不是错误,但需要关注的消息记录
ERROR logger.error() 40 用于记录错误信息,这些错误可能会影响程序某些功能,但不会导致出现崩溃或停止运行
CRITICAL logger.critical() 50 用于记录非常严重的错误信息,这些错误通常会导致程序出现崩溃或停止运行

1.3.2.2 调整日志级别

    默认情况下,loguru的日志级别为DEBUG(10) 因此loguru会记录并显示日志级别为DEBUG及以上级别的消息记录。这也就意味着,在你第一次使用loguru打印日志时,会显示除TRACE级别以外的所有日志信息。

    如果想要开启TRACE级别的日志记录,可以自行调整最小日志级别,可以使用logger.add()方法,如下所示:

import sys
from loguru import logger# 修改日志最小级别
logger.add(sys.stderr,level="TRACE")logger.info("这是一条INFO信息")
logger.debug("这是一条DEBUG信息")
logger.warning("这是一条WARNING信息")
logger.error("这是一条ERROR信息")
logger.critical("这是一条CRITICAL信息")
logger.trace("这是一条TRACE信息")

    输出结果如下所示:

02-调整日志级别.png

    通过上述代码,我们导入了sys模块并且将输出重定向于sys.stderr。通过logger.add()方法添加了一个新的handler,这样我们就成功修改了loguru默认的日志级别,并将日志输出到sys.stderr中。

    通过调用loggeer.add()方法之后,会返回一个唯一值(handler_id),用于标识handler。后面我们可以调用方法logger.remove(handler_id)来移除handler。示例如下所示:

import sys
from loguru import loggerdef print_log():logger.info("~~"*30)logger.info("这是一条INFO信息")logger.debug("这是一条DEBUG信息")logger.warning("这是一条WARNING信息")logger.error("这是一条ERROR信息")logger.critical("这是一条CRITICAL信息")logger.trace("这是一条TRACE信息")if __name__ == '__main__':# 修改日志最小级别handler_id=logger.add(sys.stderr,level="TRACE")logger.info(f"handler id:{handler_id}")print_log()logger.remove(handler_id)print_log()

    输出结果如下所示:

03-删除自定义日志handler.png

    调用logger.remove()方法时,如果不传入参数值,则默认删除所有已经存在的handler,并且包含默认的handler。通过这个方法,我们就可以实现在创建新的handler之前,删除所有已经存在的handler。

loguru中默认的handler_id为0,如果需要删除默认的handler,在调用logger.remove()中传入0即可。如果需要删除其他新增的handler,为避免出现不是期望的结果,建议传入明确的handler_id值。

    在理解了loguru的日志级别之后,我们就可以根据需要选择合适的日志级别策略。例如在开发环境中,可以使用DEBUG级别,在生产环境中,可以使用WARNING或以上的日志级别。

1.3.3 自定义日志

1.3.3.1 日志参数

    在loguru中,add函数用于添加日志处理器。这个函数用于指定日志消息应该被发送到何处,例如控制台、文件或其他自定义的目的地。其定义如下所示:

def add(self,sink: Union[TextIO, Writable, Callable[[Message], None], Handler],*,level: Union[str, int] = ...,format: Union[str, FormatFunction] = ...,filter: Optional[Union[str, FilterFunction, FilterDict]] = ...,colorize: Optional[bool] = ...,serialize: bool = ...,backtrace: bool = ...,diagnose: bool = ...,enqueue: bool = ...,context: Optional[Union[str, BaseContext]] = ...,catch: bool = ...
) -> int: ...

    add函数主要参数介绍如下:

  • sink: 定义日志消息的输出位置,可以是文件路径、标准输出(stdout)、标准错误(stderr,默认)或其他自定义的输出位置。
  • format: 指定日志消息的格式,可以是简单的字符串,也可以是格式化字符串,支持各种字段插值。
  • level: 设置处理程序处理的日志消息的最低级别。比如设置为DEBUG,则处理程序将处理DEBUG以上所有级别的日志消息。
  • filter: 可选参数,用于添加过滤器,根据特定的条件过滤掉不需要的日志消息。
  • colorize: 布尔值,指定是否对日志消息进行着色处理,使日志在控制台中更易于区分。
  • serialize: 布尔值,指定是否对日志消息进行序列化处理,通常与enqueue=True一起使用,以确保多线程安全。
  • enqueue: 布尔值,指定是否将日志消息放入队列中处理,用于多线程应用中避免阻塞。
  • backtrace: 布尔值或字符串,指定是否记录回溯信息,默认为False。
  • diagnose: 布尔值,启用后,会在处理程序内部出现错误时记录诊断信息。
  • rotation: 日志文件轮换的配置,支持按大小或时间进行日志文件的轮换。
  • retention: 用于设置日志文件的保留时间。
  • compression: 布尔值,指定是否对轮换后的日志文件进行压缩处理。

1.3.3.2 开发实践

    loguru 默认的配置已经适用于大部分场景了,但也会有一些场景需要自定义日志的场景,我们可能过logger.add()方法来实现。

1.3.3.2.1 自定义format

    通过format可以自定义想要输出的内容,而不必输出其他额外的信息,示例如下所示:

import sys
from loguru import loggerdef print_log():logger.info("~~"*30)logger.info("这是一条INFO信息")logger.debug("这是一条DEBUG信息")logger.warning("这是一条WARNING信息")logger.error("这是一条ERROR信息")logger.critical("这是一条CRITICAL信息")logger.trace("这是一条TRACE信息")if __name__ == '__main__':logger.remove()# 修改日志最小级别handler_id=logger.add(sys.stderr,level="INFO",format="{message}")logger.info(f"handler id:{handler_id}")print_log()logger.remove(handler_id)

    输出结果如下所示:

handler id:1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这是一条INFO信息
这是一条WARNING信息
这是一条ERROR信息
这是一条CRITICAL信息

    在上述代码中,使用{message}占位符来表示要输出的日志消息。这样我们就得到了一个最小日志输出记录,而无其他额外日志记录,例如时间戳、日志级别、来源等信息。format还支持以下占位符:

  • {time}: 时间戳
  • {level}: 日志级别
  • {message}: 实际的日志消息
  • {name}: Module 名称
  • {line}: 行号

更多占位符的文档可查看官网文档:https://loguru.readthedocs.io/en/stable/api/logger.html#record

    在日常使用,为了更好的进行问题定位和分析日志,在日志记录中,至少包含时间戳日志级别日志内容这三项。示例如下所示:

import sys
from loguru import loggerdef print_log():logger.info("~~"*30)logger.info("这是一条INFO信息")logger.debug("这是一条DEBUG信息")logger.warning("这是一条WARNING信息")logger.error("这是一条ERROR信息")logger.critical("这是一条CRITICAL信息")logger.trace("这是一条TRACE信息")if __name__ == '__main__':logger.remove()# 修改日志最小级别handler_id=logger.add(sys.stderr,level="INFO",format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}")logger.info(f"handler id:{handler_id}")print_log()

    输出结果如下所示:

2025-09-27 18:29:40 | INFO | handler id:1
2025-09-27 18:29:40 | INFO | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2025-09-27 18:29:40 | INFO | 这是一条INFO信息
2025-09-27 18:29:40 | WARNING | 这是一条WARNING信息
2025-09-27 18:29:40 | ERROR | 这是一条ERROR信息
2025-09-27 18:29:40 | CRITICAL | 这是一条CRITICAL信息

其中时间格式自定义可参考文档: https://loguru.readthedocs.io/en/stable/api/logger.html

    loguru 也支持在format中使用颜色标记符来自定义输出的字符串颜色,例如<red><blue>等。这样在终端中显示日志消息,会自动转换对应的颜色进行显示。示例如下所示:

import sys
from loguru import loggerdef print_log():logger.info("~~"*30)logger.info("这是一条INFO信息")logger.debug("这是一条DEBUG信息")logger.warning("这是一条WARNING信息")logger.error("这是一条ERROR信息")logger.critical("这是一条CRITICAL信息")logger.trace("这是一条TRACE信息")if __name__ == '__main__':logger.remove()# 修改日志最小级别handler_id=logger.add(sys.stderr,level="INFO",format="<red><b>{time:YYYY-MM-DD HH:mm:ss}</b></red> | <blue>{name}:{line}</blue> | <green>{level}</green> | <yellow><b> {message} </b></yellow>")logger.info(f"handler id:{handler_id}")print_log()

    输出结果如下所示:

04-自家义format颜色.png

1.3.3.2.2 添加日志上下文

    在一部分场景中,我们可以添加一些额外的上下文信息,来帮助更好理解在记录日志时发生了什么事情。loguru也提供几种方式来添加上下文信息。其中最简单常见的方式,就是通过关键字参数来传值。示例如下所示:

import sys
from loguru import loggerif __name__ == '__main__':logger.remove()# 修改日志最小级别handler_id=logger.add(sys.stderr,level="INFO",format="{time:YYYY-MM-DD HH:mm:ss}| {level} | {message} | {extra}")logger.warning(f"日志级别为警告级别", log_level="WARNING")logger.info(f"handler id:",handler_id=handler_id)

    输出结果如下所示:

2025-09-27 18:55:58| WARNING | 日志级别为警告级别 | {'log_level': 'WARNING'}
2025-09-27 18:55:58| INFO | handler id: | {'handler_id': 1}

    上述通过占位符{extra}为日志添加了一个上下文信息,适合于一次性添加的场景,loguru 还提供了以下两个方法,来适用更多的场景:

  • bind(): 可以在所有handler实例上面添加额外的上下文信息,属于永久性添加
  • contextualize(): 添加临时性的上下文信息

    bind()方法非常适合于在所有的logger实例中添加额外的上下文信息。例如,在所有logger实例上添加诸如userId、sessionIdt。这种操作将大量节省在所有logger上手动添加额外上下文信息。示例代码如下所示:

import sys
from loguru import loggerif __name__ == '__main__':logger.remove()# 修改日志最小级别handler_id=logger.add(sys.stderr,level="INFO",format="{time:YYYY-MM-DD HH:mm:ss}| {level} | {message} | {extra}")user_logger=logger.bind(username="Surpass",user_id=999,session_id=8888)user_logger.info("I am Supass")user_logger.warning("loguru user logger.bind()")

    输出结果如下所示:

2025-09-27 19:09:50| INFO | I am Supass | {'username': 'Surpass', 'user_id': 999, 'session_id': 8888}
2025-09-27 19:09:50| WARNING | loguru user logger.bind() | {'username': 'Surpass', 'user_id': 999, 'session_id': 8888}

    contextualize()提供了一种非常干净的方式来添加一个临时的上下文信息,而且在操作完成后还会自动清理,示例代码如下所示:

import sys
from loguru import loggerif __name__ == '__main__':logger.remove()# 修改日志最小级别handler_id=logger.add(sys.stderr,level="INFO",format="{time:YYYY-MM-DD HH:mm:ss}| {level} | {message} | {extra}")with logger.contextualize(username="Surpass",user_id=999,session_id=8888):logger.info("Add temporarily context with contextualize")logger.warning("Hello Surpass",without_contextualize=True)

    在上述示例中,contextualize()事实上使用了Python的上下文管理器来临时添加额外的上下文信息,在with块里面,所有日志消息都会被添加额外的上下文信息,而一旦退出with块,则额外的上下文信息则会移除。

    输出结果如下所示:

2025-09-27 19:16:55| INFO | Add temporarily context with contextualize | {'username': 'Surpass', 'user_id': 999, 'session_id': 8888}
2025-09-27 19:16:55| WARNING | Hello Surpass | {'without_contextualize': True}
1.3.3.2.3 保存日志到文件

    将日志输出到终端在开发阶段非常有用,而在生产环境中,日志需要保存到文件中,供日后的问题定位和日志分析。loguru 允许将日志保存至文件,并设置日志切割日志保留期限策略。

  • Log rotation: 即日志切割,它通常决定在什么时候开启一个新的文件用于记录日志,可以由日志文件大小时间间隔其他条件等决定。支持以下几种方式的定义:
    文件大小: 当文件大小达到设定的大小后,创建新的日志文件,可以取的值有:100 MB2 GB
    时间: 即达到指定的时间就创建新的日志文件,可以取的值有:12:00
    时间间隔:即达到指定的时间间隔之后,就创建新的日志文件,可以取的值有: 12 hours3 days

  • Log retention: 即日志保留期限,它通常决定何时删除旧的日志文件,可以由基于数量基于时间来决定。支持以下几种方式的定义:
    基于数量: 即仅保留最近n个文件,如果设置为3,则表示仅保留最近3个日志文件,其他日志文件则删除
    基于时间:即仅保留最近设定时间的文件,如果设置为"1 week",则表示仅保留最近1雕的日志文件,其他日志文件则删除

from loguru import loggerif __name__ == '__main__':logger.remove()# 修改日志最小级别handler_id=logger.add("app.log",level="INFO",format="{time:YYYY-MM-DD HH:mm:ss}| {level} | {message} | {extra}",rotation="1 KB", # 即日志文件达到1KB,就创建一个新日志文件retention="1d"   # 即日志文件仅保留当天,其他则要删除)with logger.contextualize(username="Surpass",user_id=999,session_id=8888):logger.info("Add temporarily context with contextualize")logger.warning("Hello Surpass",without_contextualize=True)
1.3.3.2.4 错误处理和使用Loguru调试

    当我们在调试程序时,仅仅从日志中得知程序运行出现错误信息是不够的。我们需要知道错误是什么时候产生和为什么会产生错误等。loguru 提供了一个非常强大的功能来辅助查看详细的日志信息,例如错误信息、变量信息、上下文信息等。

  • 使用装饰器@logger.catch

    最简单抓取错误日志信息的方式就是使用装饰器@logger.catch。示例如下所示:

import sys
from loguru import logger@logger.catch
def divide(a:int,b:int)->int:return a/bif __name__ == '__main__':divide(10,0)

    上述代码在运行会出现报错,loguru产生的日志如下所示:

2025-09-27 20:06:45.140 | ERROR    | __main__:<module>:10 - An error has been caught in function '<module>', process 'MainProcess' (4288), thread 'MainThread' (24912):
Traceback (most recent call last):> File "C:\Users\Surpass\Documents\PyCharmProjects\TestNote\test-note\loguru-demo\main.py", line 10, in <module>divide(10,0)└ <function divide at 0x000001EE6B0C8860>File "C:\Users\Surpass\Documents\PyCharmProjects\TestNote\test-note\loguru-demo\main.py", line 6, in dividereturn a/b│ └ 0└ 10ZeroDivisionError: division by zero
  • 使用装饰器@logger.catch并添加其他额外信息

    使用基本装饰器@logger.catch可以做到不需要任何配置就能自动捕捉错误信息,但在一些大型工程中,我们通常需要自行处理和控制输出的错误信息,这个时候就需要能够自定义一些错误信息、日志级别、处理特定类型的错误。这个时候我们依然可以使用装饰器@logger.catch,并传递额外的参数即可。示例如下所示:

import sys
from loguru import logger@logger.catch(message="database connection failed",level="ERROR")
def connect_to_db(addr:str,port:int):if port < 1000:raise ValueError("Port must be greater than 1000")# 模拟连接数据库错误raise Exception("Connection to database failed")if __name__ == '__main__':connect_to_db("127.0.0.1",123)

    输出结果如下所示:

2025-09-27 20:18:06.998 | ERROR    | __main__:<module>:12 - database connection failed
Traceback (most recent call last):> File "C:\Users\Surpass\Documents\PyCharmProjects\TestNote\test-note\loguru-demo\main.py", line 12, in <module>connect_to_db("127.0.0.1",123)└ <function connect_to_db at 0x00000249B8400400>File "C:\Users\Surpass\Documents\PyCharmProjects\TestNote\test-note\loguru-demo\main.py", line 7, in connect_to_dbraise ValueError("Port must be greater than 1000")ValueError: Port must be greater than 1000
1.3.3.2.5 文件和控制台同时输出日志

    在前面的示例中,日志要么输出到文件,要么输出到控制台,现在想同时输出到文件和控制中,该如何操作了,示例代码如下所示:

import sys
from loguru import loggerformat="<green>{time:YYYY-MM-DD HH:mm:ss ZZ}</green> | <red><b>{level}</b></red> | <blue>{message}</blue> | {extra}"
level="DEBUG"config={"handlers": [{"sink":sys.stdout,"format":format,"level":level},{"sink":"app.log", "format":format,"level":level}],"extra": {"name":"Surpass"}
}logger.configure(**config)logger.info(logger.level(level))
logger.info("I am Surpass",level="INFO",age=28)
logger.warning("Test Warning",level="WARNING")
logger.debug("Test Debug",level="DEBUG")
logger.error("Test Error",level="ERROR")

    输出结果如下所示:

2025-09-27 21:28:22 +0800 | INFO | Level(name='DEBUG', no=10, color='<blue><bold>', icon='🐞') | {'name': 'Surpass'}
2025-09-27 21:28:22 +0800 | INFO | I am Surpass | {'name': 'Surpass', 'level': 'INFO', 'age': 28}
2025-09-27 21:28:22 +0800 | WARNING | Test Warning | {'name': 'Surpass', 'level': 'WARNING'}
2025-09-27 21:28:22 +0800 | DEBUG | Test Debug | {'name': 'Surpass', 'level': 'DEBUG'}
2025-09-27 21:28:22 +0800 | ERROR | Test Error | {'name': 'Surpass', 'level': 'ERROR'}

2.参考资料

  • https://github.com/Delgan/loguru
  • https://loguru.readthedocs.io/en/stable/index.html
  • https://realpython.com/python-loguru/

本文同步在微信订阅号上发布,如各位小伙伴们喜欢我的文章,也可以关注我的微信订阅号:woaitest,或扫描下面的二维码添加关注:

http://www.hskmm.com/?act=detail&tid=19377

相关文章:

  • lca学习笔记
  • 内存访问流程
  • .NET操作Word实现智能文档处理 - 内容查找替换与书签操作
  • day19_添加 修改
  • day18_查询功能 合并servlet
  • NOIP模拟赛 十七
  • day22_用户模块
  • 2025 丹东店推荐:丽格门窗,用 20 年技术沉淀守护家的舒适
  • NOIP2025模拟赛23
  • step
  • 2025 呼和浩特店推荐:丽格门窗,用 20 年技术沉淀守护家的温度
  • 深入解析:浏览器端音视频处理新选择:Mediabunny 让 Web 媒体开发飞起来
  • 2025 宁波门窗店推荐:丽格门窗,甬城品质家居的安心之选
  • 2025 贵阳门窗店优选:丽格门窗,用 20 年匠心适配高原宜居需求
  • 2025 济南门窗店选购指南:丽格门窗凭硬实力圈粉品质家庭
  • “鹏云杯”第十二届山东省大学生网络安全技能大赛 -- Crypto -- WriteUp
  • 服务器系统时间不对?Linux系统时间修改与同步全面指南
  • 9/27
  • 2025 常熟门窗店优选:丽格门窗,20 年技术沉淀的品质之选
  • 2025上海门窗店选购选丽格!20 年系统门窗经验,徐汇宜山路店品质之选
  • 实用指南:Apache、Nginx 和 Tomcat 的区别
  • python+uniapp基于微信小程序美食点餐实用的系统
  • JavaDoc
  • parted command for linuxg
  • 如何在不绑定Apple账号的情况下备份florr.io
  • AI智能体框架怎么选?7个主流工具详细对比解析
  • 原创OI试题 - L
  • 《深入浅出WPF》:8.3.2 自定义路由事件 事件注册类型为 EventHandlerReportTimeEventArgs,但.NET 事件包装器类型为 RoutedEventHandler
  • day 6
  • 2025 自动售货机工厂推荐 配备 Bystronic 激光切割机,快速周转准时交货