mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-29 21:23:55 +08:00
Django: Record status, http.status_code and event on exception (#1257)
This commit is contained in:
@ -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:
|
||||
@ -177,22 +178,11 @@ class _DjangoMiddleware(MiddlewareMixin):
|
||||
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("?")):
|
||||
@ -213,9 +203,17 @@ class _DjangoMiddleware(MiddlewareMixin):
|
||||
)
|
||||
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():
|
||||
@ -231,5 +229,4 @@ class _DjangoMiddleware(MiddlewareMixin):
|
||||
)
|
||||
except Exception as ex: # pylint: disable=W0703
|
||||
_logger.warning("Error recording duration metrics: %s", ex)
|
||||
|
||||
return response
|
||||
|
@ -194,7 +194,7 @@ class TestMiddleware(TestBase, WsgiTestBase):
|
||||
)
|
||||
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,13 +202,22 @@ class TestMiddleware(TestBase, WsgiTestBase):
|
||||
)
|
||||
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/",
|
||||
}
|
||||
)
|
||||
|
Reference in New Issue
Block a user