如何从请求库中禁用日志消息?

默认情况下,请求 python库将日志消息写入控制台,如下所示:

Starting new HTTP connection (1): example.com
http://example.com:80 "GET / HTTP/1.1" 200 606

我通常对这些消息不感兴趣,并希望禁用它们。什么是沉默这些消息或减少请求的冗长的最好方法?

184812 次浏览

我找到了如何配置请求的日志级别,它是通过标准的日志记录模块完成的。我决定将其配置为不记录消息,除非它们至少是警告:

import logging


logging.getLogger("requests").setLevel(logging.WARNING)

如果你想对urllib3库(通常由请求使用)也应用这个设置,添加以下内容:

logging.getLogger("urllib3").setLevel(logging.WARNING)

让我复制/粘贴文档部分,它是我在一两周前写的,在遇到类似你的问题后:

import requests
import logging


# these two lines enable debugging at httplib level (requests->urllib3->httplib)
# you will see the REQUEST, including HEADERS and DATA, and RESPONSE with HEADERS but without DATA.
# the only thing missing will be the response.body which is not logged.
import httplib
httplib.HTTPConnection.debuglevel = 1


logging.basicConfig() # you need to initialize logging, otherwise you will not see anything from requests
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True


requests.get('http://httpbin.org/headers')
import logging
urllib3_logger = logging.getLogger('urllib3')
urllib3_logger.setLevel(logging.CRITICAL)

这样,来自urllib3的level=INFO的所有消息都不会出现在日志文件中。

因此,您可以继续使用level=INFO为您的日志消息…只需为您正在使用的库修改这个。

对于任何使用logging.config.dictConfig的人,你可以像这样在字典中修改请求库日志级别:

'loggers': {
'': {
'handlers': ['file'],
'level': level,
'propagate': False
},
'requests.packages.urllib3': {
'handlers': ['file'],
'level': logging.WARNING
}
}

简单:只要在import requests后面加上requests.packages.urllib3.disable_warnings()

我不确定之前的方法是否已经停止工作,但无论如何,这里有另一种消除警告的方法:

PYTHONWARNINGS="ignore:Unverified HTTPS request" ./do-insecure-request.py

基本上,就是在脚本执行的上下文中添加一个环境变量。

来自文档:https://urllib3.readthedocs.org/en/latest/security.html#disabling-warnings

如果你在这里寻找一种方法来修改任何(可能是深度嵌套的)模块的日志记录,使用logging.Logger.manager.loggerDict来获得所有记录器对象的字典。返回的名称可以用作logging.getLogger的参数:

import requests
import logging
for key in logging.Logger.manager.loggerDict:
print(key)
# requests.packages.urllib3.connectionpool
# requests.packages.urllib3.util
# requests.packages
# requests.packages.urllib3
# requests.packages.urllib3.util.retry
# PYREADLINE
# requests
# requests.packages.urllib3.poolmanager


logging.getLogger('requests').setLevel(logging.CRITICAL)
# Could also use the dictionary directly:
# logging.Logger.manager.loggerDict['requests'].setLevel(logging.CRITICAL)

对于注释中的user136036,请注意此方法只显示在运行上述代码段时存在的记录器。例如,如果一个模块在实例化一个类时创建了一个新的记录器,那么你必须放入这个代码段来创建类,以便打印它的名称。

如果您有配置文件,可以对其进行配置。

在记录器部分添加urllib3:

[loggers]
keys = root, urllib3

添加logger_urllib3 section:

[logger_urllib3]
level = WARNING
handlers =
qualname = requests.packages.urllib3.connectionpool

Kbrose关于查找哪个记录器正在生成日志消息的指导非常有用。对于我的Django项目,我不得不在120个不同的日志记录程序中进行排序,直到我发现是elasticsearch Python库给我带来了问题。根据大多数问题的指导,我通过添加这个到我的日志记录器来禁用它:

      ...
'elasticsearch': {
'handlers': ['console'],
'level': logging.WARNING,
},
...

在这里发布,以防其他人在运行Elasticsearch查询时看到无用的日志消息。

将记录器名称设置为requestsrequests.urllib3对我不起作用。我必须指定确切的记录器名称才能更改日志级别。

首先查看您已经定义了哪些记录器,以查看您想删除哪些记录器

print(logging.Logger.manager.loggerDict)

你会看到这样的东西:

{...'urllib3.poolmanager': <logging.Logger object at 0x1070a6e10>, 'django.request': <logging.Logger object at 0x106d61290>, 'django.template': <logging.Logger object at 0x10630dcd0>, 'django.server': <logging.Logger object at 0x106dd6a50>, 'urllib3.connection': <logging.Logger object at 0x10710a350>,'urllib3.connectionpool': <logging.Logger object at 0x106e09690> ...}

然后为确切的记录器配置级别:

   'loggers': {
'': {
'handlers': ['default'],
'level': 'DEBUG',
'propagate': True
},
'urllib3.connectionpool': {
'handlers': ['default'],
'level': 'WARNING',
'propagate' : False
},

答案在这里:Python:如何从第三方库抑制日志语句?

您可以为basicConfig保留默认日志级别,然后在获取模块的日志记录器时设置DEBUG级别。

logging.basicConfig(format='%(asctime)s %(module)s %(filename)s:%(lineno)s - %(message)s')
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)


logger.debug("my debug message")
import logging


# Only show warnings
logging.getLogger("urllib3").setLevel(logging.WARNING)


# Disable all child loggers of urllib3, e.g. urllib3.connectionpool
logging.getLogger("urllib3").propagate = False

在我的情况下,什么帮助了我(python 3.7)

import http.client as http_client
http_client.HTTPConnection.debuglevel = 0