Python 中的日志记录

2025 年 4 月 16 日 | 阅读 10 分钟

在本教程中,我们将学习标准日志记录模块的基础知识。

什么是日志记录?

日志记录是 Python 标准库中的一个模块,它提供了一个框架,用于从 Python 程序中发布日志消息。日志记录用于跟踪软件运行时发生的事件。

开发人员在日志记录工作时广泛使用此模块。它是软件开发、运行和调试中非常重要的工具。

日志记录对于存储日志记录很有益。假设没有日志记录,并且程序在执行过程中中断,我们将无法找到问题的实际原因。

不知何故,我们检测到崩溃的原因,但这将花费大量时间来解决。使用日志记录,我们可以留下面包屑的痕迹,这样如果程序中发生问题,我们可以轻松找到问题的原因。

在运行应用程序时,我们可能会遇到许多问题,例如我们假设一个整数,但我们得到了一个浮点数,服务正在维护中等等。这些问题很难确定且耗时。

日志记录如何工作

日志记录是一个强大的模块,初学者和企业都在使用。此模块提供了一种组织不同控制处理程序并将日志消息传输到这些处理程序的能力。

要发布日志消息,我们需要导入日志记录模块,如下所示。

现在,我们将调用记录器来记录我们想要看到的消息。日志记录模块提供了五个级别,用于指定事件的严重性。每个事件都包含可用于在指定严重性级别记录事件的并行方法。让我们了解以下事件及其工作原理。

  1. DEBUG - 用于提供详细信息,仅在诊断问题时使用。
  2. INFO - 提供有关事物按我们预期工作的信息。
  3. WARNING - 用于警告发生了意外情况,或者我们将在未来遇到问题。
  4. ERROR - 用于在遇到严重问题时通知,软件未执行某些程序。
  5. CRITICAL - 指定严重错误,程序本身可能无法继续执行。

上述级别足以处理任何类型的问题。这些级别的相应数值如下所示。

级别数值
NOTSET0
DEBUG10
INFO20
WARNING30
ERROR40
CRITICAL50

日志记录模块提供了许多功能。它包含几个常量、类和方法。常量由全大写字母表示;类由大写字母表示。小写字母表示方法。

让我们看一下模块本身提供的几个记录器对象。

  • Logger.info(msg) : 用于在此记录器上记录 INFO 级别的消息。
  • Logger.warning(msg) : 用于在此记录器上记录 WARNING 级别的消息。
  • Logger.error(msg) : 用于在此记录器上记录 ERROR 级别的消息。
  • Logger.critical(msg) : 用于在此记录器上记录 CRITICAL 级别的消息。
  • Logger.log(lvl,msg) : 用于在此记录器上记录整数级别 lvl 的消息。
  • Logger.exception(msg) : 用于在此记录器上记录 ERROR 级别的消息。
  • Logger.setLevel(lvl) : 用于设置此记录器的起始级别为 lvl。它将忽略所有低于此级别的消息。
  • Logger.addFilter(filt) : 用于向此记录器添加特定的过滤器 filt。
  • Logger.removeFilter(filt) : 用于从此记录器中移除特定的过滤器 filt。
  • Logger.filter(record) : 将记录器的过滤器应用于记录。如果记录可用并需要处理,则返回 True。否则,将返回 False。
  • Logger.addHandler(hdlr) : 用于向此记录器添加特定的处理程序 hdlr。
  • Logger.removeHandler(hdlr) : 用于从此记录器中移除特定的处理程序 hdlr。
  • Logger.hasHandlers() : 用于验证记录器是否配置了任何处理程序。

让我们理解下面的例子。

示例 -

输出

WARNING:root:The warning message is displaying
ERROR:root:The error message is displaying
CRITICAL:root:The critical message is displaying 

说明

如上面的输出所示,每条消息都与根一起显示,根是其默认记录器的日志记录模块名称。消息和级别名称由冒号 (:) 分隔,并以默认输出格式打印消息。

我们可以注意到 debug()info() 消息没有显示,因为默认情况下,日志模块会记录严重性级别为 WARNING、ERROR 和 CRITICAL 的消息。

基本配置

日志记录的主要任务是将记录事件存储在一个文件中。日志记录模块提供 basicConfig(**kwarg),用于配置日志记录。

它接受一些常用的参数,如下所示。

  • level - 指定的严重性级别由根级别设置。
  • filename - 指定一个文件。
  • filemode - 以特定模式打开文件。打开文件的默认模式是 a,这意味着我们可以追加内容。
  • format - 格式定义了日志消息的格式。

我们可以使用 level 参数设置日志消息的级别,如我们希望记录的那样。我们需要在类中传递一个常量,它将允许所有日志记录调用。

让我们理解下面的例子。

示例 -

输出

同样,我们可以将消息记录到文件中,而不是显示在控制台中,filenamefilemode 可以在 basicConfig() 函数中使用,并且我们可以使用 format 属性决定消息的格式。让我们理解以下示例。

示例 -

输出

说明

上述输出将显示在 msg.log 文件中,而不是控制台中。我们以 w 模式打开文件,这意味着文件以“写入模式”打开。如果 basicConfig() 被多次调用,那么程序的每次运行都将重写日志文件的输出。basicConfig() 函数可以通过传递附加参数进行修改 (https://docs.pythonlang.cn/3/library/logging.html#logging.basicConfig)。

让我们理解下面的例子。

示例 -

输出

2020-09-05 13:17:39,204 This is a harmless debug Message
2020-09-05 13:17:39,205 This is just an information
2020-09-05 13:17:39,205 It is a Warning. Please make changes
2020-09-05 13:17:39,205 You are trying to divide by zero
2020-09-05 13:17:39,205 Internet is down

说明

上面的代码将生成一个文件,我们可以在打开文件时查看输出。

格式化输出

作为消息传递到程序中的字符串可以根据我们的要求进行修改。给定字符串和 Logrecord 部分中存在一些基本元素。让我们理解以下示例。

示例 -

输出

18472-WARNING-This is a Warning Message

format 参数可以接受包含 Logrecord 属性的字符串,以我们需要的任何形式。

让我们理解以下示例 -

示例 -

输出

2020-09-02 20:12:06,288 - Admin logged in

%(asctime) 属性添加了 Logrecord 的创建时间。我们还可以使用 datefmt 属性自定义格式,它提供与 datetime 模块相同的功能。

示例 -

输出

02-Sep-20 13:29:05 - Admin logged out

记录变量数据

有时,我们希望将应用程序中的动态信息包含在日志中。日志记录方法接受字符串作为参数,并且最好将字符串与变量数据格式化并传递给日志方法。

但除此之外,我们还可以使用格式字符串作为消息,并将变量数据作为参数附加。

让我们理解以下示例 -

输出

ERROR:root: Peter Decosta raised an error

说明

传递给方法的参数将作为消息中的变量数据进行混淆。

我们可以使用 f{string} 来格式化给定的字符串。它提供了一种简洁易用的字符串处理方式。

示例 -

输出

ERROR:root: Antonio Mino raised an error

捕获堆栈跟踪

我们可以使用日志记录模块捕获应用程序中完整的堆栈跟踪。日志记录函数中有一个 exc_info 参数;如果将其设置为 True,它可以捕获 异常信息

让我们理解以下示例 -

示例 -

输出

ERROR:root:Exception occurred
Traceback (most recent call last):
  File "C:/Users/DEVANSH SHARMA/PycharmProjects/Hello/loggingFile.py", line 224, in <module>
    c = a / b
ZeroDivisionError: division by zero

说明

如果我们不将 exc_info 设置为 true,输出将不会通知我们异常。如果它只显示以下输出,那么在一千行代码中调试错误将很困难。

还有其他选项可以获取有关异常的完整信息。日志记录模块提供了 exception() 方法,该方法以 ERROR 级别记录消息并附加异常信息。要使用它,请像调用 logging.error(exc_info = True) 一样调用 logging.exception() 方法。

让我们理解下面的例子。

示例 -

输出

ERROR:root:Exception occurred
Traceback (most recent call last):
  File "C:/Users/DEVANSH SHARMA/PycharmProjects/Hello/loggingFile.py", line 224, in <module>
    c = a / b
ZeroDivisionError: division by zero

我们可以在 error()、debug() 或 critical() 方法中使用其中任何一个选项来获取有关异常的信息。

类和函数

到目前为止,我们已经看到了名为 root 的默认记录器。日志记录模块在调用其函数时使用它,例如 logging.debug()、logging.error() 等。我们还可以通过创建 Logger 类的对象来定义自己的记录器。在这里,我们定义了常用的类和函数。

以下是日志记录模块中定义的类和函数。

  • Logger - 记录器对象用于直接调用函数。
  • LogRecord - 它自动创建日志记录文件,其中包含与所有被记录事件相关的信息,例如记录器的名称、函数、行号、消息等。
  • Handler - 处理程序用于将 LogRecord 分派到输出端点。FileHandler、StreamHandler、HTTPHandler、SMTTPHandlerHandler 的子类。
  • Formatters - 格式化程序用于定义输出的结构。它使用字符串格式化方法来指定日志消息的格式。

如果我们没有要格式化的消息,默认是使用原始消息。默认格式日期格式为。

以下格式用于使日志消息成为人类可读的格式。

我们通常使用 Logger 类的对象,这些对象是使用 logging.getLogger(name) 函数创建的。如果 getLogger() 方法以相同的名称多次调用,它将返回相同记录器对象的引用。

让我们理解以下示例

示例 -

输出

This is a warning message

说明

我们创建了自己的记录器名称 first_logger,但与根记录器不同,first_logger 不属于输出格式。要显示它,请将其传递给配置函数。然后输出将如下所示。

使用处理程序

处理程序通常用于配置记录器并同时将日志传输到许多位置。它将日志消息发送到标准输出流或通过 HTTP 或电子邮件发送到文件。

让我们理解以下创建处理程序的示例。

示例

输出

__main__ - WARNING - This is a warning message
__main__ - ERROR - This is an error message

说明

在以下程序中,我们创建了一个名为 logger_obj 的自定义记录器,并创建了一个 LogRecord,它存储了所有日志事件的记录,并将其传递给它拥有的所有处理程序:w_handlerse_handlers

w_handlers 是一个 流处理程序,级别为 WARNING。它接受来自 LogRecord 的日志,以字符串格式生成输出并将其打印到屏幕。

e_handler 是一个文件处理程序,级别为 ERROR。它忽略 LogRecord,因为它的级别是 WARNING。

结论

日志记录模块灵活且易于使用。它对于跟踪日志记录和向用户显示适当的消息非常有用。它提供了创建自定义日志级别、处理程序类和许多其他有用方法的灵活性。

它还为小型项目提供基本日志记录。

在本教程中,我们讨论了日志记录模块的所有基本概念。我们涵盖了生成不同级别的消息。