3

Pythonrequestsライブラリには、ログの動作に関して、かなり奇妙な癖があるようです。最新の 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 を使用しています。

4

2 に答える 2

1

t-8chanswerに示されているように、ロガーはライブラリによって内部的に使用されてrequestsおり、このライブラリはパラメーターについて何も知りません。考えられる解決策は、ライブラリのロガー (この場合はそのモジュールの 1 つ) にカスタム フィルターを埋め込むことです。

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あなたが提供したコードの最も単純な解決策だけを追加しました-例外はもう発生しません-しかし、幅広い可能性は明らかです;)

于 2014-11-10T13:59:58.697 に答える