问题:如何禁用请求库中的日志消息?
默认情况下,Requests python库按照以下方式将日志消息写入控制台:
Starting new HTTP connection (1): example.com
http://example.com:80 "GET / HTTP/1.1" 200 606
我通常对这些消息不感兴趣,因此想禁用它们。使这些消息静音或降低请求的详细程度的最佳方法是什么?
By default, the Requests python library writes log messages to the console, along the lines of:
Starting new HTTP connection (1): example.com
http://example.com:80 "GET / HTTP/1.1" 200 606
I’m usually not interested in these messages, and would like to disable them. What would be the best way to silence those messages or decrease Requests’ verbosity?
回答 0
我发现了如何配置请求的日志记录级别,这是通过标准的日志记录模块完成的。我决定将其配置为不记录消息,除非它们至少是警告:
import logging
logging.getLogger("requests").setLevel(logging.WARNING)
如果您也希望将此设置应用于urllib3库(通常由请求使用),请添加以下内容:
logging.getLogger("urllib3").setLevel(logging.WARNING)
I found out how to configure requests‘s logging level, it’s done via the standard logging module. I decided to configure it to not log messages unless they are at least warnings:
import logging
logging.getLogger("requests").setLevel(logging.WARNING)
If you wish to apply this setting for the urllib3 library (typically used by requests) too, add the following:
logging.getLogger("urllib3").setLevel(logging.WARNING)
回答 1
如果您是来这里寻找修改任何(可能是深度嵌套的)模块的日志记录的方法,请使用它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)
请注意每个用户136036中的注释,此方法仅显示运行上述代码片段时存在的记录器。例如,如果某个模块在实例化一个类时创建了一个新的记录器,则必须在创建该类之后放置此代码段以打印其名称。
In case you came here looking for a way to modify logging of any (possibly deeply nested) module, use logging.Logger.manager.loggerDict
to get a dictionary of all of the logger objects. The returned names can then be used as the argument to 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)
Per user136036 in a comment, be aware that this method only shows you the loggers that exist at the time you run the above snippet. If, for example, a module creates a new logger when you instantiate a class, then you must put this snippet after creating the class in order to print its name.
回答 2
import logging
urllib3_logger = logging.getLogger('urllib3')
urllib3_logger.setLevel(logging.CRITICAL)
这样,来自urllib3的所有level = INFO消息都不会出现在日志文件中。
因此,您可以继续将level = INFO用作日志消息…只需为您正在使用的库修改它即可。
import logging
urllib3_logger = logging.getLogger('urllib3')
urllib3_logger.setLevel(logging.CRITICAL)
In this way all the messages of level=INFO from urllib3 won’t be present in the logfile.
So you can continue to use the level=INFO for your log messages…just modify this for the library you are using.
回答 3
在遇到类似于您的问题之后,让我复制/粘贴一周或两周前写的文档部分:
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')
Let me copy/paste the documentation section which it I wrote about week or two ago, after having a problem similar to yours:
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')
回答 4
对于使用的任何人,logging.config.dictConfig
您都可以像这样更改字典中的请求库日志级别:
'loggers': {
'': {
'handlers': ['file'],
'level': level,
'propagate': False
},
'requests.packages.urllib3': {
'handlers': ['file'],
'level': logging.WARNING
}
}
For anybody using logging.config.dictConfig
you can alter the requests library log level in the dictionary like this:
'loggers': {
'': {
'handlers': ['file'],
'level': level,
'propagate': False
},
'requests.packages.urllib3': {
'handlers': ['file'],
'level': logging.WARNING
}
}
回答 5
将记录器名称设置为requests
或requests.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
},
Setting the logger name as requests
or requests.urllib3
did not work for me. I had to specify the exact logger name to change the logging level.
First See which loggers you have defined, to see which ones you want to remove
print(logging.Logger.manager.loggerDict)
And you will see something like this:
{...'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> ...}
Then configure the level for the exact logger:
'loggers': {
'': {
'handlers': ['default'],
'level': 'DEBUG',
'propagate': True
},
'urllib3.connectionpool': {
'handlers': ['default'],
'level': 'WARNING',
'propagate' : False
},
回答 6
如果您有配置文件,则可以对其进行配置。
在loggers部分中添加urllib3:
[loggers]
keys = root, urllib3
添加logger_urllib3部分:
[logger_urllib3]
level = WARNING
handlers =
qualname = requests.packages.urllib3.connectionpool
If You have configuration file, You can configure it.
Add urllib3 in loggers section:
[loggers]
keys = root, urllib3
Add logger_urllib3 section:
[logger_urllib3]
level = WARNING
handlers =
qualname = requests.packages.urllib3.connectionpool
回答 7
答案在这里: 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")
This answer is here: Python: how to suppress logging statements from third party libraries?
You can leave the default logging level for basicConfig, and then you set the DEBUG level when you get the logger for your module.
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")
回答 8
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
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
回答 9
Kbrose关于查找哪个记录器正在生成日志消息的指南非常有用。对于我的Django项目,我不得不对120种不同的记录器进行分类,直到发现是elasticsearch
Python库对我造成了问题。根据大多数问题的指导,我通过将其添加到记录器中来禁用了它:
...
'elasticsearch': {
'handlers': ['console'],
'level': logging.WARNING,
},
...
如果有人在运行Elasticsearch查询时看到其他无用的日志消息,请在此处发布。
Kbrose’s guidance on finding which logger was generating log messages was immensely useful. For my Django project, I had to sort through 120 different loggers until I found that it was the elasticsearch
Python library that was causing issues for me. As per the guidance in most of the questions, I disabled it by adding this to my loggers:
...
'elasticsearch': {
'handlers': ['console'],
'level': logging.WARNING,
},
...
Posting here in case someone else is seeing the unhelpful log messages come through whenever they run an Elasticsearch query.
回答 10
简单:只需在requests.packages.urllib3.disable_warnings()
之后添加import requests
simple: just add requests.packages.urllib3.disable_warnings()
after import requests
回答 11
I’m not sure if the previous approaches have stopped working, but in any case, here’s another way of removing the warnings:
PYTHONWARNINGS="ignore:Unverified HTTPS request" ./do-insecure-request.py
Basically, adding an environment variable in the context of the script execution.
From the documentation: https://urllib3.readthedocs.org/en/latest/security.html#disabling-warnings