mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-08-01 17:34:38 +08:00
Configurable Middleware Position for Django Instrumentation (#2912)
This commit is contained in:
@ -417,6 +417,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
([#1879](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1879))
|
([#1879](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1879))
|
||||||
- Add optional distro and configurator selection for auto-instrumentation
|
- Add optional distro and configurator selection for auto-instrumentation
|
||||||
([#1823](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1823))
|
([#1823](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1823))
|
||||||
|
- `opentelemetry-instrumentation-django` - Add option to add Opentelemetry middleware at specific position in middleware chain
|
||||||
|
([#2912]https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2912)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
@ -285,6 +285,30 @@ def _get_django_middleware_setting() -> str:
|
|||||||
return "MIDDLEWARE"
|
return "MIDDLEWARE"
|
||||||
|
|
||||||
|
|
||||||
|
def _get_django_otel_middleware_position(
|
||||||
|
middleware_length, default_middleware_position=0
|
||||||
|
):
|
||||||
|
otel_position = environ.get("OTEL_PYTHON_DJANGO_MIDDLEWARE_POSITION")
|
||||||
|
try:
|
||||||
|
middleware_position = int(otel_position)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
_logger.debug(
|
||||||
|
"Invalid OTEL_PYTHON_DJANGO_MIDDLEWARE_POSITION value: (%s). Using default position: %d.",
|
||||||
|
otel_position,
|
||||||
|
default_middleware_position,
|
||||||
|
)
|
||||||
|
middleware_position = default_middleware_position
|
||||||
|
|
||||||
|
if middleware_position < 0 or middleware_position > middleware_length:
|
||||||
|
_logger.debug(
|
||||||
|
"Middleware position %d is out of range (0-%d). Using 0 as the position",
|
||||||
|
middleware_position,
|
||||||
|
middleware_length,
|
||||||
|
)
|
||||||
|
middleware_position = 0
|
||||||
|
return middleware_position
|
||||||
|
|
||||||
|
|
||||||
class DjangoInstrumentor(BaseInstrumentor):
|
class DjangoInstrumentor(BaseInstrumentor):
|
||||||
"""An instrumentor for Django
|
"""An instrumentor for Django
|
||||||
|
|
||||||
@ -388,10 +412,18 @@ class DjangoInstrumentor(BaseInstrumentor):
|
|||||||
|
|
||||||
is_sql_commentor_enabled = kwargs.pop("is_sql_commentor_enabled", None)
|
is_sql_commentor_enabled = kwargs.pop("is_sql_commentor_enabled", None)
|
||||||
|
|
||||||
if is_sql_commentor_enabled:
|
middleware_position = _get_django_otel_middleware_position(
|
||||||
settings_middleware.insert(0, self._sql_commenter_middleware)
|
len(settings_middleware), kwargs.pop("middleware_position", 0)
|
||||||
|
)
|
||||||
|
|
||||||
settings_middleware.insert(0, self._opentelemetry_middleware)
|
if is_sql_commentor_enabled:
|
||||||
|
settings_middleware.insert(
|
||||||
|
middleware_position, self._sql_commenter_middleware
|
||||||
|
)
|
||||||
|
|
||||||
|
settings_middleware.insert(
|
||||||
|
middleware_position, self._opentelemetry_middleware
|
||||||
|
)
|
||||||
|
|
||||||
setattr(settings, _middleware_setting, settings_middleware)
|
setattr(settings, _middleware_setting, settings_middleware)
|
||||||
|
|
||||||
|
@ -157,6 +157,46 @@ class TestMiddleware(WsgiTestBase):
|
|||||||
super().tearDownClass()
|
super().tearDownClass()
|
||||||
conf.settings = conf.LazySettings()
|
conf.settings = conf.LazySettings()
|
||||||
|
|
||||||
|
def test_middleware_added_at_position(self):
|
||||||
|
_django_instrumentor.uninstrument()
|
||||||
|
if DJANGO_2_0:
|
||||||
|
middleware = conf.settings.MIDDLEWARE
|
||||||
|
else:
|
||||||
|
middleware = conf.settings.MIDDLEWARE_CLASSES
|
||||||
|
# adding two dummy middlewares
|
||||||
|
temprory_middelware = "django.utils.deprecation.MiddlewareMixin"
|
||||||
|
middleware.append(temprory_middelware)
|
||||||
|
middleware.append(temprory_middelware)
|
||||||
|
|
||||||
|
middleware_position = 1
|
||||||
|
_django_instrumentor.instrument(
|
||||||
|
middleware_position=middleware_position
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
middleware[middleware_position],
|
||||||
|
"opentelemetry.instrumentation.django.middleware.otel_middleware._DjangoMiddleware",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_middleware_added_at_position_if_wrong_position(self):
|
||||||
|
_django_instrumentor.uninstrument()
|
||||||
|
if DJANGO_2_0:
|
||||||
|
middleware = conf.settings.MIDDLEWARE
|
||||||
|
else:
|
||||||
|
middleware = conf.settings.MIDDLEWARE_CLASSES
|
||||||
|
# adding middleware
|
||||||
|
temprory_middelware = "django.utils.deprecation.MiddlewareMixin"
|
||||||
|
middleware.append(temprory_middelware)
|
||||||
|
middleware_position = (
|
||||||
|
756 # wrong position out of bound of middleware length
|
||||||
|
)
|
||||||
|
_django_instrumentor.instrument(
|
||||||
|
middleware_position=middleware_position
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
middleware[0],
|
||||||
|
"opentelemetry.instrumentation.django.middleware.otel_middleware._DjangoMiddleware",
|
||||||
|
)
|
||||||
|
|
||||||
def test_templated_route_get(self):
|
def test_templated_route_get(self):
|
||||||
Client().get("/route/2020/template/")
|
Client().get("/route/2020/template/")
|
||||||
|
|
||||||
|
@ -72,6 +72,37 @@ class TestMiddleware(WsgiTestBase):
|
|||||||
in middleware
|
in middleware
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@patch(
|
||||||
|
"opentelemetry.instrumentation.django.middleware.sqlcommenter_middleware.SqlCommenter"
|
||||||
|
)
|
||||||
|
def test_middleware_added_at_position(self, sqlcommenter_middleware):
|
||||||
|
_django_instrumentor.uninstrument()
|
||||||
|
if DJANGO_2_0:
|
||||||
|
middleware = conf.settings.MIDDLEWARE
|
||||||
|
else:
|
||||||
|
middleware = conf.settings.MIDDLEWARE_CLASSES
|
||||||
|
|
||||||
|
# adding two dummy middlewares
|
||||||
|
temprory_middelware = "django.utils.deprecation.MiddlewareMixin"
|
||||||
|
middleware.append(temprory_middelware)
|
||||||
|
middleware.append(temprory_middelware)
|
||||||
|
|
||||||
|
middleware_position = 1
|
||||||
|
_django_instrumentor.instrument(
|
||||||
|
is_sql_commentor_enabled=True,
|
||||||
|
middleware_position=middleware_position,
|
||||||
|
)
|
||||||
|
instance = sqlcommenter_middleware.return_value
|
||||||
|
instance.get_response = HttpResponse()
|
||||||
|
self.assertEqual(
|
||||||
|
middleware[middleware_position],
|
||||||
|
"opentelemetry.instrumentation.django.middleware.otel_middleware._DjangoMiddleware",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
middleware[middleware_position + 1],
|
||||||
|
"opentelemetry.instrumentation.django.middleware.sqlcommenter_middleware.SqlCommenter",
|
||||||
|
)
|
||||||
|
|
||||||
@patch(
|
@patch(
|
||||||
"opentelemetry.instrumentation.django.middleware.sqlcommenter_middleware._get_opentelemetry_values"
|
"opentelemetry.instrumentation.django.middleware.sqlcommenter_middleware._get_opentelemetry_values"
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user