[python] Python日志记录库loguru使用指北

python,loguru · 浏览次数 : 0

小编点评

Loguru是一个功能强大且易于使用的开源Python日志记录库,建立在Python标准库中的logging模块之上。它提供了更加简洁直观、功能丰富的接口,具有以下主要特点: 1. **简单易用**:无需复杂的配置和定制即可实现基本的日志记录和输出。 2. **灵活的日志格式**:支持自定义日志格式,并提供丰富的格式化选项。 3. **丰富的日志级别**:支持多种日志级别,如DEBUG、INFO、WARNING、ERROR和CRITICAL。 4. **多种日志目标**:可以将日志输出到终端、文件、电子邮件、网络服务器等目标。 5. **强大的日志处理功能**:支持日志过滤、格式化、压缩、旋转等功能。 6. **支持异步日志记录**:能够极大地提升日志记录的性能。 7. **支持跨进程、跨线程的日志记录**:可以安全地记录多进程、多线程应用程序的日志。 与Python中常用的另一个日志记录库logging相比,loguru在易用性、功能性和性能方面都有所优势。如果需要一个简单、强大且易于使用的日志系统,loguru是一个很好的选择。而对于只需要快速输出一些调试信息的场景,print可能就足够了。在生产环境中,使用loguru或其他日志系统通常会更加合适。 要使用Loguru,首先需要通过pip安装它: ```bash pip install loguru ``` 然后,你可以简单地使用Loguru记录日志,例如: ```python import loguru logger = loguru.getLogger(__name__) logger.debug("这是一条调试信息") logger.info("这是一条普通信息") logger.success("操作成功完成") logger.warning("这是一条警告信息") logger.error("这是一条错误信息") logger.critical("这是一条严重错误信息") ``` Loguru还提供了丰富的配置选项和高级功能,如日志轮换、压缩、异步日志记录等。你可以在官方文档中找到更多详细信息和示例:[loguru文档](https://loguru.readthedocs.io/)。

正文

Loguru是一个功能强大且易于使用的开源Python日志记录库。它建立在Python标准库中的logging模块之上,并提供了更加简洁直观、功能丰富的接口。Logging模块的使用见:Python日志记录库logging总结。Loguru官方仓库见:loguru,loguru官方文档见: loguru-doc

Loguru的主要特点包括:

  • 简单易用:无需复杂的配置和定制即可实现基本的日志记录和输出。
  • 灵活的日志格式:支持自定义日志格式,并提供丰富的格式化选项。
  • 丰富的日志级别:支持多种日志级别,例如DEBUG、INFO、WARNING、ERROR和CRITICAL。
  • 多种日志目标:可以将日志输出到终端、文件、电子邮件、网络服务器等目标。
  • 强大的日志处理功能:支持日志过滤、格式化、压缩、旋转等功能。
  • 支持异步日志记录:能够极大地提升日志记录的性能。
  • 支持跨进程、跨线程的日志记录:可以安全地记录多进程、多线程应用程序的日志。

Loguru与logging是Python中常用的两个日志记录库,但两者在功能和易用性方面存在一些差异,如下所示:

特性 Loguru logging
易用性 更简单易用 相对复杂
日志格式 更灵活 较简单
日志级别 更丰富 较少
日志目标 更多种类 较少
日志处理功能 更强大 较弱
异步日志记录 支持 不支持
跨进程、跨线程支持 支持 支持

总的来说,loguru在易用性、功能性和性能方面都优于logging。如果要一个简单、强大且易于使用的日志系统,loguru是一个很好的选择。而如果只是需要快速输出一些调试信息,print可能就足够了。不过,对于生产环境,使用loguru或其他日志系统通常会更加合适。

Loguru安装命令如下:

pip install loguru

# 查看loguru版本
import loguru
print(loguru.__version__) # 输出:0.7.2

1 使用说明

1.1 基础用法

简单使用

Loguru的核心概念是只有一个全局的日志记录器,也就是logger。这个设计使得日志记录变得非常简洁和一致。使用Loguru时,你不需要创建多个日志实例,而是直接使用这个全局的logger来记录信息。这不仅减少了配置的复杂性,也使得日志管理更加集中和高效。

from loguru import logger

logger.debug("这是一个调试信息")

输出:

2024-06-29 19:57:44.506 | DEBUG    | __main__:<module>:3 - 这是一个调试信息

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

  1. 时间戳:表示日志记录的具体时间,格式通常为年-月-日 时:分:秒.毫秒。
  2. 日志级别:表示这条日志的严重性级别。
  3. 进程或线程标识:表示日志来自哪个模块或脚本。 __main__ 表示日志来自主模块。如果是其他文件会显示文件名。
  4. 文件名和行号:记录日志消息的函数名和行号。
  5. 日志消息:实际的日志内容,此外loguru支持使用颜色来区分不同的日志级别,使得日志输出更加直观.

日志等级

Loguru可以通过简单的函数调用来记录不同级别的日志,并自动处理日志的格式化和输出。这一特点可以让使用者专注于记录重要的信息,而不必关心日志的具体实现细节。Loguru支持的日志级别,按照从最低到最高严重性排序:

  • TRACE: 最详细的日志信息,用于追踪代码执行过程。Loguru默认情况下使用DEBUG级别作为最低日志记录级别,而不是TRACE级别。这是因为TRACE级别会产生大量的日志信息。
  • DEBUG: 用于记录详细的调试信息,通常只在开发过程中使用,以帮助诊断问题。
  • INFO: 用于记录常规信息,比如程序的正常运行状态或一些关键的操作。
  • SUCCESS: 通常用于记录操作成功的消息,比如任务完成或数据成功保存。
  • WARNING: 用于记录可能不是错误,但需要注意或可能在未来导致问题的事件。
  • ERROR: 用于记录错误,这些错误可能会影响程序的某些功能,但通常不会导致程序完全停止。
  • CRITICAL: 用于记录非常严重的错误,这些错误可能会导致程序完全停止或数据丢失。
from loguru import logger

logger.debug("这是一条跟踪消息")
logger.debug("这是一条调试信息")
logger.info("这是一条普通信息")
logger.success("操作成功完成")
logger.warning("这是一条警告信息")
logger.error("这是一条错误信息")
logger.critical("这是一条严重错误信息")

输出:

2024-06-29 19:58:11.535 | DEBUG    | __main__:<module>:3 - 这是一条跟踪消息
2024-06-29 19:58:11.536 | DEBUG    | __main__:<module>:4 - 这是一条调试信息
2024-06-29 19:58:11.536 | INFO     | __main__:<module>:5 - 这是一条普通信息
2024-06-29 19:58:11.537 | SUCCESS  | __main__:<module>:6 - 操作成功完成
2024-06-29 19:58:11.537 | WARNING  | __main__:<module>:7 - 这是一条警告信息
2024-06-29 19:58:11.538 | ERROR    | __main__:<module>:8 - 这是一条错误信息
2024-06-29 19:58:11.538 | CRITICAL | __main__:<module>:9 - 这是一条严重错误信息

1.2 日志配置

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

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

# 终端显示不受该段代码设置
# 添加一个日志处理器,输出到文件
# 设置日志最低显示级别为INFO,format将设置sink中的内容
# sink链接的本地文件,如不存在则新建。如果存在则追写
logger.add(sink="myapp.log", level="INFO", format="{time:HH:mm:ss}  | {message}| {level}")

# debug结果不被显示到本地文件
logger.debug("这是一条调试信息")
logger.info("这是一条普通信息")

输出:

2024-06-29 19:58:56.159 | DEBUG    | __main__:<module>:11 - 这是一条调试信息
2024-06-29 19:58:56.159 | INFO     | __main__:<module>:12 - 这是一条普通信息

当连续两次调用 add 函数时,loguru 会将新的日志处理器添加到处理器列表中,而不是覆盖之前的处理器。这意味着所有添加的处理器都会接收到日志消息,并且按照它们被添加的顺序来处理这些消息。

from loguru import logger
logger.add(sink="myapp1.log", level="INFO")
logger.add(sink="myapp2.log", level="INFO")
# 会同时存入所有add添加日志处理器
logger.info("这是一条普通信息,存入myapp2")

如果想删除所有已添加的日志处理器,loguru运行使用 logger.remove()方法不带任何参数来移除所有日志处理器。

from loguru import logger
import sys

# 移除所有日志处理器(包括终端输出)
logger.remove()
logger.add(sink="myapp3.log", level="INFO", format="{time:HH:mm:ss}  | {message}| {level}")

logger.debug("这是一条调试信息存入myapp3")
logger.info("这是一条普通信息存入myapp3")

注意调用logger.remove()之后的所有日志将不会被记录,因为没有处理器了。

from loguru import logger
# 移除所有日志处理器(包括终端输出)
logger.remove()
# 没有输出
logger.info("这是一条普通信息存入myapp3")

如果希望移除某些日志处理器,而不是从所有日志器中移除,代码如下:

from loguru import logger

# 移除默认终端logger,如果终端存在。
# logger.remove(0)
# 添加多个文件处理器,enqueu设置异步日志记录
handler1 = logger.add("myapp1.log", enqueue=True)
print(handler1) # handler_id是移除的处理器的唯一标识符
handler2 = logger.add("myapp2.log")

# 记录一些日志
logger.info("这些信息会被记录到两个文件中")

# 移除特定的文件处理器
logger.remove(handler1)

# 现在只有myapp2.log 会记录日志
logger.info("这条信息只会记录在myapp2.log 中")

如果想将日志输出到日志台,代码如下:

from loguru import logger
import sys

logger.remove() # 移除默认输出
# 添加一个日志处理器,输出到控制台,使用自定义格式
logger.add(
    sink=sys.stdout,
    level="DEBUG",
    # green表示颜色
    format="<green>{time:HH:mm}</green> <level>{message}</level>"
)

# 注意终端显示会同步显示
logger.debug("这是一条调试信息")
logger.info("这是一条普通信息")

时间自定义

可以使用datatime库来自定义日志时间格式。

from datetime import datetime
from loguru import logger

# 自定义时间格式
# time_format = "%Y-%m-%d %H:%M:%S,%f"  # 包括微秒
time_format = "%H:%M:%S,%f"  # 包括微秒但不含年月日

# 定义日志格式,使用 datetime.now().strftime() 来格式化时间
log_format = "{time:" + time_format + "} - {level} - {message}"
logger.add("myapp.log", format=log_format, level="DEBUG")

# 记录一条日志
logger.debug("这是一个带有微秒的测试日志")

日志轮换

from loguru import logger
# 当文件大小达到100MB时创建新的日志文件,旧文件保留并重命名,用于防止单个日志文件变得过大。
logger.add("file_1.log", rotation="100 MB")
# 每天中午12时创建新的日志文件,旧文件保留并重命名
logger.add("file_2.log", rotation="12:00")
# 当日志文件存在超过一周时创建新的日志文件,旧文件保留并重命名
logger.add("file_3.log", rotation="1 week")
# 设置日志文件保留10天
logger.add("file_4.log", retention="10 days")
# 当文件大小达到100MB时创建新的日志文件,旧文件保留压缩为zip文件
logger.add('file_{time}.log', rotation="100 MB", compression='zip')

1.3 进阶使用

异常捕获

@logger.catch装饰器可以用来装饰my_function函数,并将这些异常信息记录到日志中。

from loguru import logger

logger.add(sink='myapp.log')

@logger.catch
def my_function(x, y):
    return x / y
        
res = my_function(0,0)

过滤

使用loguru库进行Python日志记录时,可以通过自定义的filter函数来筛选并记录特定的日志信息。此函数接收一个记录对象作为参数,根据日志消息内容(message)、级别(level)或其他日志属性,返回布尔值以决定是否记录该条日志。如果函数返回True,则日志被记录;若返回False,则忽略该日志。

from loguru import logger

# 定义一个过滤器函数
def my_filter(record):
    # 只记录包含 "第一" 的日志
    return "第一" in record["message"]

# 使用过滤器
logger.add("myapp.log", filter=my_filter)

# 记录一些日志
logger.info("第一个记录")
logger.info("第二个记录")

此外可以结合bind方法进行过滤,bind方法用于向日志记录器添加额外的上下文信息。这些信息将被包含在每条日志消息中,但不会改变日志消息本身。如下所示:

from loguru import logger

def filter_user(record):
    return record["extra"].get("user") =="A"

logger.add("myapp.log", filter=filter_user)

# 绑定user
logger.bind(user="A").info("来自A")
logger.bind(user="B").info("来自B")

2 参考

与[python] Python日志记录库loguru使用指北相似的内容:

[python] Python日志记录库loguru使用指北

Loguru是一个功能强大且易于使用的开源Python日志记录库。它建立在Python标准库中的logging模块之上,并提供了更加简洁直观、功能丰富的接口。Logging模块的使用见:Python日志记录库logging总结。Loguru官方仓库见:loguru,loguru官方文档见: logu

Python日志模块:实战应用与最佳实践

**本文详细解析了Python的logging模块,从基本介绍到实际应用和最佳实践。我们通过具体的代码示例解释了如何高效地使用这个模块进行日志记录,以及如何避免常见的陷阱,旨在帮助读者更好地掌握这个强大的工具。** ![file](https://img2023.cnblogs.com/other/

实践探讨Python如何进行异常处理与日志记录

本文分享自华为云社区《Python异常处理与日志记录构建稳健可靠的应用》,作者:柠檬味拥抱。 异常处理和日志记录是编写可靠且易于维护的软件应用程序中至关重要的组成部分。Python提供了强大的异常处理机制和灵活的日志记录功能,使开发人员能够更轻松地管理代码中的错误和跟踪应用程序的执行过程。在本文中,

[转帖]专注于GOLANG、PYTHON、DB、CLUSTER 记一次压测引起的nginx负载均衡性能调优

https://xiaorui.cc/archives/3495 rfyiamcool2016年6月26日 0 Comments 这边有个性能要求极高的api要上线,这个服务端是golang http模块实现的。在上线之前我们理所当然的要做压力测试。起初是 “小白同学” 起头进行压力测试,但当我看到

Python如何在日志中隐藏明文密码

Python如何在日志中隐藏明文密码 前言 在项目开发中,有的时候会遇到一些安全需求,用以提升程序整体的安全性,提高外来非法攻击的门槛,而在日志中隐藏明文密码打印便是最典型的安全需求之一。 在Python中,明文密码往往发生于命令执行参数、debug日志、依赖库打印等场景中。对于程序自身的明文密码打

深入理解正则表达式:从入门到精通

title: 深入理解正则表达式:从入门到精通 date: 2024/4/30 18:37:21 updated: 2024/4/30 18:37:21 tags: 正则 Python 文本分析 日志挖掘 数据清洗 模式匹配 工具推荐 第一章:正则表达式入门 介绍正则表达式的基本概念和语法 正则表达

Python colorama 设置控制台、命令行输出彩色文字

为了方便调试代码,经常会向stdout中输出一些日志,但是大量日志,有时不好定位问题。 使用终端打印特定颜色字符串,可以突出显示关键性的信息,帮助用户更好地识别和理解输出内容。 https://pypi.org/project/colorama/ Colorama 是为了在命令行界面中提供简单、方便

【Azure 应用服务】Azure Function Python函数中,如何获取Event Hub Trigger的消息Event所属于的PartitionID呢?

问题描述 在通过Azure Function消费Event Hub中的消息时,我们从Function 的 Trigger Details 日志中,可以获得当前Funciton中处理的消息是哪一个分区(PartitionID), 偏移量Offset,序列号SequenceNumber 等信息。 但是在

【Azure 应用服务】Azure Function Python函数部署到Azure后遇见 Value cannot be null. (Parameter 'receiverConnectionString') 错误

问题描述 使用VS Code创建Python Function,处理Event Hub中的数据。当部署到Azure Function App后,函数无法执行,查看 Function 日志出现 Value cannot be null. (Parameter 'receiverConnectionSt

logging 模块因权限问题写入日志失败

哈喽大家好,我是咸鱼 今天跟大家分享一个使用 Python 的 logging 模块写入日志文件时遇到的权限问题,不知道你们有没有遇到过 ## 1.案例现象 今天上班的时候手机短信收到了 zabbix 告警,但是发现了不对劲的地方:微信没有收到告警信息,按理说短信跟微信应该是同时收到告警信息的 咸鱼