迭代中的空记录器

时间:2017-03-04 02:02:05

标签: python python-3.x logging

我正在学习使用Python(3.6.0)中的logging模块,并从Logging Cookbook的示例开始。但是,当代码从循环内运行时,日志消息会重复多次。这是为什么?在这种情况下有没有办法清空记录器?我尝试使用logger.propagate,但没有成功。

我在脚本testlog.py中的代码:

#!/usr/bin/env python3

import logging

def main():
    t = (1,2,1,2,1)

    logit('Log is fine here', '_logfile', logname='INFO', level='info')

    for i,x in enumerate(t):
        if x == 1:
            logit('Warn at iter {}'.format(i), '_logfile', logname='INFO', level='info')


def logit(message, logfile, logname='LOG', level='info'):
    '''https://docs.python.org/3.6/howto/logging-cookbook.html#logging-to-multiple-destinations'''

    logformat = '%(asctime)-30s %(levelname)-8s %(name)s\t%(message)s'
    dateformat = '[ %Y-%m-%d  %H:%M:%S ]'
    # set up logging to file
    logging.basicConfig(level=logging.DEBUG,
                        format=logformat,
                        datefmt=dateformat,
                        filename=logfile,
                        filemode='a')

    # define a Handler which writes INFO messages or higher to the sys.stderr
    console = logging.StreamHandler()
    console.setLevel(logging.DEBUG)
    # set a format which is simpler for console use
    formatter = logging.Formatter(logformat, datefmt=dateformat)
    # tell the handler to use this format
    console.setFormatter(formatter)
    # add the handler to the root logger
    logging.getLogger('').addHandler(console)
    # Now, we can log to the logger
    logger = logging.getLogger(logname)
    console.propagate = False

    if level.lower() == 'debug':
        logger.debug(message)
    elif level.lower() == 'info':
        logger.info(message)
    elif level.lower().startswith('warn'):
        logger.warning(message)
    else:
        logger.error(message)

if __name__ == '__main__':
    main()

输出:

> ./testlog.py 
[ 2017-03-04  01:59:09 ]       INFO     INFO    Log is fine here
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 0
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 0
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 2
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 2
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 2
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 4
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 4
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 4
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 4

EDIT1 :我们的想法是登录控制台和日志文件。 在日志文件中不会重复这些消息。

[ 2017-03-04  01:59:09 ]       INFO     INFO    Log is fine here
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 0
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 2
[ 2017-03-04  01:59:09 ]       INFO     INFO    Warn at iter 4

2 个答案:

答案 0 :(得分:0)

具体是因为logit中的以下行: logging.getLogger('').addHandler(console)

每次拨打logit时,您都会向根记录器添加另一个StreamHandler。您应该完成一次记录器的所有配置。

答案 1 :(得分:0)

我按照以下方式使其工作(大多数代码改编自here)。 首先需要一个函数来创建记录器并向其添加不同的处理程序。每个处理程序都可以拥有自己的设置级别:

def set_logger(logfile, logname='LOG'):

    logformat = '%(asctime)-30s %(levelname)-8s %(name)s\t%(message)s'
    dateformat = '[ %Y-%m-%d  %H:%M:%S ]'

    # Setup Logging Object
    logger = logging.getLogger(logname)
    logger.setLevel(logging.DEBUG)
    # Set log object to console
    chandler = logging.StreamHandler()
    chandler.setLevel(logging.DEBUG)
    formatter = logging.Formatter(logformat, datefmt=dateformat)
    chandler.setFormatter(formatter)
    logger.addHandler(chandler)

    # Set log object to file
    fhandler = logging.FileHandler(filename=logfile,
                                    mode='a')
    fhandler.setLevel(logging.DEBUG)
    formatter = logging.Formatter(logformat, datefmt=dateformat)
    fhandler.setFormatter(formatter)
    logger.addHandler(fhandler)

    return logger

然后可以在main()中检索记录器:

def main():

    logger=set_logger('_logfile')

    t = (1,2,1,2,1)

    # logit3('Log is fine here', '_logfile', logname='INFO', level='info')
    logger.debug('Log is fine here')

    for i,x in enumerate(t):
        if x == 1:
            # logit3('Warn at iter {}'.format(i), '_logfile', logname='INFO', level='info')
            logger.debug('Warn at iter {}'.format(i))

控制台中的输出是:

[ 2017-03-04  11:21:02 ]       DEBUG    LOG Log is fine here
[ 2017-03-04  11:21:02 ]       DEBUG    LOG Warn at iter 0
[ 2017-03-04  11:21:02 ]       DEBUG    LOG Warn at iter 2
[ 2017-03-04  11:21:02 ]       DEBUG    LOG Warn at iter 4

日志文件中的输出是:

[ 2017-03-04  11:21:02 ]       DEBUG    LOG Log is fine here
[ 2017-03-04  11:21:02 ]       DEBUG    LOG Warn at iter 0
[ 2017-03-04  11:21:02 ]       DEBUG    LOG Warn at iter 2
[ 2017-03-04  11:21:02 ]       DEBUG    LOG Warn at iter 4

不确定这是否是最合适的方法,但现在正如我所料的那样工作。