Skip to content

Commit d9d3439

Browse files
committed
Migrate Django middleware to new-style
New-style middlewares were [introduced][django_1_10_changelog] in Django `1.10`, and also `settings.MIDDLEWARE_CLASSES` was [removed][django_2_0_changelog] in Django 2.0. This change migrates the Django middleware to conform with the new style. This is useful because it will help us solve the pending issue in open-telemetry#391. By having a single entrypoint to the middleware, `__call__`, which is [wrapped with `sync_to_async` just once][call_wrapped] for async requests, we avoid the [issue][asgiref_issue] where a `ContextVar` cannot be reset from a different context. With the current deprecated `MiddlewareMixin` way, both `process_request` and `process_response` were being [wrapped separately with `sync_to_async`][mixin_wrapped], which was the source of the mentioned issue. [django_1_10_changelog]: https://docs.djangoproject.com/en/3.2/releases/1.10/#new-style-middleware [django_2_0_changelog]: https://docs.djangoproject.com/en/3.2/releases/2.0/#features-removed-in-2-0 [call_wrapped]: https://github.com/django/django/blob/213850b4b9641bdcb714172999725ec9aa9c9e84/django/core/handlers/base.py#L54-L57 [mixin_wrapped]: https://github.com/django/django/blob/213850b4b9641bdcb714172999725ec9aa9c9e84/django/utils/deprecation.py#L137-L147 [asgiref_issue]: django/asgiref#267
1 parent 5b125b1 commit d9d3439

File tree

1 file changed

+9
-6
lines changed
  • instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django

1 file changed

+9
-6
lines changed

instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,6 @@
4242
except ImportError:
4343
from django.urls import Resolver404, resolve
4444

45-
try:
46-
from django.utils.deprecation import MiddlewareMixin
47-
except ImportError:
48-
MiddlewareMixin = object
49-
5045
_logger = getLogger(__name__)
5146
_attributes_by_preference = [
5247
[
@@ -70,7 +65,7 @@
7065
]
7166

7267

73-
class _DjangoMiddleware(MiddlewareMixin):
68+
class _DjangoMiddleware:
7469
"""Django Middleware for OpenTelemetry"""
7570

7671
_environ_activation_key = (
@@ -89,6 +84,9 @@ class _DjangoMiddleware(MiddlewareMixin):
8984
[Span, HttpRequest, HttpResponse], None
9085
] = None
9186

87+
def __init__(self, get_response):
88+
self.get_response = get_response
89+
9290
@staticmethod
9391
def _get_span_name(request):
9492
try:
@@ -111,6 +109,11 @@ def _get_span_name(request):
111109
except Resolver404:
112110
return "HTTP {}".format(request.method)
113111

112+
def __call__(self, request):
113+
self.process_request(request)
114+
response = self.get_response(request)
115+
return self.process_response(request, response)
116+
114117
def process_request(self, request):
115118
# request.META is a dictionary containing all available HTTP headers
116119
# Read more about request.META here:

0 commit comments

Comments
 (0)