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判断、获取一张图片主色调的2个实例
Apr 10 Python
进一步了解Python中的XML 工具
Apr 13 Python
使用Python脚本在Linux下实现部分Bash Shell的教程
Apr 17 Python
Python中第三方库Requests库的高级用法详解
Mar 12 Python
Python实现的堆排序算法原理与用法实例分析
Nov 22 Python
[原创]pip和pygal的安装实例教程
Dec 07 Python
python分治法求二维数组局部峰值方法
Apr 03 Python
Python将DataFrame的某一列作为index的方法
Apr 08 Python
Python爬取视频(其实是一篇福利)过程解析
Aug 01 Python
使用PyCharm进行远程开发和调试的实现
Nov 04 Python
python3.x中安装web.py步骤方法
Jun 23 Python
Python虚拟环境virtualenv是如何使用的
Jun 20 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按字符无乱码截取中文的方法
2015/03/27 PHP
在WordPress中实现发送http请求的相关函数解析
2015/12/29 PHP
PHP连接数据库实现注册页面的增删改查操作
2016/03/27 PHP
PHP读取文件的常见几种方法
2016/11/03 PHP
Yii框架日志记录Logging操作示例
2018/07/12 PHP
Thinkphp5框架ajax接口实现方法分析
2019/08/28 PHP
PHP生成随机字符串实例代码(字母+数字)
2019/09/11 PHP
jQuery温习篇 强大的JQuery选择器
2010/04/24 Javascript
jQuery中ajax的使用与缓存问题的解决方法
2013/12/19 Javascript
纯js写的分页表格数据为json串
2014/02/18 Javascript
JavaScript实现身份证验证代码
2016/02/17 Javascript
jQuery实现鼠标经过购物车出现下拉框代码(推荐)
2016/07/21 Javascript
AngularJS基础 ng-submit 指令简单示例
2016/08/03 Javascript
js正则表达式注册页面表单验证
2016/10/11 Javascript
微信小程序实现缓存根据不同的id来进行设置和读取缓存
2017/06/12 Javascript
详解vue.js移动端导航navigationbar的封装
2017/07/05 Javascript
浅谈在node.js进入文件目录的问题
2018/05/13 Javascript
JS匿名函数内部this指向问题详析
2019/05/10 Javascript
后台使用freeMarker和前端使用vue的方法及遇到的问题
2019/06/13 Javascript
Windows下安装 node 的版本控制工具 nvm
2020/02/06 Javascript
JS面向对象编程实现的拖拽功能案例详解
2020/03/03 Javascript
解决新建一个vue项目过程中遇到的问题
2020/10/22 Javascript
深入浅析Python科学计算库Scipy及安装步骤
2019/10/12 Python
浅谈python已知元素,获取元素索引(numpy,pandas)
2019/11/26 Python
python 实现矩阵填充0的例子
2019/11/29 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
2020/09/28 Python
纯CSS实现颜色渐变效果(包含环形渐变、线性渐变、彩虹效果等)
2014/05/07 HTML / CSS
全球性的在线时尚男装零售商:boohooMAN
2016/12/17 全球购物
土木工程应届生自荐信
2013/09/24 职场文书
学生请假条格式
2014/04/11 职场文书
食品安全承诺书
2014/05/22 职场文书
天地会口号
2014/06/17 职场文书
国庆节主题班会
2015/08/15 职场文书
宣传委员竞选稿
2015/11/19 职场文书
高中语文教学反思范文
2016/02/16 职场文书