[英]Python Requests library throws exceptions in logging
當涉及到它的日志記錄行為時,Python requests
庫似乎有一些相當奇怪的怪癖。 使用最新的Python 2.7.8,我有以下代碼:
import requests
import logging
logging.basicConfig(
filename='mylog.txt',
format='%(asctime)-19.19s|%(task)-36s|%(levelname)s:%(name)s: %(message)s',
level=eval('logging.%s' % 'DEBUG'))
logger = logging.getLogger(__name__)
logger.info('myprogram starting up...', extra={'task': ''}) # so far so good
...
(ommited code)
...
payload = {'id': 'abc', 'status': 'ok'}
# At this point the program continues but throws an exception.
requests.get('http://localhost:9100/notify', params=payload)
print 'Task is complete! NotifyURL was hit! - Exiting'
我的程序似乎正常退出,但是在它創建的日志文件中(mylog.txt)我總是發現以下異常:
KeyError: 'task'
Logged from file connectionpool.py, line 362
如果我刪除它: requests.get('http://localhost:9100/notify', params=payload)
則異常消失。
我到底做錯了什么,我該如何解決這個問題? 我正在使用請求v2.4.3。
問題是您的自定義日志記錄格式,您期望%(task)
。 請求(或者更確切地說是捆綁的urllib3)在記錄時不包括task
參數,因為它無法知道您期望這樣做。
如t-8ch的回答所示 ,記錄器正在由requests
庫內部使用,並且該庫對您的參數一無所知。 一種可能的解決方案是在庫的記錄器中植入自定義過濾器(在本例中為其中一個模塊):
class TaskAddingFilter(logging.Filter):
def __init__(self):
logging.Filter.__init__(self)
def filter(self, record):
record.args = record.args + ('task', '')
# ...
requestsLogger = logging.getLogger('requests.packages.urllib3.connectionpool')
requestsLogger.addFilter(TaskAddingFilter())
您可能需要向requests
所有記錄器添加此類過濾,這些過濾器包括:
requests.packages.urllib3.util
requests.packages.urllib3.connectionpool
requests.packages
requests.packages.urllib3
requests.packages.urllib3.util.retry
requests
requests.packages.urllib3.poolmanager
在我的版本中,您可以使用logging.Logger.manager.loggerDict
屬性找到它們。 所以,你可以這樣做:
for name,logger in logging.Logger.manager.loggerDict.iteritems():
logger = logging.getLogger(name) # because of lazy initialization
if name.startswith('requests.'):
logger.addFilter(TaskAddingFilter())
TaskAddingFilter
可以更聰明一些,例如根據您在代碼中的位置添加特定task
條目。 我只為你提供的代碼添加了最簡單的解決方案 - 不再發生異常 - 但是各種各樣的可能性似乎很明顯;)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.