diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py index 0503d7bbcb6..722ae164046 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py @@ -20,7 +20,10 @@ from opentelemetry.configuration import Configuration from opentelemetry.context import attach, detach from opentelemetry.instrumentation.django.version import __version__ -from opentelemetry.instrumentation.utils import extract_attributes_from_object +from opentelemetry.instrumentation.utils import ( + extract_attributes_from_object, + http_status_to_canonical_code, +) from opentelemetry.instrumentation.wsgi import ( add_response_attributes, collect_request_attributes, @@ -28,6 +31,7 @@ ) from opentelemetry.propagators import extract from opentelemetry.trace import SpanKind, get_tracer +from opentelemetry.trace.status import Status from opentelemetry.util import ExcludeList try: @@ -184,13 +188,27 @@ def process_exception(self, request, exception): return if self._environ_activation_key in request.META.keys(): + status_code = 500 + # pylint:disable=W0212 + span = request.META.get(self._environ_span_key, None) + if span and span.is_recording(): + span.set_attribute("http.status_code", status_code) + span.set_status( + Status( + canonical_code=http_status_to_canonical_code( + status_code + ), + description="{}: {}".format( + exception.__class__.__name__, exception + ), + ) + ) request.META[self._environ_activation_key].__exit__( type(exception), exception, getattr(exception, "__traceback__", None), ) request.META.pop(self._environ_activation_key) - detach(request.environ[self._environ_token]) request.META.pop(self._environ_token, None) @@ -231,5 +249,4 @@ def process_response(self, request, response): ) except Exception as ex: # pylint: disable=W0703 _logger.warning("Error recording duration metrics: %s", ex) - return response diff --git a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py index 5c034a23af2..f066ad3f608 100644 --- a/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py @@ -194,7 +194,7 @@ def test_error(self): ) self.assertEqual(span.kind, SpanKind.SERVER) self.assertEqual( - span.status.canonical_code, StatusCanonicalCode.UNKNOWN + span.status.canonical_code, StatusCanonicalCode.INTERNAL ) self.assertEqual(span.attributes["http.method"], "GET") self.assertEqual( @@ -202,6 +202,7 @@ def test_error(self): ) self.assertEqual(span.attributes["http.route"], "^error/") self.assertEqual(span.attributes["http.scheme"], "http") + self.assertEqual(span.attributes["http.status_code"], 500) self.assertIsNotNone(_django_instrumentor.meter) self.assertEqual(len(_django_instrumentor.meter.metrics), 1) recorder = _django_instrumentor.meter.metrics.pop() diff --git a/instrumentation/opentelemetry-instrumentation-flask/CHANGELOG.md b/instrumentation/opentelemetry-instrumentation-flask/CHANGELOG.md index a4641e55b66..bd6ea89cb21 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/CHANGELOG.md +++ b/instrumentation/opentelemetry-instrumentation-flask/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Record span status and http.status_code attribute on exception + ([#1257](https://github.com/open-telemetry/opentelemetry-python/pull/1257)) + ## Version 0.13b0 Released 2020-09-17