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读写Excel文件的实例
Nov 01 Python
浅析Python中signal包的使用
Nov 13 Python
Python3实现Web网页图片下载
Jan 28 Python
书单|人生苦短,你还不用python!
Dec 29 Python
python监控进程脚本
Apr 12 Python
Python实现判断并移除列表指定位置元素的方法
Apr 13 Python
python递归函数绘制分形树的方法
Jun 22 Python
详解Django中六个常用的自定义装饰器
Jul 04 Python
使用python3构建文件传输的方法
Feb 13 Python
Python startswith()和endswith() 方法原理解析
Apr 28 Python
Python中文纠错的简单实现
Jul 07 Python
Python初识逻辑与if语句及用法大全
Aug 07 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 星际争霸
ajax缓存问题解决途径
2006/12/06 PHP
php+mysqli批量查询多张表数据的方法
2015/01/29 PHP
PHP中list方法用法示例
2016/12/01 PHP
PHP与Web页面的交互示例详解二
2020/08/04 PHP
javascript笔试题目附答案@20081025_jb51.net
2008/10/26 Javascript
js使用递归解析xml
2014/12/12 Javascript
jQuery中:input选择器用法实例
2015/01/03 Javascript
jQuery实现复选框批量选择与反选的方法
2015/06/17 Javascript
jQuery仿IOS弹出框插件
2017/02/18 Javascript
jQuery使用EasyUi实现三级联动下拉框效果
2017/03/08 Javascript
jquery dataTable 后台加载数据并分页实例代码
2017/06/07 jQuery
Angular4项目中添加i18n国际化插件ngx-translate的步骤详解
2017/07/02 Javascript
小试小程序云开发(小结)
2019/06/06 Javascript
在antd中setFieldsValue和defaultVal的用法
2020/10/29 Javascript
[58:32]EG vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
linux系统使用python获取内存使用信息脚本分享
2014/01/15 Python
Python多线程threading和multiprocessing模块实例解析
2018/01/29 Python
使用Django简单编写一个XSS平台的方法步骤
2019/03/25 Python
Python实现把类当做字典来访问
2019/12/16 Python
python 子类调用父类的构造函数实例
2020/03/12 Python
tensorflow pb to tflite 精度下降详解
2020/05/25 Python
css3实现wifi信号逐渐增强效果实例
2017/08/09 HTML / CSS
HTML5 video 事件应用示例
2014/09/11 HTML / CSS
百丽国际旗下购物网站:优购
2017/02/28 全球购物
美国顶级防滑鞋:Shoes For Crews
2017/03/27 全球购物
美国全球旅游运营商:Pacific Holidays
2018/06/18 全球购物
TOWER London官网:鞋子、靴子、运动鞋等
2019/07/14 全球购物
人力管理专业毕业生求职信
2014/02/27 职场文书
小区的门卫岗位职责
2014/10/01 职场文书
2014年维修电工工作总结
2014/11/20 职场文书
员工表扬信怎么写
2015/05/05 职场文书
何玥事迹观后感
2015/06/16 职场文书
网吧温馨提示
2015/07/17 职场文书
2016年师德师风学习心得体会
2016/01/12 职场文书
PyTorch的Debug指南
2021/05/07 Python