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语言使用技巧分享
May 31 Python
Python 搭建Web站点之Web服务器与Web框架
Nov 06 Python
Python编程判断这天是这一年第几天的方法示例
Apr 18 Python
Python中index()和seek()的用法(详解)
Apr 27 Python
Python cookbook(数据结构与算法)实现查找两个字典相同点的方法
Feb 18 Python
Python线程下使用锁的技巧分享
Sep 13 Python
python 消除 futureWarning问题的解决
Dec 25 Python
python 非线性规划方式(scipy.optimize.minimize)
Feb 11 Python
python GUI库图形界面开发之PyQt5菜单栏控件QMenuBar的详细使用方法与实例
Feb 28 Python
浅谈Python中的模块
Jun 10 Python
pandas 按日期范围筛选数据的实现
Feb 20 Python
python3 实现mysql数据库连接池的示例代码
Apr 17 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
10款实用的PHP开源工具
2015/10/23 PHP
yii2 modal弹窗之ActiveForm ajax表单异步验证
2016/06/13 PHP
PHP实现数组array转换成xml的方法
2016/07/19 PHP
javascript 限制输入和粘贴(IE,firefox测试通过)
2008/11/14 Javascript
基于jQuery的Tab选项框效果代码(插件)
2011/03/01 Javascript
设置iframe的document.designMode后仅Firefox中其body.innerHTML为br
2012/02/27 Javascript
jquery $.each() 使用小探
2013/08/23 Javascript
页面实时更新时间的JS实例代码
2013/12/18 Javascript
jquery访问ashx文件示例代码
2014/08/11 Javascript
JavaScript实现在数组中查找不同顺序排列的字符串
2014/09/26 Javascript
如何编写高质量JS代码
2014/12/28 Javascript
JQuery中节点遍历方法实例
2015/05/18 Javascript
使用AngularJS和PHP的Laravel实现单页评论的方法
2015/06/19 Javascript
jQuery插件实现带圆点的焦点图片轮播切换
2016/01/18 Javascript
JavaScript实现简单Tip提示框效果
2016/04/20 Javascript
利用JS实现数字增长
2016/07/28 Javascript
探讨跨域请求资源的几种方式(总结)
2016/12/02 Javascript
完美实现js焦点轮播效果(一)
2017/03/07 Javascript
原生js实现放大镜特效
2017/03/08 Javascript
redux中间件之redux-thunk的具体使用
2018/04/17 Javascript
微信小程序自定义底部弹出框动画
2020/11/18 Javascript
动态实现element ui的el-table某列数据不同样式的示例
2021/01/22 Javascript
[04:10]DOTA2英雄梦之声_第11期_圣堂刺客
2014/06/21 DOTA
[44:40]2018DOTA2亚洲邀请赛3月30日 小组赛A组Liquid VS OG
2018/03/31 DOTA
Python实现图像几何变换
2015/07/06 Python
开源软件包和环境管理系统Anaconda的安装使用
2017/09/04 Python
python3如何将docx转换成pdf文件
2018/03/23 Python
使用PyTorch实现MNIST手写体识别代码
2020/01/18 Python
Django Model层F,Q对象和聚合函数原理解析
2020/11/12 Python
CSS3模拟动画下拉菜单效果
2017/04/12 HTML / CSS
会计电算化专业应届大学生求职信
2013/10/22 职场文书
社区志愿者培训方案
2014/06/10 职场文书
全运会口号
2014/06/20 职场文书
小学生放飞梦想演讲稿
2014/08/26 职场文书
Python之基础函数案例详解
2021/08/30 Python
Android 界面一键变灰 深色主题工具类
2022/04/28 Java/Android