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 03 Python
python如何修改装饰器中参数
Mar 20 Python
Python使用pylab库实现绘制直方图功能示例
Jun 01 Python
Python操作rabbitMQ的示例代码
Mar 19 Python
在PyCharm中控制台输出日志分层级分颜色显示的方法
Jul 11 Python
python 中值滤波,椒盐去噪,图片增强实例
Dec 18 Python
python实现简单坦克大战
Mar 27 Python
django 扩展user用户字段inlines方式
Mar 30 Python
python爬虫基础知识点整理
Jun 02 Python
python与c语言的语法有哪些不一样的
Sep 13 Python
详解Python中的编码问题(encoding与decode、str与bytes)
Sep 30 Python
matplotlib grid()设置网格线外观的实现
Feb 22 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 验证码的实现代码
2011/07/17 PHP
php随机输出名人名言的代码
2012/10/07 PHP
php类常量用法实例分析
2015/07/09 PHP
完美解决phpdoc导出文档中@package的warning及Error的错误
2016/05/17 PHP
PHP新特性之字节码缓存和内置服务器
2017/08/11 PHP
来自qq的javascript面试题
2010/07/24 Javascript
Pro JavaScript Techniques学习笔记
2010/12/28 Javascript
JQuery each()嵌套使用小结
2014/04/18 Javascript
jQuery中DOM树操作之使用反向插入方法实例分析
2015/01/23 Javascript
JavaScript中数组的22种方法必学(推荐)
2016/07/20 Javascript
基于jQuery实现仿微博发布框字数提示
2016/07/27 Javascript
js 获取站点应用名的简单实例
2016/08/18 Javascript
详解Vue 方法与事件处理器
2017/06/20 Javascript
vue微信分享的实现(在当前页面分享其他页面)
2019/04/16 Javascript
关于JS解构的5种有趣用法
2019/09/05 Javascript
[02:36]DOTA2亚洲邀请赛小组赛精彩集锦:EE凭借法力虚空拿下4杀
2017/03/30 DOTA
[05:37]DOTA2-DPC中国联赛 正赛 Elephant vs iG 选手采访
2021/03/11 DOTA
Python实现批量读取word中表格信息的方法
2015/07/30 Python
Python内置函数reversed()用法分析
2018/03/20 Python
Python 实现字符串中指定位置插入一个字符
2018/05/02 Python
Python高级特性切片(Slice)操作详解
2018/09/27 Python
python实现弹跳小球
2019/05/13 Python
Django模板Templates使用方法详解
2019/07/19 Python
python读取当前目录下的CSV文件数据
2020/03/11 Python
Jupyter打开图形界面并画出正弦函数图像实例
2020/04/24 Python
Python 发送邮件方法总结
2020/08/10 Python
纯CSS实现菜单、导航栏的3D翻转动画效果
2014/04/23 HTML / CSS
美国旅游网站:Tours4Fun
2017/02/17 全球购物
Ray-Ban雷朋瑞典官方网站:全球领先的太阳眼镜品牌
2019/08/22 全球购物
State Cashmere官网:半零售价可持续蒙古羊绒
2020/02/26 全球购物
网络方面基础面试题
2012/11/16 面试题
造价工程师个人求职信
2013/09/21 职场文书
3D空间设计学生找工作的自我评价
2013/10/28 职场文书
技术总监的工作职责
2013/11/13 职场文书
如何写好自荐信
2014/04/07 职场文书
小城镇建设汇报材料
2014/08/16 职场文书