Python:如何抑制第三方库的日志记录语句?

19

我的日志设置看起来像这样

import requests
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('BBProposalGenerator')

当我运行这段代码时,我会得到以下日志记录。
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): localhost
INFO:BBProposalGenerator:created proposal: 763099d5-3c8a-47bc-8be8-b71a593c36ac
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): localhost
INFO:BBProposalGenerator:added offer with cubeValueId: f23f801f-7066-49a2-9f1b-1f8c64576a03
INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): localhost
INFO:BBProposalGenerator:evaluated proposal: 763099d5-3c8a-47bc-8be8-b71a593c36ac

如何屏蔽requests包中的日志记录语句?以便我只能看到来自我的代码的日志。
INFO:BBProposalGenerator:created proposal: 763099d5-3c8a-47bc-8be8-b71a593c36ac
INFO:BBProposalGenerator:added offer with cubeValueId: f23f801f-7066-49a2-9f1b-1f8c64576a03
INFO:BBProposalGenerator:evaluated proposal: 763099d5-3c8a-47bc-8be8-b71a593c36ac

2
logging.getLogger('requests').setLevel(logging.ERROR)? - jfs
2
我从 https://dev59.com/1mgu5IYBdhLWcg3w2ahm 得到了答案。 - daydreamer
这绝对不是与列出的问题相同。那个问题只涉及到“requests”模块。而我来到这里的标题是指所有第三方库。@VinaySajip在下面的答案解决了我的问题。 - leanne
2个回答

20

你使用 basicConfig() 并将日志级别设置为 logging.INFO,这会将根记录器和所有未显式设置级别的后代记录器的有效级别设置为INFO。这包括 requests 记录器,并解释了为什么会出现这些结果。

相反,您可以执行以下操作:

logging.basicConfig()

这将使级别保持默认值为WARNING,但添加一个处理程序,将日志消息输出到控制台。然后,将您的记录器级别设置为INFO

这将保留级别的默认值为WARNING,同时添加一个处理程序将日志消息输出到控制台。接下来,将您的记录器级别设置为INFO

logger = logging.getLogger('BBProposalGenerator')
logger.setLevel(logging.INFO)

现在,记录到BBProposalGenerator或其任何后代的INFO及更高严重性事件将被打印输出,但根记录器(以及它的其他后代,如requests.XXX)仍将保持在WARNING级别并仅显示WARNING或更高级别的消息。

当然,在basicConfig()调用中您可以指定更高的级别 - 如果您指定了ERROR,那么您将只会从所有其他记录器看到ERROR或更高级别的信息,但从BBProposalGenerator及其后代中看到INFO或更高级别的信息。


如果我想在模块之间共享记录器怎么办? - Tengerye
1
@Tengerye 记录器是单例的,因此您无需在模块之间传递它们。只需调用 logging.getLogger(<NAME>),对于给定的名称,您将始终获得相同的记录器对象。 - Vinay Sajip
可能是我搜索到的唯一一个解释了底层原理而不仅仅回答“如何”实现所要求内容的答案。 - shriek

6

您想要做的是对所有记录器应用过滤器,以便控制发出的内容。我所找到的唯一一种将过滤器应用到所有记录器的方法是通过使用 logging.Logger 的派生类初始化并在那里应用过滤器。如下所示:

class MyFilter(logging.Filter):
    def filter(self, record):
        if record.name != 'BBProposalGenerator':
            return False
        return True

class MyLogger(logging.Logger):
    def __init__(self, name):
        logging.Logger.__init__(self, name)
        self.addFilter(MyFilter())

然后你所要做的就是,在任何日志记录器实例化之前,将默认的日志记录器类设置为你的派生类,如下所示:

logging.setLoggerClass(MyLogger)
logging.basicConfig(level=logging.INFO)

希望这能帮到您!

这不是必要的 - 请看我的回答。 - Vinay Sajip

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接