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实现以时间换空间的缓存替换算法
Feb 19 Python
django使用图片延时加载引起后台404错误
Apr 18 Python
Python科学画图代码分享
Nov 29 Python
分数霸榜! python助你微信跳一跳拿高分
Jan 08 Python
使用matplotlib画散点图的方法
May 25 Python
Django跨域请求CSRF的方法示例
Nov 11 Python
如何用python写一个简单的词法分析器
Dec 18 Python
对DataFrame数据中的重复行,利用groupby累加合并的方法详解
Jan 30 Python
Django 接收Post请求数据,并保存到数据库的实现方法
Jul 12 Python
python多进程下实现日志记录按时间分割
Jul 22 Python
Python实用库 PrettyTable 学习笔记
Aug 06 Python
python实现根据给定坐标点生成多边形mask的例子
Feb 18 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将数据导入到Foxmail的实现代码
2010/09/05 PHP
php中使用explode查找某个字符是否存在的方法
2011/07/12 PHP
PHP删除数组中特定元素的两种方法
2013/07/02 PHP
PHP6 中可能会出现的新特性预览
2014/04/04 PHP
短信提示使用 特效
2007/01/19 Javascript
Prototype1.6 JS 官方下载地址
2007/11/30 Javascript
JS常用字符串处理方法应用总结
2014/05/22 Javascript
Angular2 (RC4) 路由与导航详解
2016/09/21 Javascript
AngularJS模仿Form表单提交的实现代码
2016/12/08 Javascript
bootstrap datetimepicker 日期插件在火狐下出现一条报错信息的原因分析及解决办法
2017/03/08 Javascript
vue中for循环更改数据的实例代码(数据变化但页面数据未变)
2017/09/15 Javascript
jQuery实现的点击标题文字切换字体效果示例【测试可用】
2018/04/26 jQuery
Electron中实现大文件上传和断点续传功能
2018/10/28 Javascript
Vue起步(无cli)的啊教程详解
2019/04/11 Javascript
深入理解Vue keep-alive及实践总结
2019/08/21 Javascript
[01:18:43]2014 DOTA2华西杯精英邀请赛5 24 iG VS DK
2014/05/25 DOTA
[01:00:59]VP VS VG Supermajor小组赛胜者组第二轮 BO3第二场 6.2
2018/06/03 DOTA
[01:23:45]DOTA2-DPC中国联赛 正赛 CDEC vs Dragon BO3 第一场 1月22日
2021/03/11 DOTA
python自动化测试实例解析
2014/09/28 Python
Python使用PyCrypto实现AES加密功能示例
2017/05/22 Python
Flask实现跨域请求的处理方法
2018/09/27 Python
Python列表list排列组合操作示例
2018/12/18 Python
详解Python 解压缩文件
2019/04/09 Python
TensorFlow通过文件名/文件夹名获取标签,并加入队列的实现
2020/02/17 Python
Python Pandas数据分析工具用法实例
2020/11/05 Python
常用的四种CSS透明属性介绍
2014/04/12 HTML / CSS
科尔士百货公司官网:Kohl’s
2016/07/11 全球购物
洲际酒店集团英国官网:IHG英国
2019/07/10 全球购物
什么是跨站脚本攻击
2014/12/11 面试题
什么是组件架构
2016/05/15 面试题
小学教师的自我评价范例
2013/10/31 职场文书
小学班干部竞选演讲稿
2014/04/24 职场文书
2015年置业顾问工作总结
2015/04/07 职场文书
鸡毛信观后感
2015/06/11 职场文书
职工培训工作总结
2015/08/10 职场文书
MySQL中distinct和count(*)的使用方法比较
2021/05/26 MySQL