Skip to content

Commit f267021

Browse files
committed
Django middleware position is now configurable
1 parent d7d7e96 commit f267021

File tree

4 files changed

+98
-2
lines changed

4 files changed

+98
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
402402
([#1879](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1879))
403403
- Add optional distro and configurator selection for auto-instrumentation
404404
([#1823](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1823))
405+
- Add option to add Opentelemetry middleware at specific position in middleware chain
406+
([#2908]https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2908)
405407

406408
### Added
407409
- `opentelemetry-instrumentation-kafka-python` Add instrumentation to `consume` method

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

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,33 @@ def _instrument(self, **kwargs):
388388

389389
is_sql_commentor_enabled = kwargs.pop("is_sql_commentor_enabled", None)
390390

391+
otel_position = environ.get("OTEL_PYTHON_DJANGO_MIDDLEWARE_POSITION")
392+
try:
393+
middleware_position = int(otel_position)
394+
except (ValueError, TypeError):
395+
_logger.debug(
396+
"The middleware_position you provided (%s) is not an integer. Defaulting to 0.",
397+
otel_position,
398+
)
399+
middleware_position = kwargs.pop("middleware_position", 0)
400+
401+
if len(settings_middleware) < middleware_position:
402+
_logger.debug(
403+
"The middleware_position you provided (%s) is greater than the number of middlewares (%s). Defaulting "
404+
"the middleware_position to 0.",
405+
middleware_position,
406+
len(settings_middleware),
407+
)
408+
middleware_position = 0
409+
391410
if is_sql_commentor_enabled:
392-
settings_middleware.insert(0, self._sql_commenter_middleware)
411+
settings_middleware.insert(
412+
middleware_position, self._sql_commenter_middleware
413+
)
393414

394-
settings_middleware.insert(0, self._opentelemetry_middleware)
415+
settings_middleware.insert(
416+
middleware_position, self._opentelemetry_middleware
417+
)
395418

396419
setattr(settings, _middleware_setting, settings_middleware)
397420

instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,46 @@ def tearDownClass(cls):
157157
super().tearDownClass()
158158
conf.settings = conf.LazySettings()
159159

160+
def test_middleware_added_at_position(self):
161+
_django_instrumentor.uninstrument()
162+
if DJANGO_2_0:
163+
middleware = conf.settings.MIDDLEWARE
164+
else:
165+
middleware = conf.settings.MIDDLEWARE_CLASSES
166+
# adding two dummy middlewares
167+
temprory_middelware = "django.utils.deprecation.MiddlewareMixin"
168+
middleware.append(temprory_middelware)
169+
middleware.append(temprory_middelware)
170+
171+
middleware_position = 1
172+
_django_instrumentor.instrument(
173+
middleware_position=middleware_position
174+
)
175+
self.assertEqual(
176+
middleware[middleware_position],
177+
"opentelemetry.instrumentation.django.middleware.otel_middleware._DjangoMiddleware",
178+
)
179+
180+
def test_middleware_added_at_position_if_wrong_position(self):
181+
_django_instrumentor.uninstrument()
182+
if DJANGO_2_0:
183+
middleware = conf.settings.MIDDLEWARE
184+
else:
185+
middleware = conf.settings.MIDDLEWARE_CLASSES
186+
# adding middleware
187+
temprory_middelware = "django.utils.deprecation.MiddlewareMixin"
188+
middleware.append(temprory_middelware)
189+
middleware_position = (
190+
756 # wrong position out of bound of middleware length
191+
)
192+
_django_instrumentor.instrument(
193+
middleware_position=middleware_position
194+
)
195+
self.assertEqual(
196+
middleware[len(middleware) - 1],
197+
"opentelemetry.instrumentation.django.middleware.otel_middleware._DjangoMiddleware",
198+
)
199+
160200
def test_templated_route_get(self):
161201
Client().get("/route/2020/template/")
162202

instrumentation/opentelemetry-instrumentation-django/tests/test_sqlcommenter.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,37 @@ def test_middleware_added(self, sqlcommenter_middleware):
7272
in middleware
7373
)
7474

75+
@patch(
76+
"opentelemetry.instrumentation.django.middleware.sqlcommenter_middleware.SqlCommenter"
77+
)
78+
def test_middleware_added_at_position(self, sqlcommenter_middleware):
79+
_django_instrumentor.uninstrument()
80+
if DJANGO_2_0:
81+
middleware = conf.settings.MIDDLEWARE
82+
else:
83+
middleware = conf.settings.MIDDLEWARE_CLASSES
84+
85+
# adding two dummy middlewares
86+
temprory_middelware = "django.utils.deprecation.MiddlewareMixin"
87+
middleware.append(temprory_middelware)
88+
middleware.append(temprory_middelware)
89+
90+
middleware_position = 1
91+
_django_instrumentor.instrument(
92+
is_sql_commentor_enabled=True,
93+
middleware_position=middleware_position,
94+
)
95+
instance = sqlcommenter_middleware.return_value
96+
instance.get_response = HttpResponse()
97+
self.assertEqual(
98+
middleware[middleware_position],
99+
"opentelemetry.instrumentation.django.middleware.otel_middleware._DjangoMiddleware",
100+
)
101+
self.assertEqual(
102+
middleware[middleware_position + 1],
103+
"opentelemetry.instrumentation.django.middleware.sqlcommenter_middleware.SqlCommenter",
104+
)
105+
75106
@patch(
76107
"opentelemetry.instrumentation.django.middleware.sqlcommenter_middleware._get_opentelemetry_values"
77108
)

0 commit comments

Comments
 (0)