Python标准日志模块logging简介

jopen 12年前

前一段工作的时候用到了python写后台系统,需要把一些系统的行为记录下来。本着不要去重复发明轮子的精神,就去搜索了一下python的系统库本身是否有写日志的模块。果然有。python语言作为一门接口简单,标准库强大的语言,果然没有令我失望。

简单的使用方法

python的标准库里的日志系统从Python2.3开始支持。只要import logging这个模块即可使用。如果你想把日志写入指定的一个文件中,只要这样使用:

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 %s %d, too','123',1)

basicConfig是指定文件的路径和日志的级别。

日志一共分成5个等级,从低到高分别是:DEBUG INFO WARNING ERROR CRITICAL。这5个等级,也分别对应5种打日志的方法: debug info ,warning error critical。这5种方法都是类似C语言的printf的方法。 在basicConfig中设置的是日志的最低级别,换句话说,在程序中,只有使用了更高等级的日志信息才会打印出来。 比如你设置的日志级别是logging.INFO, 那么只有使用info, warning, error, critical这4种方法日志才会被记录下来,debug的日志将会被忽略。

用上面的方法,简单的日志就可以被打印出来了。不过logging模块的功能非常强大,你还可以通过更加自由的接口,自定义出更复杂的日志形式。需要用到下面3种对象:

logger formatter handler .

logger

logger对象直接提供日志接口。formatter描述日志的格式。handler把日志写到不同的地方,你可以把日志保存成本地文件,也可以每个小时写一个日志文件,还可以把日志通过socket传到别的机器上。

从最简单的formatter对象来看。formatter指定的是每一条日志记录的抬头信息,也就是你可以指定日志记录的时间格式、进程号、文件名、函数名等信息。可以用这个方法来创建一个formatter对象:

logging.Formatter.__init__( fmt=None, datefmt=None)

fmt参数指定进程号、文件名、函数名等信息是否出现以及格式, datefmt为日期时间格式,默认的日期格式精确到微秒,例如‘2003-07-08 16:49:45,896’。fmt中可以指定多个字段,每个字段的格式为“%( key>)s”, 例如你想打印时间、日志级别、日志信息可以用下面的format:

'%(asctime)s - %(levelname)s - %(message)s'

所有的可以使用的字段如下表:

Python标准日志模块logging简介

hander

通过handler对象可以把日志内容写到不同的地方。比如简单的StreamHandler就是把日志写到类似文件的地方。python提供了十几种实用handler,比较常用和比较有意思的我列举一下:

StreamHandler 写入类文件的流。

BaseRotatingHandler 可以按时间写入到不同的日志中。比如将日志按天写入不同的日期结尾的文件文件。

SocketHandler 用TCP网络连接写LOG

DatagramHandler 用UDP网络连接写LOG

SMTPHandler 把LOG写成EMAIL邮寄出去

等等

简单的例子来说明下 formatter handler logger 3个对象之间的交互吧。

#!/usr/bin/python  #coding: utf-8    import logging  import logging.handlers    logger = logging.getLogger()  logger.setLevel(logging.DEBUG)    rh=logging.handlers.TimedRotatingFileHandler('loggertester','D')  fm=logging.Formatter("%(asctime)s  %(levelname)s - %(message)s","%Y-%m-%d %H:%M:%S")  rh.setFormatter(fm)  logger.addHandler(rh)    debug=logger.debug  info=logger.info  warn=logger.warn  error=logger.error  critical=logger.critical    info("testlog1")  warn("warn you %s","costaxu")  critical("it is critical")