Skip to content

Add support for asgi django apps #607

@thegoodlittlescript

Description

@thegoodlittlescript

Currently the RequestMiddleware for django uses threading.local to pass the request to the logging code. As a consequence it appears the middleware can only be used by a wsgi app. Without the middleware headers are unavailable to the logging code and things like traceparent logging won't happen. I don't know much about it but I've seen references to asgiref as the way to store thread locals for an asgi app.

I request you add support for asgi, maybe by making an asgiref version of RequestMiddleware.

Notes

When I run an example app using asgi, I get errors like:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.10/site-packages/django/utils/deprecation.py", line 136, in __call__
    response = self.process_response(request, response)
  File "/usr/local/lib/python3.10/site-packages/django/middleware/clickjacking.py", line 27, in process_response
    if response.get("X-Frame-Options") is not None:
AttributeError: 'coroutine' object has no attribute 'get'
[2022-08-15 15:21:54 +0000] [77] [ERROR] Exception in ASGI application
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 403, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "/usr/local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
    return await self.app(scope, receive, send)
  File "/usr/local/lib/python3.10/site-packages/django/core/handlers/asgi.py", line 155, in __call__
    await self.handle(scope, receive, send)
  File "/usr/local/lib/python3.10/site-packages/django/core/handlers/asgi.py", line 177, in handle
    response = await self.get_response_async(request)
  File "/usr/local/lib/python3.10/site-packages/django/core/handlers/base.py", line 162, in get_response_async
    response = await self._middleware_chain(request)
TypeError: object HttpResponse can't be used in 'await' expression

For this I made a django app using:

Django==4.0.4
uvicorn==0.18.2
gunicorn==20.1.0
google-cloud-logging==3.1.2

Configured it like:

# added at the bottom of settings.py
import google.cloud.logging
google.cloud.logging.Client().setup_logging()
MIDDLEWARE.append('google.cloud.logging_v2.handlers.middleware.request.RequestMiddleware')

And ran it like:

gunicorn server.asgi -k uvicorn.workers.UvicornWorker

Metadata

Metadata

Assignees

Labels

api: loggingIssues related to the googleapis/python-logging API.priority: p2Moderately-important priority. Fix may not be included in next release.type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions