什么是使用python日志过滤不同记录器的正确方法? [英] What is a correct way to filter different loggers using python logging?

查看:169
本文介绍了什么是使用python日志过滤不同记录器的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目的是通过 logging 提出的方式来进行分层过滤的多模块日志记录



作者Vinay Sajip,at至少据我猜测 - )



您可以跳到我想要它如何工作

不幸的是,我很快就学会了使用日志记录工具的工作要比我的大多数其他语言经验复杂得多,而且我已经做了很多常见的(设计)错误,例如试图实现一个集中的单一Logger类记录多个模块,甚至像(使用Python记录器类为不同的日志级别生成多个日志)。但是显然有更好的设计空间,花时间去寻找和学习它可能会更糟糕。所以,现在我希望我走在正确的轨道上。否则Vinaj将不得不澄清其余的; - )

我安排我的日志为:




  • 每个python模块都有它的自己的记录器

  • 每个记录器的名称都与其定义的模块名称相同,例如 logger = logging.getLogger(__ name __)
  • 像这样,每个模块中的代码可以使用自己的(本地定义的)记录器来发送将日志消息(logging.LogRecord)记录到处理程序(logging.Handler)中。
  • 使用 logging.config ,以实现日志配置的完全灵活性(注意:在下面的代码中,我只是从 basicConfig



这种方法是推荐的方法,我同意它的可能的优点。例如,我可以使用完全限定的模块名称(代码中已经存在的命名层次结构)打开/关闭外部库的DEBUG。



现在有一个更高的级别控制我想使用logging.Filter类,以便能够过滤(允许)只有一个选定的子树内的记录器层次结构。

这一切都很好,但这里描述的过滤


 过滤器实例用于执行LogRecords的任意过滤。 

记录器和处理程序可以根据需要选择使用过滤器实例来过滤
记录。基本过滤器类只允许在记录器层次结构中某个点以下
的事件。例如,用AB初始化的过滤器
将允许由记录器AB,
ABC,ABCD,ABD等记录事件,但不允许记录A.BB, BAB等。如果用空字符串初始化
,所有事件都会被传递。


仍然不适合我。



我的猜测是,我对LogRecords传播背后的细节缺乏了解是问题的根源。在跳转到代码之前,我想在这里显示一个流程图(从食谱教程,起初我不知道如何发现):


$ b

示例代码



我用两个模块例子开始,每个使用它自己的命名记录器:



bar.py:

  

$ b logger = logging.getLogger(__ name__)


def bar():
logger.info('hello from'+ __name__)

foo.py: b
$ b

 导入记录
从bar导入栏,记录器作为bar_logger


logger = logging.getLogger('foo ')


def foo():
logger.info('hello from foo')


if __name__ ==' __main__':
#微小的日志记录etup。
logging.basicConfig(
level = logging.INFO,
format ='%(asctime)s%(name)-20s%(levelname)-8s%(message)s',
datefmt ='%m-%d%H:%M'

#做一些工作。
foo()
bar()

>导入日志记录之后创建的basicConfig(根记录器)被 __ main __ 获取了一个附加到它的流处理程序,有一个控制台)启用(相应的Logger.disabled = False),并且模块记录器 bar foo 传播到根记录器(所以我们共有三个记录器) 。

 打印记录器
打印bar_logger
打印logging.root
#打印
#< logging.Logger对象在0x7f0cfd520790>
#< logging.Logger对象在0x7f0cfd55d710>
#< logging.RootLogger对象在0x7f0cfd520550>

实际的用例是当bar是一个我想静音的外部库(过滤掉) / p>

它是如何工作的,但是我不喜欢它



 #不喜欢它
bar_logger.addFilter(logging.Filter('foo'))
#做一些工作。
foo()
bar()

只能打印

  06-24 14:08 foo INFO hello from foo 



我想如何工作



我想集中过滤它,即在我的根记录器不需要导入所有外部模块的记录器都在那里。

  logging.root.addFilter(logging.Filter('foo')) 

打印

  06-24 14:17 foo INFO hello from foo 
06-24 14:17 bar信息hello from bar

一定有一些明显/愚蠢的错误,我想:我不想要任何来自 bar 记录器的消息。嘿,但是总结一下所有的人,找到它还有什么更好的办法? ; - )

我会试图找出bar_logger等待来自根记录器的决定的方式,然后发射任何东西。我只是希望这确实是应该如何工作的。

解决方案

解决方案



添加过滤器而不是记录器:

  handler.addFilter(logging.Filter('foo'))





$ b $在您张贴的流程图中,请注意有两个钻石:
$
b $ b
查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆