Python 中 Logging 模块使用方法

简介

在代码调试过程中,我们使用最多的方法是 print 函数,在我们需要知道中间变量的值时,插入一句 print 函数即可。但这种方法存在一个问题,那就是在程序调试完以后我们需要一个一个把 print 函数删掉或者注释掉。logging 模块能非常好得解决这个问题,通过设置 severity level,我们可以方便得控制在控制台打印的信息,另外我们也可以同时把日志信息输出到多个目的地,比如控制台,日志文件,网络位置等。

logging 基本用法

Logging 的基本用法非常简单,比如下面这个例子:

1
2
3
4
5
import logging
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 模块。
  • 然后利用函数 logging.basicConfig 设置 logger 的行为。其中,filename 指定日志文件,默认情况下,日志输出至控制台。level 指定记录日志的 severity level,logging 模块有 DEBUG, INFO, WARNING, ERROR, CRITICAL 五个从低到高的 severity level,logger 只输出与 level 参数指定级别相同更高级别的日志信息,比如,如果我们让 level=logging.INFO,上面程序中 logging.debug 信息在执行过程中将不会输出。当然,filenamelogging.basicConfig 可以传入很多参数,具体可以参考官方文档
  • 最后在需要记录日志的地方根据需要的 severity level 添加 logging.debug 等日志信息。

Logging 模块的基本用法是通过创建 Loggers 对象来实现的,Loggers 对象提供了很多方法来操作其属性,比如 setLevel 方法可以用来改变其 severity level。我们可以通过以下程序在不同模块中创建 Loggers 对象:

1
logger = logging.getLogger(__name__)

其中,name 是该模块的名字,当然我们也可以自己给该 logger 取一个名字。每次调用 logging.getLogger 便创建了一个指定名字的 logger,在同一个线程中,不管调用多少次该函数,相同名字都指向同一个 logger 对象。

Logging 模块通过层级结构来组织这些 loggers 对象,在同一个线程中,所有 loggers 对象都继承自 root logger,前面程序中的 logging.basicConfig 便创建了一个 root logger。loggers 对象之间的继承关系用类似于a.b.c的方式表示,如果子对象指定了属性,则使用它自己的属性进行输出,如果没有则使用其父对象的属性进行输出,比如前面的 logging.basicConfig 函数设置了 root logger 的属性,如果后面创建的子对象都没有设置属性,那么 root logger 的属性将在所有 logger 对象间共享。

logging 工作流程

上一节介绍的是 logging 模块的基本用法,利用上面这些知识进行基本的程序调试已经没有问题了。然而,logging 模块的功能并不仅仅于此,事实上,Logging 模块包含 Loggers, Handlers, Filters 和 Formatters 等多个类,我们可以利用这些类来对日志进行更加精细化的控制。在这之前,我们需要了解 logging 模块的工作流程,如下图所示:

  • Loggers 类是整个 logger 的载体,一般使用 getLogger 方法来创建。然后我们可以为创建好的 Logger 实体设置 severity level(调用方法 Logger.setLevel()),设置 Filters(filter 能比 severity level 更精细化的控制 logger 向后面 handler 的输出,一个 logger 可以设置多个 filter,所有 filter 的过滤关系是串联的,调用方法 Logger.addFilter()),设置 Handlers(handler 的作用是指定 logger 的最终输出去向,比如可以终端输出,可以写入日志文件,可以放入某个网络服务器等,一个 loggers 可以设置多个 handler,调用方法 Logger.addHandler())
  • Hanlder 类指定 logger 的输出去向,常用的 Handler 有 StreamHandler, FileHandler 和 SocketHandler 等。跟 Logger 类一样,我们也可以为 Handler 设置 severity level 和 filter,用法和 logger 也差不多,这样可以对最终输出进行更加精细化的控制。另外,我们可以设置最后的输出格式(调用方法 setFormatter())
  • Formatters 和 Filters 类顾名思义就是设置最终的输出格式和滤波器

Reference

[1] Logging HOWTO
[2] Logging Cookbook
[3] Logging facility for Python
[4] 替换你的print(logging模块超简明指南)
[5] logging的用法

Contents
  1. 1. 简介
  2. 2. logging 基本用法
  3. 3. logging 工作流程
  4. 4. Reference
|