通过日志,我们可以理解程序中发生的事件,以及事件发生的顺序。通过 Python 的 logging 模块可以创建自定义的日志记录。这些日志记录可以包含调用时间以及当时变量的值;而且如果日志记录有缺失,说明有部分代码被跳过。
1 示例
Al Sweigart 写过这样一个示例,很好地诠释了使用日志来排查程序问题的实践方法。他举了一个计算阶乘的示例:
import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.debug('Start of program')
def factorial(n):
logging.debug('Start of factorial(%s)' % (n))
total = 1
for i in range(n + 1):
total *= i
logging.debug('i is ' + str(i) + ', total is ' + str(total))
logging.debug('End of factorial(%s)' % (n))
return total
print(factorial(5))
logging.debug('End of program')
运行结果:
这里首先加载 logging 模块,然后使用 basicConfig 方法,初始化日志配置。日志格式说明如下:
格式 | 说明 |
---|---|
%(asctime)s | 日志时间。 |
%(levelname)s | 日志级别名称。 |
%(message)s | 日志具体内容。 |
通过 logging 模块所打印的 debug 日志可以看出,因为 i 从 0 开始,导致阶乘计算失败,结果始终为 0。
修复程序,让其从 1 开始:
运行结果:
2 杜绝 print() 诱惑
采用日志模块的好处是,通过配置,就可以控制日志输出级别或禁用日志。这样我们可以随心所欲地在程序中的任意位置加上我们所需要的日志。而 print() 方法就没有这些好处。
3 日志级别
“日志级别”可以按重要性对日志消息进行分类。 5 个日志级别如表 1 所示,从最不重要到最重要。利用不同的日志级别函数,我们可以将需要记录的内容按照某种级别写入日志。
表 1 logging 模块日志级别
级别 | 日志函数 | 说明 |
---|---|---|
DEBUG | logging.debug() | 最低级别,一般用于代码调试,诊断问题。 |
INFO | logging.info() | 记录程序中一般事件,或确认一切工作正常。 |
WARNING | logging.warning() | 警告日志,表述可能存在的问题。 |
ERROR | logging.error() | 错误日志,用于记录错误,因为它导致程序执行某段逻辑失败。 |
CRITICAL | logging.critical() | 最高级别。用于表示致命错误,因为它导致程序停止工作。 |
日志内容作为一个字符串,传递给以上这些日志函数。最终,是由编码者来决定采用哪种级别来记录这些日志。
我们可以控制日志输出级别,比如向向 basicConfig() 函数传入 logging.DEBUG 作为 level 关键字参数,这会
显示所有日志级别的消息。如果将 level 参数设置为 logging.ERROR,这样只会显示 ERROR 和 CRITICAL 级别的消息。也就是说,日志级别指定在哪一级,对应级别及其以上级别,才会显示出来。
4 关闭日志
利用 disable() 就可以关闭日志功能。只要向 logging.disable() 传入一个日志级别,它就会关闭该级别及其更低级别的所有日志消息。所以,如果想要关闭所有日志,只要在程序中添加 logging.disable(logging.CRITICAL)。
运行结果:
因为 logging.disable() 将关闭它之后的所有日志消息,所以建议将它添加到程序中接近 import logging 代码行的位置。这样可以容易找到它,然后根据实际需要,启用或关闭日志消息。
5 记录到日志文件
利用 logging.basicConfig() 函数的 filename 关键字参数,我们可以把日志消息写入文件中。
import logging
# logging.disable(logging.CRITICAL)
logging.basicConfig(filename='log.txt',level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
这时,就会在 *.py 的同级目录下找到写入的 log.txt 日志文件。