Added ability to extract span attributes from django request objects. (#1154)

OTEL_PYTHON_DJANGO_TRACED_REQUEST_ATTRS env var can be set to a command
separated list of attributes names that will be extracted from Django's
request object and set as attributes on spans.
This commit is contained in:
Owais Lone
2020-09-29 10:22:11 +05:30
committed by GitHub
parent 06511cd31a
commit e3199ac411
4 changed files with 54 additions and 0 deletions

View File

@ -3,6 +3,7 @@
## Unreleased
- Changed span name extraction from request to comply semantic convention ([#992](https://github.com/open-telemetry/opentelemetry-python/pull/992))
- Added support for `OTEL_PYTHON_DJANGO_TRACED_REQUEST_ATTRS` ([#1154](https://github.com/open-telemetry/opentelemetry-python/pull/1154))
## Version 0.13b0

View File

@ -30,6 +30,21 @@ For example,
will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``.
Request attributes
********************
To extract certain attributes from Django's request object and use them as span attributes, set the environment variable ``OTEL_PYTHON_DJANGO_TRACED_REQUEST_ATTRS`` to a comma
delimited list of request attribute names.
For example,
::
export OTEL_PYTHON_DJANGO_TRACED_REQUEST_ATTRS='path_info,content_type'
will extract path_info and content_type attributes from every traced request and add them as span attritbues.
Django Request object reference: https://docs.djangoproject.com/en/3.1/ref/request-response/#attributes
References
----------

View File

@ -58,6 +58,13 @@ class _DjangoMiddleware(MiddlewareMixin):
else:
_excluded_urls = ExcludeList(_excluded_urls)
_traced_request_attrs = [
attr.strip()
for attr in (Configuration().DJANGO_TRACED_REQUEST_ATTRS or "").split(
","
)
]
@staticmethod
def _get_span_name(request):
try:
@ -95,6 +102,10 @@ class _DjangoMiddleware(MiddlewareMixin):
tracer = get_tracer(__name__, __version__)
attributes = collect_request_attributes(environ)
for attr in self._traced_request_attrs:
value = getattr(request, attr, None)
if value is not None:
attributes[attr] = str(value)
span = tracer.start_span(
self._get_span_name(request),

View File

@ -174,3 +174,30 @@ class TestMiddleware(WsgiTestBase):
span = span_list[0]
self.assertEqual(span.name, "HTTP GET")
def test_traced_request_attrs(self):
with patch(
"opentelemetry.instrumentation.django.middleware._DjangoMiddleware._traced_request_attrs",
[],
):
Client().get("/span_name/1234/", CONTENT_TYPE="test/ct")
span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 1)
span = span_list[0]
self.assertNotIn("path_info", span.attributes)
self.assertNotIn("content_type", span.attributes)
self.memory_exporter.clear()
with patch(
"opentelemetry.instrumentation.django.middleware._DjangoMiddleware._traced_request_attrs",
["path_info", "content_type", "non_existing_variable"],
):
Client().get("/span_name/1234/", CONTENT_TYPE="test/ct")
span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 1)
span = span_list[0]
self.assertEqual(span.attributes["path_info"], "/span_name/1234/")
self.assertEqual(span.attributes["content_type"], "test/ct")
self.assertNotIn("non_existing_variable", span.attributes)