解决Python logging模块无法正常输出日志的问题


Posted in Python onFebruary 21, 2020

废话少说,先上代码

File:logger.conf
 
[formatters]
keys=default
 
[formatter_default]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
class=logging.Formatter
 
[handlers]
keys=console, error_file
 
[handler_console]
class=logging.StreamHandler
formatter=default
args=tuple()
 
[handler_error_file]
class=logging.FileHandler
level=INFO
formatter=default
args=("logger.log", "a")
 
[loggers]
keys=root
 
[logger_root]
level=DEBUG
formatter=default
handlers=console,error_file
File:logger.py
 
#!/bin/env python
 
import logging
from logging.config import logging
 
class Test(object):
 """docstring for Test"""
 def __init__(self):
 logging.config.fileConfig("logger.conf")
 self.logger = logging.getLogger(__name__)
 
 def test_func(self):
 self.logger.error('test_func function')
 
class Worker(object):
 """docstring for Worker"""
 def __init__(self):
 logging.config.fileConfig("logger.conf")
 self.logger = logging.getLogger(__name__)
 
 data_logger = logging.getLogger('data')
 handler = logging.FileHandler('./data.log')
 fmt = logging.Formatter('%(asctime)s|%(message)s')
 handler.setFormatter(fmt)
 data_logger.addHandler(handler)
 data_logger.setLevel(logging.DEBUG)
 self.data_logger = data_logger
 
 def test_logger(self):
 self.data_logger.error("test_logger function")
 instance = Test()
 self.data_logger.error("test_logger output")
 instance.test_func()
 
 
def main():
 worker = Worker()
 worker.test_logger()
 
if __name__ == '__main__':
 main()

问题一:测试过程中,只能打印出test_logger function一条语句

问题二:明明只在data_logger中打印出语句,但是logger的日志中也出现了相关的日志。

问题一解决方案:

利用python -m pdb logger.py 语句对脚本进行调试发现,在执行instance = Test()语句后,通过print '\n'.join(['%s:%s' % item for item in self.data_logger.__dict__.items()])调试语句看到data_logger的disable属性值由0变成了True,此时logger的对应属性也发生了相同的变化。这种变化导致了logger对象停止记录日志。

参考python logging模块的相关手册发现

“The fileConfig() function takes a default parameter, disable_existing_loggers, which defaults to True for reasons of backward compatibility. This may or may not be what you want, since it will cause any loggers existing before the fileConfig() call to be disabled unless they (or an ancestor) are explicitly named in the configuration.”

的说明,即调用fileconfig()函数会将之前存在的所有logger禁用。

在python 2.7版本该fileConfig()函数添加了一个参数,logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True),可以显式的将disable_existing_loggers设置为FALSE来避免将原有的logger禁用。

将上述代码中的Test类中的logging.config.fileConfig函数改成logging.config.fileConfig("./logger.conf", disable_existing_loggers=0)就可以解决问题。

不过该代码中由于位于同一程序内,可以直接用logging.getLogger(LOGGOR_NAME)函数引用同一个logger,不用再调用logging.config.fileConfig函数重新加载一遍了。

问题二解决方案:

logger对象有个属性propagate,如果这个属性为True,就会将要输出的信息推送给该logger的所有上级logger,这些上级logger所对应的handlers就会把接收到的信息打印到关联的日志中。logger.conf配置文件中配置了相关的root logger的属性,这个root logger就是默认的logger日志。

修改后的如下:

File:logger.conf
 
[formatters]
keys=default, data
 
[formatter_default]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
class=logging.Formatter
 
[formatter_data]
format=%(asctime)s|%(message)s
class=logging.Formatter
 
[handlers]
keys=console, error_file, data_file
 
[handler_console]
class=logging.StreamHandler
formatter=default
args=tuple()
 
[handler_error_file]
class=logging.FileHandler
level=INFO
formatter=default
args=("logger.log", "a")
 
[handler_data_file]
class=logging.FileHandler
level=INFO
formatter=data
args=("data_new.log", "a")
 
[loggers]
keys=root, data
 
[logger_root]
level=DEBUG
handlers=console,error_file
 
[logger_data]
level=DEBUG
handlers=data_file
qualname=data
propagate=0
File:logger.py
 
#!/bin/env python
 
import logging
from logging.config import logging
 
class Test(object):
 """docstring for Test"""
 def __init__(self):
 self.logger = logging.getLogger(__name__)
 
 def test_func(self):
 self.logger.error('test_func function')
 
class Worker(object):
 """docstring for Worker"""
 def __init__(self):
 logging.config.fileConfig("logger.conf")
 self.logger = logging.getLogger(__name__)
 self.data_logger = logging.getLogger('data')
 
 def test_logger(self):
 self.data_logger.error("test_logger function")
 instance = Test()
 self.data_logger.error("test_logger output")
 instance.test_func()
 
 
def main():
 worker = Worker()
 worker.test_logger()
 
if __name__ == '__main__':
 main()

以上这篇解决Python logging模块无法正常输出日志的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python网络编程学习笔记(六):Web客户端访问
Jun 09 Python
跟老齐学Python之赋值,简单也不简单
Sep 24 Python
Python中的Numeric包和Numarray包使用教程
Apr 13 Python
Python实现在matplotlib中两个坐标轴之间画一条直线光标的方法
May 20 Python
Python使用面向对象方式创建线程实现12306售票系统
Dec 24 Python
Django中更改默认数据库为mysql的方法示例
Dec 05 Python
python 使用正则表达式按照多个空格分割字符的实例
Dec 20 Python
python矩阵/字典实现最短路径算法
Jan 17 Python
python定时检测无响应进程并重启的实例代码
Apr 22 Python
Python初学者常见错误详解
Jul 02 Python
python程序 创建多线程过程详解
Sep 23 Python
手把手教你Python yLab的绘制折线图的画法
Oct 23 Python
Pycharm和Idea支持的vim插件的方法
Feb 21 #Python
在python中logger setlevel没有生效的解决
Feb 21 #Python
详解python内置常用高阶函数(列出了5个常用的)
Feb 21 #Python
Python开发之pip安装及使用方法详解
Feb 21 #Python
python logging 日志的级别调整方式
Feb 21 #Python
logging level级别介绍
Feb 21 #Python
Python中常用的高阶函数实例详解
Feb 21 #Python
You might like
推荐Discuz!5的PHP代码高亮显示与实现可运行代码
2007/03/15 PHP
详解PHP的Yii框架的运行机制及其路由功能
2016/03/17 PHP
基于PHP制作验证码
2016/10/12 PHP
Thinkphp5.0 框架视图view的比较标签用法分析
2019/10/12 PHP
javascript之学会吝啬 精简代码
2010/04/25 Javascript
JS简单实现元素复制示例附图
2013/11/19 Javascript
php is_numberic函数造成的SQL注入漏洞
2014/03/10 Javascript
jQuery无刷新分页完整实例代码
2015/10/27 Javascript
AngularJS使用带属性值的ng-app指令实现自定义模块自动加载的方法
2017/01/04 Javascript
使用grunt合并压缩js和css文件的方法
2017/03/02 Javascript
jQuery接受后台传递的List的实例详解
2017/08/02 jQuery
JavaScript图片处理与合成总结
2018/03/04 Javascript
浅谈关于JS下大批量异步任务按顺序执行解决方案一点思考
2019/01/08 Javascript
Vue之beforeEach非登录不能访问的实现(代码亲测)
2019/07/18 Javascript
解析原来浏览器原生支持JS Base64编码解码
2019/08/12 Javascript
微信公众号平台接口开发 获取微信服务器IP地址方法解析
2019/08/14 Javascript
node.js中npm包管理工具用法分析
2020/02/14 Javascript
vue移动端的左右滑动事件详解
2020/06/17 Javascript
Python使用稀疏矩阵节省内存实例
2014/06/27 Python
Python smtplib实现发送邮件功能
2018/05/22 Python
Python 使用folium绘制leaflet地图的实现方法
2019/07/05 Python
利用Python产生加密表和解密表的实现方法
2019/10/15 Python
python解析多层json操作示例
2019/12/30 Python
动态设置django的model field的默认值操作步骤
2020/03/30 Python
Pycharm配置lua编译环境过程图解
2020/11/28 Python
css3图片边框border-image的用法
2017/06/30 HTML / CSS
船餐厅和泰晤士河餐饮游轮:Bateaux London
2018/03/19 全球购物
巴黎欧莱雅法国官网:L’Oreal Paris
2019/04/30 全球购物
德国领先的大尺码和超大尺码男装在线零售商:Bigtex
2019/06/22 全球购物
英国顶尖手表珠宝品牌独家授权经销商:HS Johnson
2020/10/28 全球购物
电子邮箱格式怎么写
2014/01/12 职场文书
房屋授权无偿使用证明
2014/11/29 职场文书
2014年防汛工作总结
2014/12/08 职场文书
伊索寓言读书笔记
2015/06/30 职场文书
心得体会格式及范文
2016/01/25 职场文书
TensorFlow的自动求导原理分析
2021/05/26 Python