以前看过,但一直认为很复杂。象 NewEdit 都是自已写的日志处理。其实 logging 做得很好,也不是很复杂,只要看明白例子。在新发布的crawl 2.1.1中使用了logging,下面把它的使用代码写出来,很简单:

1       def initlog():
2           import logging
3          
4           logger = logging.getLogger()
5           hdlr = logging.FileHandler(logfile)
6           formatter = logging.Formatter(‘%(asctime)s %(levelname)s %(message)s’)
7           hdlr.setFormatter(formatter)
8           logger.addHandler(hdlr)
9           logger.setLevel(logging.NOTSET)
10         
11          return logger

这个函数用来返回一个日志对象。

第4行生成一个日志对象,可以带一个名字,可以缺省。
第5行生成一个Handler。logging支持许多Handler,象FileHandler, SocketHandler, SMTPHandler等,我由于要写文件就使用了FileHandler。logfile是一个全局变量,它就是一个文件名,如:’crawl.log’。
第6行生成一个格式器,用于规范日志的输出格式。如果没有这行代码,那么缺省的格式就是:”%(message)s”。也就是写日志时,信息是什么日志中就是什么,没有日期,没有信息级别等信息。logging支持许多种替换值,详细请看Formatter的文档说明。这里有三项:时间,信息级别,日志信息。
第7行将格式器设置到处理器上。
第8行将处理器加到日志对象上。
第9行设置日志信息输出的级别。logging提供多种级别的日志信息,如:NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL等。每个级别都对应一个数值。如果不执行此句,缺省为30(WARNING)。可以执行:logging.getLevelName(logger.getEffectiveLevel())来查看缺省的日志级别。日志对象对于不同的级别信息提供不同的函数进行输出,如:info(), error(), debug()等。当写入日志时,小于指定级别的信息将被忽略。因此为了输出想要的日志级别一定要设置好此参数。这里我设为NOTSET(值为0),也就是想输出所有信息。

有了日志对象,输出就非常简单了:

logger.error(message)
logger.info(message)


9条评论

  1. 非常有用,感觉豁然开朗.

  2. 很有用,谢谢你的例子!

  3. 经过测试:

    设置为这个

    logger.setLevel(logging.NOTSET)

    那么logger.debug, logger.info无法写入日志。

    实际效果:logger.setLevel(logging.NOTSET) 变成了logger.setLevel(logging.WARNING)

    设置为

    logger.setLevel(logging.DEBUG)

    才可以。 

    Level Numeric value

    CRITICAL 50

    ERROR 40

    WARNING 30

    INFO 20

    DEBUG 10

    NOTSET 0

    例子:

    import logging

    conf={}

    conf["name"]="debug"

    conf["filename"]="a.txt"

    conf["format"]="[%(asctime)s]: %(message)s"

    conf["datefmt"]="%Y-%m-%d %H:%M:%S"

    conf["level"]=0

    logger=logging.getLogger(conf["name"])

    handler=logging.FileHandler(conf["filename"])

    fmt = logging.Formatter(conf["format"],conf["datefmt"])

    handler.setFormatter(fmt)

    logger.addHandler(handler)

    logger.setLevel(logging.DEBUG)

    logger.debug("dddd")

    logger.info("dddddddddd")

    logger.warning("warning!!!")

    print logger

  4. good

  5. 现在我有个问题想问一下,我打开一个LOG文件并输出,最后怎么关闭这个LOG文件呢?shutdown?

    代码如下:

    class CLogInfo:

    #output the information to log,it will be instanced in testcase modele.

    def __init__(self,logfile="testcase.log"):

    try:

    import logging

    self.logger = None

    self.logger = logging.getLogger()

    self.hdlr = logging.FileHandler(logfile)

    formatter = logging.Formatter("[%(asctime)s]: %(message)s","%Y-%m-%d %H:%M:%S")

    self.hdlr.setFormatter(formatter)

    self.logger.addHandler(self.hdlr)

    self.logger.setLevel(logging.DEBUG)

    except:

    print "log init error!"

    #exit(1)

    def output(self,logInfo,errFlag=0):

    try:

    if (errFlag):

    self.logger.error("error:"+logInfo)

    #exit(errFlag)

    else:

    self.logger.info(logInfo)

    except:

    print "log output error!"

    #exit(1)

    def close(self):

    try:

    logging.shutdown([self.hdlr])

    except error:

    print "log closed error!"

    #exit(1)

    然后运行:

    from logtest import CLogInfo,c1

    log = CLogInfo("1.log")

    log.output("aaa right")

    这些都正确,但是

    log.close()就提示错误,有知道如何关闭log文件的么?

  6. I have find it:

    self.logger.removeHandler(self.hdlr)

  7. 非常不错,谢谢了,我想问一下,这个写日志的有那种回滚的函数嘛,要是一直写,如果是一个daemon程序,岂不是日志会越来越大,怎么把时间最旧的给删除呀,有自带的函数没,谢谢。。

  8. def shutdown(handlerList=_handlerList):

    """

    Perform any cleanup actions in the logging system (e.g. flushing

    buffers).

    Should be called at application exit.

    """

    for h in handlerList[:]:

    #errors might occur, for example, if files are locked

    #we just ignore them if raiseExceptions is not set

    try:

    h.flush()

    h.close()

    except:

    if raiseExceptions:

    raise

    #else, swallow

    #Let’s try and shutdown automatically on application exit…

  9. 日志消息同时输出到stderr和日志文件,stderr中文正常显示,日志文件中中文部分是乱码.

发表评论

评论也有版权!

click to change验证码