代码之家  ›  专栏  ›  技术社区  ›  Pawel Miech

如何为aiohttp设置日志记录。客户端在使用aiohttp.ClientSession()发出请求时?

  •  11
  • Pawel Miech  · 技术社区  · 7 年前

    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>
    

    我知道我可以添加记录器。在每个请求后调用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)
    

    有什么方法可以实现我需要的吗?也许我可以订阅来自客户端的一些信号,并在发送信号时记录一些消息?E、 g.是否有某种机制来订阅客户端收到响应时发送的信号,然后将消息记录在上面?

    2 回复  |  直到 7 年前
        1
  •  8
  •   Arthur    4 年前

    正如您在aiohttp的代码中所看到的,aiohttp。客户端记录器不用于记录请求,但只能在响应中的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 要求

    • 或者确保您的代码从不使用 收到 /助手和始终呼叫 要求

    • 或者也可以定义 LoggingClientSession

    -

    正如Romuald所指出的, _请求 现在是一个协程,因此用常规函数重写它将不会在正确的时间进行日志记录。下面是一个更新的示例:

    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)
    
        2
  •  5
  •   apatrushev    4 年前

    在撰写本文时(2020年11月),您应该使用 tracing functionality of 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())