关于Python的logging模块初始化无效的一个小坑

2016/4/19 23:45 下午 posted in  Python

众所周知,logging模块是一个非常方便好用的日志输出模块。但是最近的使用发现了一个小坑,记录一下,避免再次踩坑。

一般使用logging模块都会对其进行初始化,使用以下代码:

    log_format = '[%(levelname)s] %(asctime)s  %(filename)s line %(lineno)d: %(message)s'
    date_fmt = '%a, %d %b %Y %H:%M:%S'
    logging.basicConfig(
        format=log_format,
        datefmt=date_fmt,
        level=log_level,
    )

或者,只是简单使用,可以不初始化,直接logging.info("blablabla")

但是,如果当你先直接不初始化logging设置,直接输出之后,你再尝试初始化,你的设置将不会不会生效。尝试以下代码

# -*- coding: utf-8 -*-
import logging

def init_logging(log_level=logging.INFO):
    log_format = '[%(levelname)s] %(asctime)s  %(filename)s line %(lineno)d: %(message)s'
    date_fmt = '%a, %d %b %Y %H:%M:%S'
    logging.basicConfig(
        format=log_format,
        datefmt=date_fmt,
        level=log_level,
    )


if __name__ == '__main__':
    logging.critical("critical")
    logging.warning("warning")
    logging.info("info")
    logging.debug("debug")

    init_logging(logging.DEBUG)
    print "\n"
    print "initial finished."
    print "\n"

    logging.critical("critical")
    logging.warning("warning")
    logging.info("info")
    logging.debug("debug")

输出:

CRITICAL:root:critical
WARNING:root:warning


initial finished.


CRITICAL:root:critical
WARNING:root:warning

输出中,因为logging默认等级为warning,所以成功输出critical和warning
但当初始化之后,其输出格式原本应该改变,并且输出等级应该变为DEBUG,但是从输出可以看到,和初始化前的输出没有任何区别,说明初始化没有生效。这一问题在官方文档中有简单提及

The call to basicConfig() should come before any calls to debug(), info() etc. As it’s intended as a one-off simple configuration facility, only the first call will actually do anything: subsequent calls are effectively no-ops.