1.为什么选用loguru
python自带的logging模块,需要完成复杂的配置才能很好的使用,基本生产环境都需要进行二次包装。
loguru专门梳理了这方面的问题,可以通过简单直接的配置完成你的需求。
简单的例子:
1 2 | from loguru import logger logger.info( "hello from loguru" ) |
输出到标准输出:
1 | 2023-09-10 09:38:52.275 | INFO | __main__:<module>:2 - hello from loguru |
输出到日志文件:
1 2 3 4 5 | from loguru import logger logger.remove( 0 ) logger.add( "out.log" ) logger.success( "Written message to log file" ) |
2.如何使用loguru
2.1 安装
1 | pip install loguru |
最简单的使用:
1 2 3 4 | from loguru import logger # 在标准输出里面输出一行debug日志 logger.debug( "That's it, beautiful and simple logging!" ) |
2.2 日志类型(Level)介绍
loguru提供了七层日志层级,或者说七种日志类型。
生产环境中,常常在不同场景下使用不用的日志类型,用于处理各种问题。
每种类型的日志有一个整数值,表示日志层级,我们成为log level no。
- TRACE (5): 用于记录程序执行路径的细节信息,以进行诊断。
- DEBUG (10): 开发人员使用该工具记录调试信息。
- INFO (20): 用于记录描述程序正常操作的信息消息。
- SUCCESS (25): 类似于INFO,用于指示操作成功的情况。
- WARNING (30): 警告类型,用于指示可能需要进一步调查的不寻常事件。
- ERROR (40): 错误类型,用于记录影响特定操作的错误条件。
- CRITICAL (50): 严重类型,用于记录阻止核心功能正常工作的错误条件。
1 2 3 4 5 6 7 | logger.trace( "A trace message." ) logger.debug( "A debug message." ) logger.info( "An info message." ) logger.success( "A success message." ) logger.warning( "A warning message." ) logger.error( "An error message." ) logger.critical( "A critical message." ) |
输出如下:
1 2 3 4 5 6 | 2022-08-10 11:58:33.224 | DEBUG | __main__:<module>:12 - A debug message. 2022-08-10 11:58:33.224 | INFO | __main__:<module>:13 - An info message. 2022-08-10 11:58:33.225 | SUCCESS | __main__:<module>:14 - A success message. 2022-08-10 11:58:33.226 | WARNING | __main__:<module>:15 - A warning message. 2022-08-10 11:58:33.226 | ERROR | __main__:<module>:16 - An error message. 2022-08-10 11:58:33.227 | CRITICAL | __main__:<module>:17 - A critical message. |
如果你在linux的终端上,可以看到不同类型的日志,已经有不同的颜色加以区分,默认的配置已经很方便的让我们识别和使用了。
请注意,上述输出不包括TRACE级别的日志信息。这是因为Loguru默认使用DEBUG作为其最低日志级别,导致任何严重性低于DEBUG的日志信息都会被忽略。
如果您想更改默认级别,可以使用下面所示的add()方法的级别参数:
1 2 3 4 5 | import sys from loguru import logger logger.remove( 0 ) logger.add(sys.stderr, level = "INFO" ) |
remove()方法被首先调用,以删除默认处理程序的配置(其ID为0)。然后,add()方法向记录器添加一个新处理程序。该处理程序将记录到标准错误,只记录INFO或更高级别的日志。
2.3 设置日志输出的格式
在日常使用中,如果默认的输出内容不够,我们还可以自定义日志的输出内容和格式。
可以通过add()方法中的格式选项对Loguru生成的日志记录进行重新格式化。
Loguru 中的每条日志记录都是一个 Python 字典,其中包含其时间戳、日志级别等数据。
可以使用loguru提供的格式化指令,包括或重新排列每条信息,如下所示:
1 2 3 4 5 6 7 | import sys from loguru import logger logger.remove( 0 ) logger.add(sys.stderr, format = "{time} | {level} | {message}" ) logger.debug( "Happy logging with Loguru!" ) |
格式参数定义了自定义格式,在这个例子中有三个指令:
{time}:时间戳
{level}:日志级别
{message}:日志消息
输出如下:
1 | 2022-08-10T15:01:32.154035-0400 | DEBUG | Happy logging with Loguru! |
Loguru还通过其序列化选项支持JSON格式的结构化日志。
这可以让你以JSON格式输出你的日志,这样机器可以很容易地解析和分析它,因为每条记录中的信息将以键/值对的形式提供。
1 2 3 4 5 6 | import sys from loguru import logger logger.remove( 0 ) logger.add(sys.stderr, format = "{time:MMMM D, YYYY > HH:mm:ss!UTC} | {level} | {message}" , serialize = True ) logger.debug( "Happy logging with Loguru!" ) |
json格式的输出:
1 | { "text" : "August 10, 2022 > 19:38:06 | DEBUG | Happy logging with Loguru!\n" , "record" : { "elapsed" : { "repr" : "0:00:00.004000" , "seconds" : 0.004}, "exception" : null, "extra" : {}, "file" : { "name" : "app.py" , "path" : "C:\\Users\\Eric\\Documents\\Better Stack\\loguru-demo\\app.py" }, "function" : "<module>" , "level" : { "icon" : "🐞" , "name" : "DEBUG" , "no" : 10}, "line" : 8, "message" : "Happy logging with Loguru!" , "module" : "app" , "name" : "__main__" , "process" : { "id" : 22652, "name" : "MainProcess" }, "thread" : { "id" : 25892, "name" : "MainThread" }, "time" : { "repr" : "2022-08-10 15:38:06.369578-04:00" , "timestamp" : 1660160286.369578}}} |
2.4 把日志记录到文件中
最简单的配置如下:
1 2 | logger.add( "loguru.log" ) logger.debug( "A debug message." ) |
输出如下:
1 2 | cat loguru.log 2022-08-11 13:16:52.573 | DEBUG | __main__:<module>:13 - A debug message. |
当add函数配置为一个文件时,add方法提供了更多选项来自定义日志文件的处理方式:
- rotate:指定关闭当前日志文件并创建新文件的条件。此条件可以是 int、datetime 或 str,建议使用 str,因为它更易于人类阅读。
- 如果是整数值,它对应于当前文件在创建新文件之前允许保留的最大字节数。
- 如果是datetime.timedelta 值时,它指示每次旋转的频率,而 datetime.time 指定每个旋转应在一天中发生的时间。
- 如果是str值,这是上述类型的变体。
- retention:指定在从文件系统中删除每个日志文件之前如何保留日志。
- compression:如果设置此选项,日志文件将转换为指定的压缩格式。
- delay:如果设置为 True,则新日志文件的创建将延迟到推送第一条日志消息。
- mode, buffering, encoding: 这些参数将被传递给 Python 的 open() 函数,该函数决定了 Python 将如何打开日志文件。
1 2 3 4 | # 将自动删除超过一分钟的老文件 logger.add( "loguru.log" , rotation = "5 seconds" , retention = "1 minute" ) # 将仅保留三个最新文件 logger.add( "loguru.log" , rotation = "5 seconds" , retention = 3 ) |
一个完整的配置:
1 2 3 4 5 6 7 8 9 10 | logger.add( sink = "./logs/app.log" , enqueue = True , rotation = "4 weeks" , retention = "4 months" , encoding = "utf-8" , backtrace = True , diagnose = True , compression = "zip" , ) |
add函数参数的完整解释:
- sink:为记录器生成的每条记录指定目的地。默认情况下,它设置为 sys.stderr。
- level:指定记录器的最低日志级别。
- format:用于为日志定义自定义格式。
- filter:用于确定一条记录是否应该被记录。
- colorize: 采用布尔值并确定是否应启用终端着色。
- serialize:如果设置为 True,则日志记录以 JSON 格式呈现。
- backtrace:确定异常跟踪是否应该延伸到捕获错误的点之外,以便于调试。 诊断:确定变量值是否应显示在异常跟踪中。您应该在生产环境中将其设置为 False 以避免泄露敏感信息。
- enqueue:启用此选项会将日志记录放入队列中,以避免多个进程记录到同一目的地时发生冲突。
- catch:如果在记录到指定的接收器时发生意外错误,您可以通过将此选项设置为 True 来捕获该错误。错误将打印到标准错误。
3. 其他使用
3.1 不同类型的日志记录到不同的文件中
在上面的配置中,我们讲到,可以使用add函数来配置最小的日志级别,如果我们需要把不同的日志输出到不同的文件中,我们需要使用到filter参数:
1 2 3 4 5 6 7 8 9 10 | import sys from loguru import logger def level_filter(level): def is_level(record): return record[ "level" ].name = = level return is_level logger.remove( 0 ) logger.add( "./logs/app.log" , filter = level_filter(level = "WARNING" )) |
输出如下:
1 | 2022-09-30 12:17:00.548 | WARNING | __main__:<module>:15 - A warning message. |
还可以使用lambda函数直接配置filter参数,一个完整的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from loguru import logger # 设置不同级别的日志输出文件 logger.add( "debug.log" , level = "DEBUG" , rotation = "10 MB" , filter = lambda record: record[ "level" ].name = = "DEBUG" ) logger.add( "info.log" , level = "INFO" , rotation = "10 MB" , filter = lambda record: record[ "level" ].name = = "INFO" ) logger.add( "warning.log" , level = "WARNING" , rotation = "10 MB" , filter = lambda record: record[ "level" ].name = = "WARNING" ) logger.add( "error.log" , level = "ERROR" , rotation = "10 MB" , filter = lambda record: record[ "level" ].name = = "ERROR" ) logger.add( "critical.log" , level = "CRITICAL" , rotation = "10 MB" , filter = lambda record: record[ "level" ].name = = "CRITICAL" ) # 输出不同级别的日志消息 logger.debug( "This is a debug message" ) logger.info( "This is an info message" ) logger.warning( "This is a warning message" ) logger.error( "This is an error message" ) logger.critical( "This is a critical message" ) |
3.2 异常记录
loguru提供了非常方便的异常定位功能,可以直接使用catch闭包,把抛出异常的位置记录到日志中。
1 2 3 4 5 6 7 8 9 | from loguru import logger logger.add(sink = 'log.log' ) @logger .catch def my_function(x, y, z): return 1 / (x + y + z) res = my_function( 0 , 0 , 0 ) |
输出如下:
1 2 3 4 5 6 7 8 9 10 11 | > File "/var/folders/kb/0pw_yx2n75z8mlyzjk3mwlwc0000gn/T/ipykernel_85315/1609034425.py" , line 9, in <module> res = my_function(0,0,0) └ < function my_function at 0x7fcce2170670> File "/var/folders/kb/0pw_yx2n75z8mlyzjk3mwlwc0000gn/T/ipykernel_85315/1609034425.py" , line 7, in my_function return 1 / (x + y + z) │ │ └ 0 │ └ 0 └ 0 ZeroDivisionError: division by zero |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
2020-09-10 pycharm 报错内存不足: There is not enough memory to perform the requested operation。。。
2020-09-10 递归替换字典的键和值
2020-09-10 pycharm 显示