Python 日志工具 loguru

王 茂南 2023年8月22日07:23:11
评论
5406字阅读18分1秒
摘要本文介绍了Python的日志库loguru的使用方法。相比于Python内置的logging库,loguru提供了更简单、美观的日志记录方式,可以轻松地配置和输出日志信息。我们详细介绍了loguru的直接使用、添加处理器、记录到文件中、异常捕捉、记录异常backtrace、绑定参数以及启用和禁用日志等功能。通过灵活使用loguru,我们可以更方便地进行日志记录和管理,提高程序的可读性和可维护性。

简介

在 Python 中,日志是一种重要的工具,用于记录程序运行时的信息、警告和错误。Python 内置了logging模块作为标准日志库,但其使用起来相对繁琐。而loguru是一个简单易用的第三方日志库,可以提供美观、简洁的日志输出,并且具有更方便的配置和使用方式。

相比于logging库,为什么我们应该选择使用loguru呢?首先,loguru提供了一种更简单的日志记录方式,通过直接调用logger对象的方法即可完成日志记录,无需额外配置。其次,loguru的日志输出格式默认较为美观,可以直接显示时间、日志级别和消息内容,方便阅读。此外,loguru还支持灵活的日志处理器配置,可以轻松地将日志记录到文件、控制台或其他地方,满足不同场景的需求。

在接下来的内容中,我们将详细介绍loguru的使用方法,并演示一些常用功能和技巧。

参考资料

 

Loguru 的使用

直接使用

首先让我们看一下最简单的loguru使用示例。下面的代码示例展示了如何直接使用loguru进行日志记录:

  1. from loguru import logger
  2. logger.debug("That's it, beautiful and simple logging!")

以上代码中,我们导入了logger对象,并调用其debug方法记录一条日志。loguru会自动将日志输出到控制台,并显示时间戳、日志级别和消息内容。这种直接使用的方式非常简单,适用于快速的日志记录需求。下面是输出的结果示例:

Python 日志工具 loguru

需要注意,由于 loguru 只有一个对象,因此 loguru 可以在多个 module 中使用,而不会出现冲突。

 

添加 handler

除了直接使用loguru进行日志记录外,我们还可以通过添加处理器来自定义日志的输出方式和格式。下面的代码示例展示了如何使用loguruadd函数添加处理器(handler):

  1. import sys
  2. from loguru import logger
  3. def stringFilter(record) -> bool:
  4.     # 只记录出现 RL 的 log
  5.     if 'RL' in record['message']:
  6.         return True
  7.     return False
  8. # 添加或删除 handler
  9. logger.remove() # 删除原有的 handler
  10. logger.add(sys.stderr, format="Without Filter: <green>{time}</green> | {level} | {message}", level="INFO", colorize=True# 不会显示 debug 的日志
  11. logger.add(sys.stderr, format="With Filter: {file} | {line} | {level} | <level>{message}</level>", filter=stringFilter, level="DEBUG")
  12. # 添加日志
  13. logger.info("That's it, beautiful and simple logging!")
  14. logger.info("RL: Info, Test Filter.")
  15. logger.debug("RL: Debug-1, Test Filter.")
  16. logger.debug("Debug-2, Test Filter.")

在上述代码中:

  • 我们首先使用logger.remove()函数删除了原有的处理器;
  • 然后使用logger.add()函数添加了两个处理器。
    • 第一个处理器的日志级别为 INFO,使用了自定义的格式,并启用了颜色显示。
    • 第二个处理器的日志级别为 DEBUG,并使用了自定义的过滤器(只显示有 RL 的日志)。

通过添加处理器,我们可以根据需求自由地配置日志的输出方式和格式。下面是最终的输出。可以看到第一个处理器不会显示 DEBUG,第二个只显示有 RL 的日志:

Python 日志工具 loguru

下面是不同的等级,例如我们设置为 INFO,那么所有的 DEBUG 的信息就会看不到:

Python 日志工具 loguru

 

记录到文件中

除了将日志输出到控制台外,loguru还支持将日志记录到文件中。下面的代码示例展示了如何使用loguru将日志记录到文件中(只需要将 add 中修改为文件名即可):

  1. from loguru import logger
  2. def stringFilter(record) -> bool:
  3.     # 只记录出现 RL 的 log
  4.     if 'RL' in record['message']:
  5.         return True
  6.     return False
  7. # 添加或删除 handler
  8. logger.remove() # 删除原有的 handler
  9. logger.add('./log-{time}.log', format="{time} {level} {message}", filter=stringFilter, level="DEBUG", rotation="1 MB")
  10. # 添加日志
  11. logger.info("That's it, beautiful and simple logging!")
  12. logger.info("RL: Info, Test Filter.")
  13. logger.debug("RL: Debug-1, Test Filter.")
  14. logger.debug("Debug-2, Test Filter.")

在上述代码中,我们使用logger.add()函数将日志记录到文件中。通过指定文件路径和格式,我们可以将日志输出到指定的文件中,并根据需要进行日志轮换、日志保留等操作。在示例中,我们使用了一个自定义的过滤器,只记录包含"RL"的日志消息。
除此之外,还有一系列的轮换方式:

  1. logger.add("file_1.log", rotation="500 MB")    # Automatically rotate too big file
  2. logger.add("file_2.log", rotation="12:00")     # New file is created each day at noon
  3. logger.add("file_3.log", rotation="1 week")    # Once the file is too old, it's rotated
  4. logger.add("file_X.log", retention="10 days")  # Cleanup after some time
  5. logger.add("file_Y.log", compression="zip")    # Save some loved space

 

异常捕捉

loguru还提供了异常捕捉功能,可以方便地记录异常信息。下面的代码示例展示了如何使用loguru捕捉并记录异常:

  1. from loguru import logger
  2. logger.add('./log-{time}.log', rotation="1 MB")
  3. @logger.catch
  4. def my_function(x, y, z):
  5.     try:
  6.         a = 1 / (x + y + z)
  7.         return a
  8.     except ZeroDivisionError:
  9.         raise f'除数不为 0.'
  10. a = my_function(0,0,0)
  11. print(a)

在上述代码中,我们使用logger.catch装饰器捕捉了my_function函数中的异常,并将异常信息记录到日志中。通过使用该装饰器,我们可以方便地捕捉和记录函数中的异常,避免程序崩溃,并可以在日志中查看详细的异常信息。如下所示,可以看到非常详细的堆栈调用:

Python 日志工具 loguru

除了上面的方式外,loguru还支持使用 backtrace 来进行记录。我们使用logger.add()函数添加了一个处理器,并通过设置backtrace=Truediagnose=True参数来启用异常的调用栈信息记录。当程序发生异常时,loguru会将异常的调用栈信息记录到日志中,方便我们进行故障排查和问题定位。

  1. logger.add("out.log", backtrace=True, diagnose=True)  # Caution, may leak sensitive data in prod

或者是可以使用 logger.exception 的方式来异常的捕获和记录:

  1. from loguru import logger
  2. def func(a, b):
  3.     return a / b
  4. def nested(c):
  5.     try:
  6.         func(5, c)
  7.     except ZeroDivisionError:
  8.         logger.exception("What?!")
  9. nested(0)

 

bind,绑定参数

logurubind方法可以用于绑定额外的参数到日志记录中,方便我们在日志中添加自定义的上下文信息。下面的代码示例展示了如何使用bind方法绑定参数:

  1. import sys
  2. from loguru import logger
  3. logger.add(sys.stderr, format="{extra} - {extra[ip]} - {message}")
  4. class Server:
  5.     def __init__(self, ip, user):
  6.         self.ip = ip
  7.         self.user = user
  8.         self.logger = logger.bind(ip=ip, user=user)
  9.     def call(self, message):
  10.         self.logger.info(message)
  11. instance_1 = Server("192.168.0.200", "user1")
  12. instance_2 = Server("127.0.0.1", "user2")
  13. instance_1.call("First instance")
  14. instance_2.call("Second instance")

在上述代码中,我们定义了一个Server类,并在其中使用logger.bind()方法绑定了ipuser两个参数。在call方法中,我们使用了self.logger.info()方法记录日志,并在日志格式中添加了额外的上下文信息。通过绑定参数,我们可以方便地在日志中添加自定义的上下文信息,提供更详细的日志内容。

 

启用和禁用日志

loguru还提供了启用和禁用日志的功能,可以根据需要控制日志的输出。下面的代码示例展示了如何使用loguru启用和禁用日志:

  1. import sys
  2. from loguru import logger
  3. # For scripts
  4. config = {
  5.     "handlers": [
  6.         {"sink": sys.stdout, "format": "{time} - {message}"},
  7.         {"sink": "file.log", "serialize": True},
  8.     ],
  9.     "extra": {"user": "someone"}
  10. }
  11. logger.configure(**config)
  12. if __name__ == '__main__':
  13.     # For libraries, should be your library's `__name__`
  14.     logger.disable("__main__")
  15.     logger.info("No matter added sinks, this message is not displayed")
  16.     # In your application, enable the logger in the library
  17.     logger.enable("__main__")
  18.     logger.info("This message however is propagated to the sinks")

在上述代码中,我们首先使用logger.configure()函数配置了日志处理器,并指定了日志输出到控制台和文件中。在if name == 'main'条件下,我们使用logger.disable()函数禁用了指定名称的日志输出,使得该名称下的日志不会被记录。然后,我们使用logger.enable()函数启用了指定名称的日志输出,使得该名称下的日志可以正常记录。

通过启用和禁用日志的功能,我们可以根据需要灵活地控制日志的输出,避免不必要的日志记录。

  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南
  • 本文由 发表于 2023年8月22日07:23:11
  • 转载请务必保留本文链接:https://mathpretty.com/16218.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: