原文链接:https://blog.csdn.net/huilan_same/article/details/51858817
在用logging模块写日志的时候,遇到了日志重复打印的问题。即在同一个脚本中第一次调用,正常显示,第二次调用,则显示了重复的两条,以此类推,非常头疼。
网上找到原因:没有删除前一次调用的handle对象
示例
importloggingdeflog(message):
logger= logging.getLogger('testlog')
streamhandler=logging.StreamHandler()
streamhandler.setLevel(logging.ERROR)
formatter= logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
streamhandler.setFormatter(formatter)
logger.addHandler(streamhandler)
logger.error(message)if __name__ == '__main__':
log('hi')
log('hi too')
log('hi three')
输出结果:
2016-07-08 09:17:29,740 - ERROR - testlog -hi2016-07-08 09:17:29,740 - ERROR - testlog -hi too2016-07-08 09:17:29,740 - ERROR - testlog -hi too2016-07-08 09:17:29,740 - ERROR - testlog -hi three2016-07-08 09:17:29,740 - ERROR - testlog -hi three2016-07-08 09:17:29,740 - ERROR - testlog - hi three
修改后的代码:
importloggingdeflog(message):
logger= logging.getLogger('testlog')
streamhandler=logging.StreamHandler()
streamhandler.setLevel(logging.ERROR)
formatter= logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
streamhandler.setFormatter(formatter)
logger.addHandler(streamhandler)
logger.error(message)#添加下面一句,在记录日志之后移除句柄
logger.removeHandler(streamhandler)if __name__ == '__main__':
log('hi')
log('hi too')
log('hi three')
修改后显示结果:
2016-07-08 09:32:28,206 - ERROR - testlog -hi2016-07-08 09:32:28,206 - ERROR - testlog -hi too2016-07-08 09:32:28,206 - ERROR - testlog - hi three
深度解析
第二次调用log的时候,根据getLogger(name)里的name获取一个logger对象,而这个logger对象里已经有了第一次添加的handler,第二次又添加了一个handler,所以logger对象里有两个相同的handler,以此类推,调用几次就有几个handler。
解决方法:1.每次调用都修改getLogger(name) 中的name
2.使用removeHandler(handlername)
3.在log方法里做判断,是否已经存在handler
4.使用pop函数把handle列表中的handler删除
方法三:
importloggingdeflog(message):
logger= logging.getLogger('testlog')#这里进行判断,如果logger.handlers列表为空,则添加,否则,直接去写日志
if notlogger.handlers:
streamhandler=logging.StreamHandler()
streamhandler.setLevel(logging.ERROR)
formatter= logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
streamhandler.setFormatter(formatter)
logger.addHandler(streamhandler)
logger.error(message)if __name__ == '__main__':
log('hi')
log('hi too')
log('hi three')
方法四:
importloggingdeflog(message):
logger= logging.getLogger('testlog')
streamhandler=logging.StreamHandler()
streamhandler.setLevel(logging.ERROR)
formatter= logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
streamhandler.setFormatter(formatter)
logger.addHandler(streamhandler)
logger.error(message)#用pop方法把logger.handlers列表中的handler移除,注意如果你add了多个handler,这里需多次pop,或者可以直接为handlers列表赋空值
logger.handlers.pop()#logger.handler = []
if __name__ == '__main__':
log('hi')
log('hi too')
log('hi three')