解决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 相关文章推荐
python3.3教程之模拟百度登陆代码分享
Jan 16 Python
python使用标准库根据进程名如何获取进程的pid详解
Oct 31 Python
django模板语法学习之include示例详解
Dec 17 Python
Python使用re模块正则提取字符串中括号内的内容示例
Jun 01 Python
Python基于Logistic回归建模计算某银行在降低贷款拖欠率的数据示例
Jan 23 Python
python编写简单端口扫描器
Sep 04 Python
Python实现代码块儿折叠
Apr 15 Python
Keras:Unet网络实现多类语义分割方式
Jun 11 Python
Python+OpenCV图像处理——图像二值化的实现
Oct 24 Python
python 发送get请求接口详解
Nov 17 Python
基于 Python 实践感知器分类算法
Jan 07 Python
Python上下文管理器Content Manager
Jun 26 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
新版PHP将向Java靠拢
2006/10/09 PHP
第七节--类的静态成员
2006/11/16 PHP
Apache2中实现多网站域名绑定的实现方法
2011/06/01 PHP
合格的PHP程序员必备技能
2015/11/13 PHP
js资料toString 方法
2007/03/13 Javascript
文本链接逐个出现的js脚本
2007/12/12 Javascript
juery框架写的弹窗效果适合新手
2013/11/27 Javascript
javascript 处理null及null值示例
2014/06/09 Javascript
JS实现淡蓝色简洁竖向Tab点击切换效果
2015/10/06 Javascript
js判断文本框输入的内容是否为数字
2015/12/23 Javascript
jQuery实现别踩白块儿网页版小游戏
2017/01/18 Javascript
ES6新增数据结构WeakSet的用法详解
2017/08/07 Javascript
微信小程序用户自定义模版用法实例分析
2017/11/28 Javascript
如何使用vuex实现兄弟组件通信
2018/11/02 Javascript
详解用vue2.x版本+adminLTE开源框架搭建后台应用模版
2019/03/15 Javascript
细说webpack6 Babel的使用详解
2019/09/26 Javascript
jQuery实现点击滚动到指定元素上的方法分析
2020/03/19 jQuery
纯JS实现五子棋游戏
2020/05/28 Javascript
小程序实现上下切换位置
2020/11/16 Javascript
[01:08:17]2018DOTA2亚洲邀请赛3月29日 小组赛B组 EG VS VGJ.T
2018/03/30 DOTA
Django小白教程之Django用户注册与登录
2016/04/22 Python
配置 Pycharm 默认 Test runner 的图文教程
2018/11/30 Python
python3 实现的对象与json相互转换操作示例
2019/08/17 Python
python实现人脸签到系统
2020/04/13 Python
python 通过exifread读取照片信息
2020/12/24 Python
纯CSS3发光分享按钮的实现教程
2014/09/06 HTML / CSS
怎样在 Applet 中建立自己的菜单(MenuBar/Menu)?
2012/06/20 面试题
2014升学宴答谢词
2014/01/26 职场文书
《孔子游春》教学反思
2014/02/25 职场文书
《记金华的双龙洞》教学反思
2014/04/19 职场文书
2014年度安全生产目标管理责任书
2014/07/25 职场文书
纪念九一八事变演讲稿:青少年应树立远大理想
2014/09/14 职场文书
2015年化工厂工作总结
2015/05/04 职场文书
加班费申请报告
2015/05/15 职场文书
2016年9月份红领巾广播稿
2015/12/21 职场文书
百年校庆宣传标语口号
2015/12/26 职场文书