文章目录

  • Python日志模块的使用--基础教程
  • 参考文章
  • 什么时候使用?
  • 一个简单的示例
  • 日志记录到文件
  • 改变变量数据
  • 更改显示消息的格式
  • 在消息中显示日期/时间
  • 稍微高级一点的用法:从多个模块记录日志
  • 总结


Python日志模块的使用–基础教程


我们平时是如何对我们的软件进行追踪,或者查看某事件的发生呐。相信有些同学可能是用以下方式:

...
print(11111111)
...
print(22222222)
...
# 数字用完了再接着用字母
print(aaaaaaaa)

不要问我是怎么知道的。

什么时候使用?

当然,并不是说上述方式不可以,相反,不同的场景有不同的需求,如果你只是调试一个几十行的简单脚本,我还会鼓励你这么做:因为这样确实会很方便快捷。但是我们确实也有更科学、严谨、美观的做法,Python自带的log模块十分强大,本教程只能展现一二。

该使用何种工具的表格:

你想要执行的任务

此任务的最好的工具

对于命令行或程序的应用,结果显示在控制台。

print()

在对程序的普通操作发生时提交事件报告(比如:状态监控和错误调查)

logging.info() 函数(当有诊断目的需要详细输出信息时使用 logging.debug() 函数)

提出一个警告信息基于一个特殊的运行时事件

warnings.warn() 位于代码库中,该事件是可以避免的,需要修改客户端应用以消除告警logging.warning() 不需要修改客户端应用,但是该事件还是需要引起关注

对一个特殊的运行时事件报告错误

引发异常

报告错误而不引发异常(如在长时间运行中的服务端进程的错误处理)

logging.error(), logging.exception() 或 logging.critical() 分别适用于特定的错误及应用领域

日志级别适用性:

级别

何时使用

DEBUG

细节信息,仅当诊断问题时适用。

INFO

确认程序按预期运行

WARNING

表明有已经或即将发生的意外(例如:磁盘空间不足)。程序仍按预期进行

ERROR

由于严重的问题,程序的某些功能已经不能正常执行

CRITICAL

严重的错误,表明程序已不能继续执行

一个简单的示例

import logging
logging.warning('Watch out!')  # will print a message to the console
logging.info('I told you so')  # will not print anything
# 打印
# WARNING:root:Watch out!

输出到命令行。INFO 消息并没有出现,因为默认级别是 WARNING 。打印的信息包含事件的级别以及在日志调用中的对于事件的描述,例如“Watch out!”。暂时不用担心“root”部分:之后会作出解释。输出格式可按需要进行调整,格式化选项同样会在之后作出解释。

日志记录到文件

一种非常常见的情况是将日志事件记录到文件,值得一提的是,在最新的3.9版本,可以直接设置编码模式,3.9之前的版本则不可以。

简单来说,通过设置logging.basicConfig(),可以控制日志是输出到控制台,还是保存到文件,还可以控制日志的级别,我们建议无论是打印到那,都把这个加上,如果想输出到控制台,把filename='example.log'去掉就好。

# Python3.9
import logging
logging.basicConfig(filename='example.log', encoding='utf-8', level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
logging.error('And non-ASCII stuff, too, like Øresund and Malmö')

# Python3.9之前
import logging
with open('example.log', encoding='utf-8', mode='w') as f:
    f.write("log test\n")
logging.basicConfig(filename='example.log', level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
logging.error('And non-ASCII stuff, too, like resund and Malm')

改变变量数据

使用占位符实现打印变量

import logging
logging.warning('%s before you %s', 'Look', 'leap!')

# 输出
# WARNING:root:Look before you leap!

更改显示消息的格式

如果你不想显示那让人摸不着头脑的root:

import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')

# 输出
# DEBUG:This message should appear on the console
# INFO:So should this
# WARNING:And this, too

在消息中显示日期/时间

另一个常用的功能就是显示时间了,我们按照上面的格式稍微拓展一下:

import logging
logging.basicConfig(format='%(asctime)s %(levelname)s:%(message)s', level=logging.DEBUG)
logging.warning('is when this event was logged.')

# 输出
# 2020-12-31 22:53:59,627 WARNING:is when this event was logged.

或者我们想更近一步,改变时间显示的格式:

import logging
logging.basicConfig(format='%(asctime)s %(levelname)s:%(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')

# 输出
# 12/31/2020 10:57:49 PM WARNING:is when this event was logged.

稍微高级一点的用法:从多个模块记录日志

# myapp.py
import logging
import mylib

def main():
    logging.basicConfig(filename='myapp.log', level=logging.INFO)
    logging.info('Started')
    mylib.do_something()
    logging.info('Finished')

if __name__ == '__main__':
    main()
# mylib.py
import logging

def do_something():
    logging.info('Doing something')
    
# 打印
# INFO:root:Started
# INFO:root:Doing something
# INFO:root:Finished

总结

上述的这些操作,足够日常的操作使用,但是官方提供的日志模块其实功能十分强大,可玩性也非常强,建议大家去阅读官方文档或者搜搜网上大神怎么玩的。有了这个东西,我们就不再是单调的print()了,感觉自己离正儿八经的程序员又近了一步(狗头保命)。