Skip to content

Commit d01efe5

Browse files
Develop/condition server span django (#832)
* Code changes and pytests for #448 * removing unnecessary imports * removing unnecessary imports * adding wsgi.py file to get the wsgi application object * Revert "Updating personal fork from public repo" * Revert "Updating personal fork from public repo" * Revert "Updating personal fork from public repo" * Revert "Updating personal fork from public repo" * Changing the unit test case by removing WSGI instrumentation and make it from generalised * removing unnecessary import statements * Revert "Updating personal fork from public repo" * resolving failed builds for lint and generate * removing commented code * removing blank line * removed unused variable resp from test_middleware.py and modified the CHANGELOG.md with PR entry * modified the CHANGELOG.md to removed unnecessary entry * modified the CHANGELOG.md to add proper PR entry Co-authored-by: Diego Hurtado <[email protected]>
1 parent 4c813c4 commit d01efe5

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414

1515
### Fixed
1616

17+
- `opentelemetry-instrumentation-django` Django: Conditionally create SERVER spans
18+
([#832](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/832))
19+
1720
- `opentelemetry-instrumentation-flask` Flask: Conditionally create SERVER spans
1821
([#828](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/828))
1922

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

+18-6
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@
3232
from opentelemetry.instrumentation.wsgi import wsgi_getter
3333
from opentelemetry.propagate import extract
3434
from opentelemetry.semconv.trace import SpanAttributes
35-
from opentelemetry.trace import Span, SpanKind, use_span
35+
from opentelemetry.trace import (
36+
INVALID_SPAN,
37+
Span,
38+
SpanKind,
39+
get_current_span,
40+
use_span,
41+
)
3642
from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs
3743

3844
try:
@@ -183,11 +189,16 @@ def process_request(self, request):
183189
carrier_getter = wsgi_getter
184190
collect_request_attributes = wsgi_collect_request_attributes
185191

186-
token = attach(extract(carrier, getter=carrier_getter))
187-
192+
token = context = None
193+
span_kind = SpanKind.INTERNAL
194+
if get_current_span() is INVALID_SPAN:
195+
context = extract(carrier, getter=carrier_getter)
196+
token = attach(context)
197+
span_kind = SpanKind.SERVER
188198
span = self._tracer.start_span(
189199
self._get_span_name(request),
190-
kind=SpanKind.SERVER,
200+
context,
201+
kind=span_kind,
191202
start_time=request_meta.get(
192203
"opentelemetry-instrumentor-django.starttime_key"
193204
),
@@ -220,7 +231,8 @@ def process_request(self, request):
220231

221232
request.META[self._environ_activation_key] = activation
222233
request.META[self._environ_span_key] = span
223-
request.META[self._environ_token] = token
234+
if token:
235+
request.META[self._environ_token] = token
224236

225237
if _DjangoMiddleware._otel_request_hook:
226238
_DjangoMiddleware._otel_request_hook( # pylint: disable=not-callable
@@ -295,7 +307,7 @@ def process_response(self, request, response):
295307
else:
296308
activation.__exit__(None, None, None)
297309

298-
if self._environ_token in request.META.keys():
310+
if request.META.get(self._environ_token, None) is not None:
299311
detach(request.META.get(self._environ_token))
300312
request.META.pop(self._environ_token)
301313

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

+19
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from django.test.client import Client
2323
from django.test.utils import setup_test_environment, teardown_test_environment
2424

25+
from opentelemetry import trace
2526
from opentelemetry.instrumentation.django import (
2627
DjangoInstrumentor,
2728
_DjangoMiddleware,
@@ -409,6 +410,7 @@ def setUp(self):
409410
result = self.create_tracer_provider(resource=resource)
410411
tracer_provider, exporter = result
411412
self.exporter = exporter
413+
self.tracer_provider = tracer_provider
412414
_django_instrumentor.instrument(tracer_provider=tracer_provider)
413415

414416
def tearDown(self):
@@ -432,3 +434,20 @@ def test_tracer_provider_traced(self):
432434
self.assertEqual(
433435
span.resource.attributes["resource-key"], "resource-value"
434436
)
437+
438+
def test_django_with_wsgi_instrumented(self):
439+
tracer = self.tracer_provider.get_tracer(__name__)
440+
with tracer.start_as_current_span(
441+
"test", kind=SpanKind.SERVER
442+
) as parent_span:
443+
Client().get("/span_name/1234/")
444+
span_list = self.exporter.get_finished_spans()
445+
print(span_list)
446+
self.assertEqual(
447+
span_list[0].attributes[SpanAttributes.HTTP_STATUS_CODE], 200
448+
)
449+
self.assertEqual(trace.SpanKind.INTERNAL, span_list[0].kind)
450+
self.assertEqual(
451+
parent_span.get_span_context().span_id,
452+
span_list[0].parent.span_id,
453+
)

0 commit comments

Comments
 (0)