Python内置了很多非常使用的模块,logging 模块是用于控制和输出日志的,它是一个非常强大的日志模块,可以按照不同的需求配置。它的官方文档地址是在这里

我自己也用过几次logging模块,但是前面用的时候都把它用得太复杂了,还自己封装了下。其实,有些代码越是简单越好,写得复杂得反而不容易扩展和使用。

以下是我在脚本中用到的一段代码:

def init_log(log_file):
    '''Initialize logging module.
    '''
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)

    formatter = logging.Formatter('[%(levelname)s] %(message)s')

    # Create a file handler to store error messages
    fhdr = logging.FileHandler(log_file, mode = 'w')
    fhdr.setLevel(logging.ERROR)
    fhdr.setFormatter(formatter)

    # Create a stream handler to print all messages to console 
    chdr = logging.StreamHandler()
    chdr.setFormatter(formatter)

    logger.addHandler(fhdr)
    logger.addHandler(chdr)

    return logger

代码的意思很简单,这里就不多加解释了,需要注意的是第5行不能少,要不然会出现问题。因为当logging模块输出的日志分成多个级别,例如DEBUG、INFO、WARN、ERROR等。当没有通过setLevel方法设置日志级别的话,系统默认的日志级别是WARN,也就是说只胡日志级别大于等于WARN的日志才会输出可见,例如ERROR,而日志级别比它低的则被过滤掉了,例如DEBUG。

那为什么这一行不能少呢?因为当一条日志要打印输出时,首先会看这条日志的级别是否大于logging.setLevel设置的级别或者默认的WARN,如果不是则直接过滤掉;如果大于,则会发送给Logger对象绑定的各个handler对象,交由它们进一步处理日志,或者输出到屏幕,或者写入到文件中。而每个handler对象也会有它自己设置的日志级别,然后再进一步地过滤。所以如果不包含第5行,然后StreamHandler对象设置的日志级别是DEBUG的话,其实是没有意义的。

使用方法:

logger = init_logger('test.log')
logger.debug('%s, %s', 'hello', 'world');
logger.info(...)
logger.warn(...)
logger.error(...)