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 相关文章推荐
Python3.X 线程中信号量的使用方法示例
Jul 24 Python
使用python读取csv文件快速插入数据库的实例
Jun 21 Python
python实现flappy bird小游戏
Dec 24 Python
Python3实现的旋转矩阵图像算法示例
Apr 03 Python
python字典的常用方法总结
Jul 31 Python
python web框架中实现原生分页
Sep 08 Python
Python values()与itervalues()的用法详解
Nov 27 Python
git查看、创建、删除、本地、远程分支方法详解
Feb 18 Python
python GUI库图形界面开发之PyQt5切换按钮控件QPushButton详细使用方法与实例
Feb 28 Python
python re的findall和finditer的区别详解
Nov 15 Python
Python数据可视化之绘制柱状图和条形图
May 25 Python
如何在Python项目中引入日志
May 31 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实现表单多按钮提交action的处理方法
2015/10/24 PHP
javascript Demo模态窗口
2009/12/06 Javascript
基于jQuery的消息提示插件之旅 DivAlert(三)
2010/04/01 Javascript
JS记录用户登录次数实现代码
2014/01/15 Javascript
容易造成JavaScript内存泄露几个方面
2014/09/04 Javascript
jquery让指定的元素闪烁显示的方法
2015/03/17 Javascript
JS判断是否手机或pad访问实现方法
2016/12/09 Javascript
详解Vue.js分发之作用域槽
2017/06/13 Javascript
详解Vue + Vuex 如何使用 vm.$nextTick
2017/11/20 Javascript
vue2.5.2使用http请求获取静态json数据的实例代码
2018/02/27 Javascript
Vue-Router的使用方法
2018/09/05 Javascript
Vuejs开发环境搭建及热更新【推荐】
2018/09/07 Javascript
vue-resource:jsonp请求百度搜索的接口示例
2019/11/09 Javascript
javascript中contains是否包含功能实现代码(扩展字符、数组、dom)
2020/04/07 Javascript
一个简单的python程序实例(通讯录)
2013/11/29 Python
编写Python脚本把sqlAlchemy对象转换成dict的教程
2015/05/29 Python
Python scikit-learn 做线性回归的示例代码
2017/11/01 Python
使用实现pandas读取csv文件指定的前几行
2018/04/20 Python
python写入已存在的excel数据实例
2018/05/03 Python
pandas dataframe添加表格框线输出的方法
2019/02/08 Python
python Zmail模块简介与使用示例
2020/12/19 Python
css3 按钮 利用css3实现超酷下载按钮
2013/03/18 HTML / CSS
一款简洁的纯css3代码实现的动画导航
2014/10/31 HTML / CSS
JAVA程序设计笔试题面试题一套
2015/07/28 面试题
工商管理实习自我鉴定
2013/09/28 职场文书
马云的职业生涯规划之路
2014/01/01 职场文书
高考备战决心书
2014/03/11 职场文书
小学教师师德承诺书
2014/05/23 职场文书
大学生应聘求职信
2014/05/26 职场文书
医生党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
土建施工员岗位职责
2015/04/11 职场文书
垂直极限观后感
2015/06/08 职场文书
求职信如何撰写?
2019/05/22 职场文书
小公司融资,商业计划书的8切记
2019/07/15 职场文书
详解JavaScript中的执行上下文及调用堆栈
2021/04/29 Javascript
Pytorch 统计模型参数量的操作 param.numel()
2021/05/13 Python