我正在学习使用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
答案 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
不确定这是否是最合适的方法,但现在正如我所料的那样工作。