python logging 重复写日志问题解决办法详解


Posted in Python onAugust 04, 2020

python logging 重复写日志问题

用Python的logging模块记录日志时,遇到了重复记录日志的问题,第一条记录写一次,第二条记录写两次,第三条记录写三次。。。很头疼,这样记日志可不行。网上搜索到了原因与解决方案:

原因:没有移除handler
解决:在日志记录完之后removeHandler

修改前示例代码:

import logging


def log(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 - hi
2016-07-08 09:17:29,740 - ERROR - testlog - hi too
2016-07-08 09:17:29,740 - ERROR - testlog - hi too
2016-07-08 09:17:29,740 - ERROR - testlog - hi three
2016-07-08 09:17:29,740 - ERROR - testlog - hi three
2016-07-08 09:17:29,740 - ERROR - testlog - hi three

修改后示例代码:

import logging


def log(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 - hi
2016-07-08 09:32:28,206 - ERROR - testlog - hi too
2016-07-08 09:32:28,206 - ERROR - testlog - hi three

深度解析:

Google之后,大概搞明白了,就是你第二次调用log的时候,根据getLogger(name)里的name获取同一个logger,而这个logger里已经有了第一次你添加的handler,第二次调用又添加了一个handler,所以,这个logger里有了两个同样的handler,以此类推,调用几次就会有几个handler。。

所以这里有以下几个解决办法:

  1. 每次创建不同name的logger,每次都是新logger,不会有添加多个handler的问题。(ps:这个办法太笨,不过我之前就是这么干的。。)
  2. 像上面一样每次记录完日志之后,调用removeHandler()把这个logger里的handler移除掉。在log方法里做判断,如果这个logger已有handler,则不再添加handler。
  3. 与方法2一样,不过把用pop把logger的handler列表中的handler移除。

下面是方法3与方法4的代码示例:

方法3:

import logging


def log(message):
 logger = logging.getLogger('testlog')

 # 这里进行判断,如果logger.handlers列表为空,则添加,否则,直接去写日志
 if not logger.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')

方法4:

import logging


def log(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')

这几种方法都亲试可行,个人觉得方法3判断更加优雅,你觉得呢?

到此这篇关于python logging 重复写日志问题j解决办法详解的文章就介绍到这了,更多相关python logging 重复写日志问题内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python 爬虫学习笔记之多线程爬虫
Sep 21 Python
python面向对象_详谈类的继承与方法的重载
Jun 07 Python
Python利用ElementTree模块处理XML的方法详解
Aug 31 Python
Python基于socket实现简单的即时通讯功能示例
Jan 16 Python
python OpenCV学习笔记直方图反向投影的实现
Feb 07 Python
Python实现的FTP通信客户端与服务器端功能示例
Mar 28 Python
Python迭代器定义与简单用法分析
Apr 30 Python
python对日志进行处理的实例代码
Oct 06 Python
python实现向微信用户发送每日一句 python实现微信聊天机器人
Mar 27 Python
详解PANDAS 数据合并与重塑(join/merge篇)
Jul 09 Python
Django使用消息提示简单的弹出个对话框实例
Nov 15 Python
python不到50行代码完成了多张excel合并的实现示例
May 28 Python
Windows下Sqlmap环境安装教程详解
Aug 04 #Python
Python中logger日志模块详解
Aug 04 #Python
Python模块zipfile原理及使用方法详解
Aug 04 #Python
Python爬虫之Spider类用法简单介绍
Aug 04 #Python
Python绘图之二维图与三维图详解
Aug 04 #Python
Python连接Impala实现步骤解析
Aug 04 #Python
python利用蒙版抠图(使用PIL.Image和cv2)输出透明背景图
Aug 04 #Python
You might like
提升PHP执行速度全攻略(下)
2006/10/09 PHP
完美解决dedecms中的[html][/html]和[code][/code]问题
2007/03/20 PHP
深入PHP数据加密详解
2013/06/18 PHP
PHP读取CSV大文件导入数据库的实例
2017/07/24 PHP
PHP实现搜索时记住状态的方法示例
2018/05/11 PHP
JavaScript中令你抓狂的魔术变量
2006/11/30 Javascript
在Z-Blog中运行代码[html][/html](纯JS版)
2007/03/25 Javascript
一个加载js文件的小脚本
2007/06/28 Javascript
DHTML Slide Show script图片轮换
2008/03/03 Javascript
js实现页面打印功能实例代码(附去页眉页脚功能代码)
2009/12/15 Javascript
js解析与序列化json数据(三)json的解析探讨
2013/02/01 Javascript
jquery自定义插件——window的实现【示例代码】
2016/05/06 Javascript
使用js获取地址栏参数的方法推荐(超级简单)
2016/06/14 Javascript
Javascript单例模式的介绍和实例
2016/10/08 Javascript
JS实现线性表的链式表示方法示例【经典数据结构】
2017/04/11 Javascript
JS二分查找算法详解
2017/11/01 Javascript
JavaScript使用享元模式实现文件上传优化操作示例
2018/08/07 Javascript
Element Input组件分析小结
2018/10/11 Javascript
javascript中floor使用方法总结
2019/02/02 Javascript
JavaScript canvas实现文字时钟
2021/01/10 Javascript
Python对象的深拷贝和浅拷贝详解
2014/08/25 Python
python使用Apriori算法进行关联性解析
2017/12/21 Python
运行django项目指定IP和端口的方法
2018/05/14 Python
Python3爬虫之urllib携带cookie爬取网页的方法
2018/12/28 Python
Python如何使用字符打印照片
2020/01/03 Python
Python根据指定文件生成XML的方法
2020/06/29 Python
filter使用python3代码进行迭代元素的实例详解
2020/12/03 Python
DOUGLAS荷兰:购买香水和化妆品
2020/10/24 全球购物
中秋节主持词
2014/04/02 职场文书
建设工地安全标语
2014/06/07 职场文书
单位活动策划方案
2014/08/17 职场文书
综合管理员岗位职责
2015/02/11 职场文书
幼儿园庆六一主持词
2015/06/30 职场文书
感谢信
2019/04/11 职场文书
mysql 带多个条件的查询方式
2021/06/05 MySQL
Nginx如何配置根据路径转发详解
2022/07/23 Servers