3

这似乎是一个非常简单的问题,但我找不到任何适合我的好例子。

我想过滤具有特定名称的记录器。

例如

import logging

logging.root.setLevel(logging.DEBUG)
logging.root.addHandler(logging.StreamHandler())
logging.root.addFilter(logging.Filter(name="a"))

a = logging.getLogger("a")
b = logging.getLogger("b")

a.info("aaaaa")
b.info("bbbbb")

我希望根记录器会过滤来自的消息,b因为我知道logging.Filter只通过nameor childs of the name

但正如您所料,它只是传递所有消息。

我误解的重点是什么?

4

2 回答 2

6

正如logging文件所述:

由后代记录器生成的事件不会被记录器的过滤器设置过滤,除非过滤器也已应用于那些后代记录器

如果您只想关闭来自子记录器的消息,您可以设置其级别:

logging.getLogger("a").setLevel(logging.CRITICAL + 1)
于 2015-03-18T16:05:26.477 回答
2

我刚刚学习了同样的问题。如果您查看https://docs.python.org/2.7/howto/logging.html#logging-advanced-tutorial上的流程图​​(或阅读上面文档中的句子),您可以看到 LOGGERS 上的过滤器仅在初始日志事件中应用,但在记录传播到父记录器时不应用。因此,过滤器似乎应该几乎总是应用于处理程序而不是记录器。

在您的原始示例中,将您的名称过滤器添加到流处理程序将按预期工作。

我希望这样的工作:

class RestFilter(logging.Filter):
    def filter(self,record):
        return '/rest' not in record.msg

# Add the filter to the root logger
logging.getLogger().setFilter(RestFilter())

我认为向根添加过滤器会在记录传递给附加到根的所有处理程序之前过滤所有记录。但这只会过滤在根目录下 ENTER 的记录。我很好奇是否有任何评论者可以提出这种设计的理由。

于 2015-12-16T20:29:09.010 回答