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 相关文章推荐
Python3访问并下载网页内容的方法
Jul 28 Python
qpython3 读取安卓lastpass Cookies
Jun 19 Python
怎样使用Python脚本日志功能
Aug 14 Python
运行django项目指定IP和端口的方法
May 14 Python
Python编程flask使用页面模版的方法
Dec 28 Python
PyTorch中Tensor的维度变换实现
Aug 18 Python
Django自带的加密算法及加密模块详解
Dec 03 Python
使用keras实现densenet和Xception的模型融合
May 23 Python
在keras中对单一输入图像进行预测并返回预测结果操作
Jul 09 Python
python基于socket模拟实现ssh远程执行命令
Dec 05 Python
python状态机transitions库详解
Jun 02 Python
Python Pandas读取Excel日期数据的异常处理方法
Feb 28 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文件操作的详解
2013/06/05 PHP
ThinkPHP开发--使用七牛云储存
2017/09/14 PHP
热点新闻滚动特效的js代码
2013/08/17 Javascript
Javascript解析URL方法详解
2014/12/05 Javascript
Angular实现form自动布局
2016/01/28 Javascript
简单的渐变轮播插件
2017/01/12 Javascript
canvas实现简易的圆环进度条效果
2017/02/28 Javascript
基于vue2.0实现简单轮播图
2017/11/27 Javascript
Vue中使用 setTimeout() setInterval()函数的问题
2018/09/13 Javascript
layerui代码控制tab选项卡,添加,关闭的实例
2019/09/04 Javascript
django简单的前后端分离的数据传输实例 axios
2020/05/18 Javascript
[01:23]一分钟告诉你 DOTA2为什么叫信仰2
2014/06/20 DOTA
[58:37]Serenity vs Fnatic 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
用Python编写一个简单的俄罗斯方块游戏的教程
2015/04/03 Python
Python实现将sqlite数据库导出转成Excel(xls)表的方法
2017/07/17 Python
轻松实现TensorFlow微信跳一跳的AI
2018/01/05 Python
python 重定向获取真实url的方法
2018/05/11 Python
python实现指定字符串补全空格、前面填充0的方法
2018/11/16 Python
简单了解Python matplotlib线的属性
2019/06/29 Python
Django 反向生成url实例详解
2019/07/30 Python
python实现几种归一化方法(Normalization Method)
2019/07/31 Python
Numpy 中的矩阵求逆实例
2019/08/26 Python
python中如何使用insert函数
2020/01/09 Python
css3 中实现炫酷的loading效果
2019/04/26 HTML / CSS
稀有和绝版书籍:Biblio.com
2017/02/02 全球购物
澳大利亚床上用品、浴巾和家居用品购物网站:Bambury
2020/04/16 全球购物
波兰最大的电商平台:Allegro.pl
2021/02/06 全球购物
安全标准化汇报材料
2014/02/03 职场文书
模具毕业生推荐信
2014/02/15 职场文书
母亲节感恩寄语
2014/02/21 职场文书
幼儿评语大全
2014/04/30 职场文书
学校节能减排倡议书
2014/05/16 职场文书
大学生入党推荐书范文
2014/05/17 职场文书
感恩小明星事迹材料
2014/05/23 职场文书
银行授权委托书样本
2014/10/13 职场文书
公司承诺书格式范文
2015/04/28 职场文书