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。。
所以这里有以下几个解决办法:
- 每次创建不同name的logger,每次都是新logger,不会有添加多个handler的问题。(ps:这个办法太笨,不过我之前就是这么干的。。)
- 像上面一样每次记录完日志之后,调用removeHandler()把这个logger里的handler移除掉。
- 在log方法里做判断,如果这个logger已有handler,则不再添加handler。
- 与方法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')
python logging 重复写日志问题的更多相关文章
- 解决python logging重复写日志问题
import logging from homework.exam_homework_0413.common import contants from homework.exam_homework_0 ...
- Python Logging模块 输出日志颜色、过期清理和日志滚动备份
# coding:utf-8 import logging from logging.handlers import RotatingFileHandler # 按文件大小滚动备份 import co ...
- [已解决] Python logging 重复打印日志信息
问题描述 问题代码如下: def get_logger(logger_name): """得到日志对象""" logger = loggin ...
- 0x03 Python logging模块之Formatter格式
目录 logging模块之Formatter格式 Formater对象 日志输出格式化字符串 LogRecoder对象 时间格式化字符串 logging模块之Formatter格式 在记录日志是,日志 ...
- python找寻合适的日志库logging Handler——Handler自定义实现
最近在用python tornado开发一个app的服务端.投产的系统肯定需要包含日志功能,这里就自然想到了用python自带的logging库. logging中日志内容的输出都交由Handle ...
- python中利用logging包进行日志记录时的logging.level设置选择
之前在用python自带的logging包进行日志输出的时候发现有些logging语句没有输出,感到比较奇怪就去查了一下logging文档.然后发现其在设置和引用时的logging level会影响最 ...
- python logging 日志轮转文件不删除问题
前言 最近在维护项目的python项目代码,项目使用了 python 的日志模块 logging, 设定了保存的日志数目, 不过没有生效,还要通过contab定时清理数据. 分析 项目使用了 logg ...
- Python同时向控制台和文件输出日志logging的方法 Python logging模块详解
Python同时向控制台和文件输出日志logging的方法http://www.jb51.net/article/66756.htm 1 #-*- coding:utf-8 -*- 2 import ...
- Python logging日志系统
写我小小的日志系统 配置logging有以下几种方式: 1)使用Python代码显式的创建loggers, handlers和formatters并分别调用它们的配置函数: 2)创建一个日志配置文件, ...
随机推荐
- python 执行字符串中的python代码
mycode = 'print("hello world")' code = """ def mutiply(x,y): return x*y pri ...
- [osgearth]oe学习的一些经验(别人的)
参考:http://bbs.osgchina.org/forum.php?mod=viewthread&tid=5484&extra=page%3D1&_dsign=70b15 ...
- Rails 5 Test Prescriptions 第8章 Integration Testing with Capybara and Cucumber
Capybara: A complete reference is available atrubydoc.info. 集成测试就是把局部的程序组合起来测试. 端到端测试是一个特殊的集成测试,覆盖了 ...
- @RequestParam注解的作用及用法
最简单的两种写法,在写接口时:加或不加@RequestParam注解的区别 第一种写法参数为非必传,第二种写法参数为必传.参数名为userId 第二种写法可以通过@RequestParam(requi ...
- UVA-10305 Ordering Tasks (拓扑排序)
题目大意:给出n个点,m条关系,按关系的从小到大排序. 题目分析:拓扑排序的模板题,套模板. kahn算法: 伪代码: Kahn算法: 摘一段维基百科上关于Kahn算法的伪码描述: L← Empty ...
- App6种常见的数据加载设计
App6种常见的数据加载设计 设计师在进行APP设计的设计时,往往会更加专注于界面长什么样,界面和界面之间怎么跳转,给予用户什么样的操作反馈,却偏偏特别容易忽略掉一个比较重要的环节,就是APP数据加载 ...
- python socket 编程(TCP与UDP)
实验环境:python2 一.TCP编程 1.建立TCP服务器 ①创建TCPServer.py文件 ②编写服务器代码 1)创建socket对象,调用socket构造函数 2)绑定ip端口(IP号和端口 ...
- Chrome浏览器插件开发-关于案例
前言 关于案例 下一章 版本更新提示案例 一.前言 上章我们提到过开发一个插件所需要的步骤: Chrome浏览器插件开发-淘宝自动登录 并且还介绍了如何在页面上面注入脚本代码,并且成功的完成用户名和密 ...
- New Concept English Two 21 55
$课文53 触电的蛇 544. At last firemen have put out a big forest fire in California. 消防队员们终于扑灭了加利福尼亚的一场森林大 ...
- spring boot 教程(二)模板依赖
在Spring boot中有一个很重要的概念,叫做约定优于配置--软件开发的简约原则.所以Spring boot会按照约定好的文件位置去找我们的包和类. 默认配置 Spring Boot默认提供静态资 ...