[英]How to set up logging for aiohttp.client when making request with aiohttp.ClientSession()?
我有一些代碼向某些 API 發出請求序列。 我想為所有人設置通用日志記錄,我該如何設置?
假設我的代碼看起來像這樣
import aiohttp
import asyncio
async def fetch(client):
async with client.get('http://httpbin.org/get') as resp:
assert resp.status == 200
return await resp.text()
async def post_data(client):
async with client.post('http://httpbin.org/post', data={'foo': 'bar'}) as resp:
assert resp.status == 200
return await resp.text()
async def main(loop):
async with aiohttp.ClientSession(loop=loop) as client:
html = await fetch(client)
print(html)
other_html = await post_data(client)
print(other_html)
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
現在我想查看所有請求的狀態代碼、url、標題和所有內容,因此日志中的輸出如下所示:
2017-08-09 08:44:30 DEBUG (200) <GET http://httpbin.org/get>
2017-08-09 08:44:30 DEBUG (200) <POST http://httpbin.org/post>
我知道我可以在每個請求之后添加 logger.log() 調用,但這將是重復的。 如果我有更多的請求,我將不得不在每次調用 logger.log 的請求下編寫重復的代碼。 似乎效率低下。
有aiohttp.client logger ,但沒有詳細說明如何設置它。
我正在嘗試像這樣設置它
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)
logging.getLogger('aiohttp.client').addHandler(ch)
但它不會打印我希望看到的信息(例如響應狀態代碼、url)。
有什么方法可以實現我所需要的嗎? 也許我可以從客戶端訂閱一些信號並在發送信號時記錄一些消息? 例如,有某種機制可以訂閱客戶端收到響應時發送的信號,然后在其上記錄消息?
正如你在 aiohttp 的代碼中看到的,aiohttp.client logger 不是用來記錄請求的,而是只能在響應中的 cookie 無效時記錄警告https://github.com/aio-libs/aiohttp/search? utf8=%E2%9C%93&q=client_logger&type=
要記錄您正在執行的每個請求,您需要創建一個自定義ClientSession
來執行您想要的操作。 類似的東西:
class LoggingClientSession(aiohttp.ClientSession):
def request(self, method, url, **kwargs):
logger.debug('Starting request <%s %r>', method, url)
return super().request(method, url, **kwargs)
——
正如 Jaanus 在此處的評論中所指出的, post
、 get
、 ... 助手現在直接調用ClientSession._request
而不是request
。 因此覆蓋后者不會攔截使用速記助手進行的調用。
所以你可以:
在您的助手中覆蓋_request
而不是request
或者確保您的代碼從不使用get
/... 幫助程序並始終直接調用request
。
或者在你的LoggingClientSession
定義所有的輔助方法
——
正如 Romuald 所指出的, _request
現在是一個協程,所以用常規函數覆蓋它不會在正確的時間記錄。 這是一個更新的示例:
class LoggingClientSession(aiohttp.ClientSession):
async def _request(self, method, url, **kwargs):
logger.debug('Starting request <%s %r>', method, url)
return await super()._request(method, url, **kwargs)
在撰寫本文時 (11/2020),您應該使用aiohttp 的跟蹤功能:
import asyncio
import logging
import aiohttp
async def on_request_start(session, context, params):
logging.getLogger('aiohttp.client').debug(f'Starting request <{params}>')
async def main():
logging.basicConfig(level=logging.DEBUG)
trace_config = aiohttp.TraceConfig()
trace_config.on_request_start.append(on_request_start)
async with aiohttp.ClientSession(trace_configs=[trace_config]) as session:
await session.get('https://google.com')
asyncio.run(main())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.