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使用百度API上传文件到百度网盘代码分享
Nov 08 Python
Python批量重命名同一文件夹下文件的方法
May 25 Python
python创建进程fork用法
Jun 04 Python
Python遍历目录中的所有文件的方法
Jul 08 Python
django之session与分页(实例讲解)
Nov 13 Python
Python对列表去重的多种方法(四种方法)
Dec 05 Python
python编程线性回归代码示例
Dec 07 Python
Python3之文件读写操作的实例讲解
Jan 23 Python
详解python字节码
Feb 07 Python
Python3环境安装Scrapy爬虫框架过程及常见错误
Jul 12 Python
Django静态资源部署404问题解决方案
May 11 Python
python将YUV420P文件转PNG图片格式的两种方法
Jan 22 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递归创建和删除文件夹的代码小结
2012/04/13 PHP
php输出xml格式字符串(用的这个)
2012/07/12 PHP
zf框架的校验器InArray使用示例
2014/03/13 PHP
PHP临时文件的安全性分析
2014/07/04 PHP
PHP魔术引号所带来的安全问题分析
2014/07/15 PHP
PHP会话控制实例分析
2016/12/24 PHP
php实现留言板功能(代码详解)
2017/03/28 PHP
JavaScript 直接操作本地文件的实现代码
2009/12/01 Javascript
jquery UI 1.72 之datepicker
2009/12/29 Javascript
jquery入门—访问DOM对象方法
2013/01/07 Javascript
js文件包含的几种方式介绍
2014/09/28 Javascript
JS实现文字向下滚动完整实例
2015/02/06 Javascript
Easyui form combobox省市区三级联动
2016/01/13 Javascript
阻止表单提交按钮多次提交的完美解决方法
2016/05/16 Javascript
详解Node.js开发中的express-session
2017/05/19 Javascript
JS实现图片手风琴效果
2020/04/17 Javascript
vue-cli中的babel配置文件.babelrc实例详解
2018/02/22 Javascript
vue动态循环出的多个select出现过的变为disabled(实例代码)
2019/11/10 Javascript
vue 获取到数据但却渲染不到页面上的解决方法
2020/11/19 Vue.js
[40:03]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
python使用datetime模块计算各种时间间隔的方法
2015/03/24 Python
python实现数组插入新元素的方法
2015/05/22 Python
检测python爬虫时是否代理ip伪装成功的方法
2019/07/12 Python
Python定时任务随机时间执行的实现方法
2019/08/14 Python
Python内置函数property()如何使用
2020/09/01 Python
Python Pivot table透视表使用方法解析
2020/09/11 Python
css3实现wifi信号逐渐增强效果实例
2017/08/09 HTML / CSS
用canvas显示验证码的实现
2020/04/10 HTML / CSS
工程招投标邀请书
2014/01/26 职场文书
经典广告词大全
2014/03/14 职场文书
创业融资计划书
2014/04/25 职场文书
房地产推广策划方案
2014/05/19 职场文书
2014年高校辅导员工作总结
2014/12/09 职场文书
辛德勒的名单观后感
2015/06/03 职场文书
2019客服个人年终工作总结范文
2019/07/08 职场文书
vue封装数字翻牌器
2022/04/20 Vue.js