-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
[PROPOSAL] new signal on_request #3787
Copy link
Copy link
Closed
Description
Long story short
We want to attach context from contextvars to logger message
Problem
When user tries to put some information to logs (i.e. request_id) there's no access to contextvars, because user can only put something to contextvars in middleware
I propose to add new signal, like response.on_prepare, but for request, where I can put something to contextvars, for example mark this request with uuid.
see example (python 3.7 only):
import logging
import uuid
from logging.config import dictConfig
import contextvars
from aiohttp import web
from aiohttp.abc import AbstractAccessLogger
REQUEST_ID = contextvars.ContextVar("request_id")
class AsyncAccessLogger(AbstractAccessLogger):
def log(self, request, response, time):
print(("AsyncAccessLogger", REQUEST_ID.get()))
self.logger.info("test")
class ContextFilter(logging.Filter):
def filter(self, record: logging.LogRecord) -> bool:
record.__dict__.update({"request_id": REQUEST_ID.get()})
return True
def setup_logs():
dictConfig(
config={
"version": 1,
"disable_existing_loggers": False,
"filters": {"request_context": {"()": "start_log_test.ContextFilter"}},
"handlers": {"stdout": {"level": "DEBUG", "class": "logging.StreamHandler"}},
"loggers": {
"aiohttp.access": {"handlers": ["stdout"], "level": "DEBUG"},
"aiohttp.server": {"handlers": ["stdout"], "level": "DEBUG"},
},
}
)
@web.middleware
async def request_id(request, handler):
REQUEST_ID.set(str(uuid.uuid4()))
return await handler(request)
async def get_(request: web.Request):
print(("REQUEST", REQUEST_ID.get()))
# for exception
1 / 0
return web.json_response()
def main():
app = web.Application(middlewares=[request_id])
app.add_routes([web.get("/", get_)])
setup_logs()
web.run_app(app, access_log_class=AsyncAccessLogger, port=8088)
if __name__ == "__main__":
main()after request
======== Running on http://0.0.0.0:8088 ========
(Press CTRL+C to quit)
('REQUEST', '3bd497ec-1df1-4deb-842d-d12197a9c9a1')
Error handling request
Traceback (most recent call last):
File ".../code/venvs/aiohttp_logs/lib/python3.7/site-packages/aiohttp/web_protocol.py", line 418, in start
resp = await task
File ".../code/venvs/aiohttp_logs/lib/python3.7/site-packages/aiohttp/web_app.py", line 458, in _handle
resp = await handler(request)
File ".../code/venvs/aiohttp_logs/lib/python3.7/site-packages/aiohttp/web_middlewares.py", line 119, in impl
return await handler(request)
File ".../code/python/aiohttp_logs/start_log_test.py", line 42, in request_id
return await handler(request)
File ".../code/python/aiohttp_logs/start_log_test.py", line 48, in get_
1 / 0
ZeroDivisionError: division by zero
Unhandled exception
Traceback (most recent call last):
File ".../code/venvs/aiohttp_logs/lib/python3.7/site-packages/aiohttp/web_protocol.py", line 455, in start
self.log_access(request, resp, loop.time() - now)
File ".../code/venvs/aiohttp_logs/lib/python3.7/site-packages/aiohttp/web_protocol.py", line 348, in log_access
self.access_logger.log(request, response, time)
File ".../code/python/aiohttp_logs/start_log_test.py", line 14, in log
print(("AsyncAccessLogger", REQUEST_ID.get()))
LookupError: <ContextVar name='request_id' at 0x10aee7d00>
If we agree on design/architecture, I can work on pull request or maybe someone can give us a hint how to achieve that :)
Thanks!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels