Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在使用aiohttp.ClientSession()发出请求时为aiohttp.client设置日志记录?_Python_Python 3.x_Python 3.5_Python Asyncio_Aiohttp - Fatal编程技术网

Python 如何在使用aiohttp.ClientSession()发出请求时为aiohttp.client设置日志记录?

Python 如何在使用aiohttp.ClientSession()发出请求时为aiohttp.client设置日志记录?,python,python-3.x,python-3.5,python-asyncio,aiohttp,Python,Python 3.x,Python 3.5,Python Asyncio,Aiohttp,我有一些代码生成对一些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_d

我有一些代码生成对一些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))
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、标题和所有内容,因此日志中的输出如下所示:

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>
但它不会打印我希望看到的信息(例如响应状态代码、url)


有什么方法可以实现我的需求吗?也许我可以订阅来自客户端的一些信号,并在发送信号时记录一些消息?例如,有某种机制可以订阅客户端接收响应时发送的信号,然后在该信号上记录消息?

正如您在aiohttp的代码中所看到的,aiohttp.client记录器不用于记录请求,但只能在响应中的cookie无效时记录警告

要记录您正在执行的每个请求,您需要创建一个定制的
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)
在撰写本文时(2020年11月),您应使用:

导入异步IO
导入日志记录
进口aiohttp
请求启动时的异步定义(会话、上下文、参数):
logging.getLogger('aiohttp.client').debug(f'Starting request'))
异步def main():
logging.basicConfig(级别=logging.DEBUG)
trace_config=aiohttp.TraceConfig()
跟踪请求启动时的配置。追加(请求启动时)
与aiohttp.ClientSession(trace\u configs=[trace\u config])作为会话异步:
等待会话。获取会话https://google.com')
asyncio.run(main())

非常适合将其包装到类中。非常干净!看起来,
请求
已重命名
\u请求
@JeremyBanks否,
\u请求
是不应修改的aiohttp内部。
请求
方法仍然存在,可用于拦截所有请求。cf即使是内部的,覆盖
\u请求
而不是
请求
也是很有用的,因为会话方法,如
获取
发布
等,都是通过前者而不是后者进行的。但是正如@Arthur所提到的,这是一个很滑的斜坡,可以从一个版本到另一个版本进行更改。对于aiohttp来说,不为最常用的调试功能之一提供挂钩是相当不明智的。其他语言HTTP客户端提供了某种方式,可以在请求发送到网络之前拦截请求,而无需破解“私有”方法。
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)
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())