您的位置:首页 > 编程语言 > Python开发

python模块---logging(日志管理)

2012-10-12 11:53 826 查看
一般情况下,一些程序的调试过程中我们会让它输出一些信息,特别是一些大型的程序,我们通过这些信息可以了解程序的运行情况,python提供了一个日志模块logging,它可以把我们想要的信息全部保存到一个日志文件中,方面我们查看。最近做的项目,有一些业务处理逻辑是先将数据写入队列,然后通过python读取队列中的内容,继续处理后续的逻辑。因为队列消费一次就没了,所以做好日志记录格外重要;

test_log1.py

#! /usr/bin/python

import logging
LOG_FILENAME="log_test.txt"
logging.basicConfig(filename=LOG_FILENAME,level=logging.NOTSET)
logging.debug("This message should go to the log file")

LOG_FILENAME_22="log_test22.txt"
logging.basicConfig(filename=LOG_FILENAME_22,level=logging.DEBUG)
logging.debug("This message 222should go to the log file")


执行结果:

只生成了一个log_test.txt文件,文件内容是:

DEBUG:root:This message should go to the log file
DEBUG:root:This message 222should go to the log file

而没有生成log_test22.txt文件.

原因:查看logging的文档:

FUNCTIONS
addLevelName(level, levelName)
Associate 'levelName' with 'level'.

This is used when converting levels to text during message formatting.

basicConfig(**kwargs)
Do basic configuration for the logging system.

 This function does nothing if the root logger already has handlers
configured. It is a convenience method intended for use by simple scripts
to do one-shot configuration of the logging package.

The default behaviour is to create a StreamHandler which writes to
sys.stderr, set a formatter using the BASIC_FORMAT format string, and
add the handler to the root logger.

A number of optional keyword arguments may be specified, which can alter
the default behaviour.

filename  Specifies that a FileHandler be created, using the specified
filename, rather than a StreamHandler.
filemode  Specifies the mode to open the file, if filename is specified
(if filemode is unspecified, it defaults to 'a').
format    Use the specified format string for the handler.
datefmt   Use the specified date/time format.
level     Set the root logger level to the specified level.
stream    Use the specified stream to initialize the StreamHandler. Note
that this argument is incompatible with 'filename' - if both
are present, 'stream' is ignored.


test_log2.py

>>> import logging
>>> logger=logging.getLogger()
>>> handler=logging.FileHandler("Log_test.txt")
>>> logger.addHandler(handler)
>>> logger.setLevel(logging.NOTSET)
>>> logger.error("This is an error message")
>>> logger.info("This is an info message")
>>> logger.critical("This is a critical message")


日志文件中会出现三行内容:

This is an error message

This is an info message

This is a critical message

上面程序的第2行是生成一个日志对象,里面的参数时日志的名字,可以带,也可以不带。

第3行是生成了一个handler,logging支持很多种Handler,像FileHandler,SocketHandler等待,这里由于我们要写文件,所以用了FileHandler,它的参数就是filename,默认当前路径,当然我们可以自己指定路径。

第5行设置日志信息输出的级别。Logging提供了多种日志级别,如NOTSET,DEBUG,INFO,WARNING,ERROR,CRITICAL等,每个级别都对应一个数值,如果我们不自己设置输出级别,那么系统会执行缺省级别,值为30,就warning。Logging也提供了一个方法来查看缺省日志级别,getLevelName(logger,getEffectiveLevel())。



如果想将写入日志的这个功能抽象出一个方法出来,并且能够制定不同的日志写入不同的文件里,如,

test_log3.py

#! /usr/bin/python

import logging
def setLog(log_filename,log_message):
logger=logging.getLogger()
handler=logging.FileHandler(log_filename)
logger.addHandler(handler)
logger.setLevel(logging.NOTSET)
logger.debug(log_message)
# 如果没有此句话,则会将同一个message追加到不同的log中
logger.removeHandler(handler)

if __name__ =='__main__':
setLog('Log_test','it all right')
setLog('Log_test88','it all righ8888t')
setLog('Log_test99','it all righ999t')


上面最重要的是:logger.removeHandler(handler),没有了这行code,'it all righ8888t'会写入到Log_test文件中;

日志对象对于不同的级别信息提供不同的函数进行输出,如:info(), error(), debug()等。当写入日志时,小于指定级别的信息将被忽略。因此为了输出想要的日志级别一定要设置好此参数。这里我设为NOTSET(值为0),也就是想输出所有信息。系统默认的日志级别排序为,CRITICAL,ERROR,WARNING,INFO,DEBUG,NOTSET。比如说我们要输出的信息为CRITICAL,但是我们的日志级别为DEBUG,那么这个信息将被忽略掉。我们看下面的例子:

test_log4.py

#! /usr/bin/python
# -*- coding: utf-8 -*-

import logging
import sys
LEVELS={'debug':logging.DEBUG,
'info':logging.INFO,
'warning':logging.WARNING,
'error':logging.ERROR,
'critical':logging.CRITICAL}

if len(sys.argv)>1:
level_name=sys.argv[1]
level=LEVELS.get(level_name,logging.NOTSET)
logging.basicConfig(level=level)

logging.debug("This is a debug message")
logging.info("This is an info message")
logging.warning("This is a warning message")
logging.error("This is an error message")
logging.critical("This is a critical error message")


执行结果:



可以看到过滤进行的很明显。当我们设置级别最低位debug时,所有的信息都输出了,当我们设为最高位critical时候,只有critical输出了,低于critical的被过滤了。

Logging是非常有用的,一个程序的健壮性也这个有关,当一个程序包含很多的调试信息时,可以方便我们发现问题,发现错误。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: