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 相关文章推荐
在Windows服务器下用Apache和mod_wsgi配置Python应用的教程
May 06 Python
Python实现按逗号分隔列表的方法
Oct 23 Python
详解用python写一个抽奖程序
May 10 Python
Django模型序列化返回自然主键值示例代码
Jun 12 Python
Python基于机器学习方法实现的电影推荐系统实例详解
Jun 25 Python
浅析Python 引号、注释、字符串
Jul 25 Python
Python线上环境使用日志的及配置文件
Jul 28 Python
深入了解Python在HDA中的应用
Sep 05 Python
pytorch实现Tensor变量之间的转换
Feb 17 Python
如何将PySpark导入Python的放实现(2种)
Apr 26 Python
tensorflow从ckpt和从.pb文件读取变量的值方式
May 26 Python
keras的backend 设置 tensorflow,theano操作
Jun 30 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
星际玩家的三大定律
2020/03/04 星际争霸
PHP json_decode函数详细解析
2014/02/17 PHP
PHP的MVC模式实现原理分析(一相简单的MVC框架范例)
2014/04/29 PHP
Laravel 5框架学习之向视图传送数据(进阶篇)
2015/04/08 PHP
PHP基于ORM方式操作MySQL数据库实例
2017/06/21 PHP
学习thinkphp5.0验证类使用方法
2017/11/16 PHP
jquery获取一组checkbox的值(实例代码)
2013/11/04 Javascript
Javascript setInterval的两种调用方法(实例讲解)
2013/11/29 Javascript
JavaScript中获取样式的原生方法小结
2014/10/08 Javascript
JavaScript检测实例属性, 原型属性
2015/02/04 Javascript
JavaScript实现的类字典插入或更新方法实例
2015/07/10 Javascript
javascript实现添加附件功能的方法
2015/11/18 Javascript
纯JavaScript代码实现文本比较工具
2016/02/17 Javascript
AngularJS删除路由中的#符号的方法
2016/09/20 Javascript
js匿名函数使用&传参(实例)
2017/09/08 Javascript
vue2.0s中eventBus实现兄弟组件通信的示例代码
2017/10/25 Javascript
如何基于原生javaScript生成带图片的二维码
2019/11/21 Javascript
在vue中动态修改css其中一个属性值操作
2020/12/07 Vue.js
[01:34]传奇从这开始 2016国际邀请赛中国区预选赛震撼开启
2016/06/26 DOTA
python操作MySQL数据库具体方法
2013/10/28 Python
Python实现Mysql数据库连接池实例详解
2017/04/11 Python
PyChar学习教程之自定义文件与代码模板详解
2017/07/17 Python
Python获取二维数组的行列数的2种方法
2020/02/11 Python
python GUI库图形界面开发之PyQt5信号与槽机制、自定义信号基础介绍
2020/02/25 Python
整理的15个非常有用的 HTML5 开发教程和速查手册
2011/10/18 HTML / CSS
建筑设计专业求职自我评价
2014/03/02 职场文书
室内趣味活动方案
2014/08/24 职场文书
党员民主生活会材料
2014/12/15 职场文书
后进生评语大全
2015/01/04 职场文书
前台接待员岗位职责
2015/04/15 职场文书
2015年重阳节主持词
2015/07/04 职场文书
《工作是最好的修行》读后感3篇
2019/12/13 职场文书
《家庭教育》读后感3篇
2019/12/18 职场文书
超级详细实用的pycharm常用快捷键
2021/05/12 Python
详解Mysq MVCC多版本的并发控制
2022/04/29 MySQL
Python可视化神器pyecharts之绘制地理图表练习
2022/07/07 Python