Skip to content

Commit

Permalink
Django: Record status, http.status_code and event on exception
Browse files Browse the repository at this point in the history
  • Loading branch information
owais committed Oct 19, 2020
1 parent 5fc08ad commit b922711
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class _DjangoMiddleware(MiddlewareMixin):
)
_environ_token = "opentelemetry-instrumentor-django.token"
_environ_span_key = "opentelemetry-instrumentor-django.span_key"
_environ_exception_key = "opentelemetry-instrumentor-django.exception_key"

_excluded_urls = Configuration().DJANGO_EXCLUDED_URLS or []
if _excluded_urls:
Expand Down Expand Up @@ -177,22 +178,11 @@ def process_view(self, request, view_func, *args, **kwargs):
span.set_attribute("http.route", route)

def process_exception(self, request, exception):
# Django can call this method and process_response later. In order
# to avoid __exit__ and detach from being called twice then, the
# respective keys are being removed here.
if self._excluded_urls.url_disabled(request.build_absolute_uri("?")):
return

if self._environ_activation_key in request.META.keys():
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)
request.META[self._environ_exception_key] = exception

def process_response(self, request, response):
if self._excluded_urls.url_disabled(request.build_absolute_uri("?")):
Expand All @@ -213,9 +203,17 @@ def process_response(self, request, response):
)
request.META.pop(self._environ_span_key)

request.META[self._environ_activation_key].__exit__(
None, None, None
)
exception = request.META.pop(self._environ_exception_key, None)
if exception:
request.META[self._environ_activation_key].__exit__(
type(exception),
exception,
getattr(exception, "__traceback__", None),
)
else:
request.META[self._environ_activation_key].__exit__(
None, None, None
)
request.META.pop(self._environ_activation_key)

if self._environ_token in request.META.keys():
Expand All @@ -231,5 +229,4 @@ def process_response(self, request, response):
)
except Exception as ex: # pylint: disable=W0703
_logger.warning("Error recording duration metrics: %s", ex)

return response
Original file line number Diff line number Diff line change
Expand Up @@ -194,21 +194,30 @@ 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(
span.attributes["http.url"], "http://testserver/error/"
)
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)

self.assertEqual(len(span.events), 1)
event = span.events[0]
self.assertEqual(event.name, "exception")
self.assertEqual(event.attributes["exception.type"], "ValueError")
self.assertEqual(event.attributes["exception.message"], "error")

recorder = _django_instrumentor.meter.metrics.pop()
match_key = get_dict_as_key(
{
"http.flavor": "1.1",
"http.method": "GET",
'http.status_code': '500',
"http.url": "http://testserver/error/",
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit b922711

Please sign in to comment.