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使用正则表达式分析网页中的图片并进行替换的方法
Mar 26 Python
详解Python中的装饰器、闭包和functools的教程
Apr 02 Python
让Python更加充分的使用Sqlite3
Dec 11 Python
pandas数据框,统计某列数据对应的个数方法
Apr 11 Python
python的pandas工具包,保存.csv文件时不要表头的实例
Jun 14 Python
Python实现的简单排列组合算法示例
Jul 04 Python
python递归全排列实现方法
Aug 18 Python
Python 带有参数的装饰器实例代码详解
Dec 06 Python
python3人脸识别的两种方法
Apr 25 Python
使用 Python 清理收藏夹里已失效的网站
Dec 03 Python
python中sys模块是做什么用的
Aug 16 Python
python 简单的调用有道翻译
Nov 25 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
BBS(php & mysql)完整版(五)
2006/10/09 PHP
yii2 RBAC使用DbManager实现后台权限判断的方法
2016/07/23 PHP
PHP利用缓存处理用户注册时的邮箱验证,成功后用户数据存入数据库操作示例
2019/12/31 PHP
jQuery帮助之筛选查找 children([expr])
2011/01/31 Javascript
12种不宜使用的Javascript语法整理
2013/11/04 Javascript
jQuery之过滤元素操作小结
2013/11/30 Javascript
jquery 隐藏与显示tr标签示例代码
2014/06/06 Javascript
js获取元素的偏移量offset简单方法(必看)
2017/07/05 Javascript
jQuery初级教程之网站品牌列表效果
2017/08/02 jQuery
react native实现往服务器上传网络图片的实例
2017/08/07 Javascript
深入理解vue-router之keep-alive
2017/08/31 Javascript
web前端开发中常见的多列布局解决方案整理(一定要看)
2017/10/15 Javascript
javascript验证form表单数据的案例详解
2019/03/25 Javascript
关于JS解构的5种有趣用法
2019/09/05 Javascript
改变layer confirm弹窗按钮的颜色方法
2019/09/12 Javascript
JavaScript编写开发动态时钟
2020/07/29 Javascript
解决vue-cli输入命令vue ui没效果的问题
2020/11/17 Javascript
[00:50]深扒TI7聊天轮盘语音出处6
2017/05/11 DOTA
Python读取本地文件并解析网页元素的方法
2018/05/21 Python
使用 Python 实现简单的 switch/case 语句的方法
2018/09/17 Python
python绘制多个曲线的折线图
2020/03/23 Python
Django+JS 实现点击头像即可更改头像的方法示例
2018/12/26 Python
pyinstaller参数介绍以及总结详解
2019/07/12 Python
Python telnet登陆功能实现代码
2020/04/16 Python
Keras 实现加载预训练模型并冻结网络的层
2020/06/15 Python
美国男女折扣服饰百货连锁店:Stein Mart
2017/05/02 全球购物
全球最大的瓷器、水晶和银器零售商:Replacements
2020/06/15 全球购物
若通过ObjectOutputStream向一个文件中多次以追加方式写入object,为什么用ObjectInputStream读取这些object时会产生StreamCorruptedException?
2016/10/17 面试题
霸王洗发水广告词
2014/03/14 职场文书
农林经济管理专业自荐信
2014/09/01 职场文书
学前班语言教学计划
2015/01/20 职场文书
清明节文明祭祀倡议书
2015/04/28 职场文书
教师病假条范文
2015/08/17 职场文书
互联网创业商业模式以及赚钱法则有哪些?
2019/10/12 职场文书
教你怎么用Python selenium操作浏览器对象的基础API
2021/06/23 Python
Elasticsearch 配置详解
2022/04/19 Java/Android