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中为feedparser设置超时时间避免堵塞
Sep 28 Python
详细探究Python中的字典容器
Apr 14 Python
Python实现批量读取word中表格信息的方法
Jul 30 Python
python3学习笔记之多进程分布式小例子
Feb 13 Python
linux安装Python3.4.2的操作方法
Sep 28 Python
python抓取搜狗微信公众号文章
Apr 01 Python
Python实现基于SVM的分类器的方法
Jul 19 Python
对Django外键关系的描述
Jul 26 Python
用python解压分析jar包实例
Jan 16 Python
Django项目uwsgi+Nginx保姆级部署教程实现
Apr 19 Python
django queryset 去重 .distinct()说明
May 19 Python
Python if else条件语句形式详解
Mar 24 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
使用sockets:从新闻组中获取文章(二)
2006/10/09 PHP
用PHP将数据导入到Foxmail的实现代码
2010/09/05 PHP
php利用腾讯ip分享计划获取地理位置示例分享
2014/01/20 PHP
PHP的Laravel框架中使用消息队列queue及异步队列的方法
2016/03/21 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
2018/03/31 PHP
JQuery 风格的HTML文本转义
2009/07/01 Javascript
使用JavaScript 实现对象 匀速/变速运动的方法
2013/05/08 Javascript
JS、jquery实现几分钟前、几小时前、几天前等时间差显示效果的代码实例分享
2014/04/11 Javascript
JavaScript怎么判断图片是否加载完成以便获取其尺寸
2014/05/08 Javascript
JS使用cookie设置样式的方法
2016/06/30 Javascript
利用Node.js+Koa框架实现前后端交互的方法
2017/02/27 Javascript
jQuery实现全选、反选和不选功能
2017/08/16 jQuery
详解让sublime text3支持Vue语法高亮显示的示例
2017/09/29 Javascript
vue awesome swiper异步加载数据出现的bug问题
2018/07/03 Javascript
JavaScript封装的常用工具类库bee.js用法详解【经典类库】
2018/09/03 Javascript
layui 上传文件_批量导入数据UI的方法
2019/09/23 Javascript
node创建Vue项目步骤详解
2020/03/06 Javascript
解决vue scoped scss 无效的问题
2020/09/04 Javascript
vue.js封装switch开关组件的操作
2020/10/26 Javascript
Python入门篇之字符串
2014/10/17 Python
python实现闹钟定时播放音乐功能
2018/01/25 Python
Python实现屏幕截图的两种方式
2018/02/05 Python
Python简易版停车管理系统
2019/08/12 Python
解决python和pycharm安装gmpy2 出现ERROR的问题
2020/08/28 Python
Python实现小黑屋游戏的完整实例
2021/01/06 Python
super关键字的用法
2012/04/10 面试题
护士自我介绍信
2014/01/13 职场文书
建房协议书
2014/04/11 职场文书
小学校园文化建设汇报材料
2014/08/19 职场文书
横店影视城导游词
2015/02/06 职场文书
德能勤绩廉个人总结
2015/02/14 职场文书
计划生育个人总结
2015/03/02 职场文书
西部计划志愿者工作总结
2015/08/11 职场文书
送给自己的励志语句:要安静的优秀,悄无声息的坚强
2019/11/26 职场文书
浅谈Python基础之列表那些事儿
2021/05/11 Python
Python爬虫基础之简单说一下scrapy的框架结构
2021/06/26 Python