Skip to content

Instantly share code, notes, and snippets.

@srikanthccv
Created January 24, 2022 19:10
Show Gist options
  • Save srikanthccv/89007a022321de3f04ce90e1983b8209 to your computer and use it in GitHub Desktop.
Save srikanthccv/89007a022321de3f04ce90e1983b8209 to your computer and use it in GitHub Desktop.
diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py
index d5e1f072..a03b9c6d 100644
--- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py
+++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/__init__.py
@@ -90,7 +90,11 @@ from django.conf import settings
from opentelemetry.instrumentation.django.environment_variables import (
OTEL_PYTHON_DJANGO_INSTRUMENT,
)
-from opentelemetry.instrumentation.django.middleware import _DjangoMiddleware
+from opentelemetry.instrumentation.django.middleware import (
+ _DjangoMiddleware,
+ _QueryExecuteWrapper,
+ _QueryMiddleware,
+)
from opentelemetry.instrumentation.django.package import _instruments
from opentelemetry.instrumentation.django.version import __version__
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
@@ -119,6 +123,9 @@ class DjangoInstrumentor(BaseInstrumentor):
_opentelemetry_middleware = ".".join(
[_DjangoMiddleware.__module__, _DjangoMiddleware.__qualname__]
)
+ _query_middleware = ".".join(
+ [_QueryMiddleware.__module__, _QueryMiddleware.__qualname__]
+ )
def instrumentation_dependencies(self) -> Collection[str]:
return _instruments
@@ -138,6 +145,7 @@ class DjangoInstrumentor(BaseInstrumentor):
)
_DjangoMiddleware._tracer = tracer
+ _QueryExecuteWrapper._tracer = tracer
_DjangoMiddleware._otel_request_hook = kwargs.pop("request_hook", None)
_DjangoMiddleware._otel_response_hook = kwargs.pop(
@@ -158,6 +166,7 @@ class DjangoInstrumentor(BaseInstrumentor):
if isinstance(settings_middleware, tuple):
settings_middleware = list(settings_middleware)
+ settings_middleware.insert(0, self._query_middleware)
settings_middleware.insert(0, self._opentelemetry_middleware)
setattr(settings, _middleware_setting, settings_middleware)
@@ -176,4 +185,6 @@ class DjangoInstrumentor(BaseInstrumentor):
return
settings_middleware.remove(self._opentelemetry_middleware)
+ if self._query_middleware in settings_middleware:
+ settings_middleware.remove(self._query_middleware)
setattr(settings, _middleware_setting, settings_middleware)
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 47df930b..0f41b59a 100644
--- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py
+++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware.py
@@ -18,13 +18,17 @@ from time import time
from typing import Callable
from django import VERSION as django_version
+from django.db import connection
from django.http import HttpRequest, HttpResponse
from opentelemetry.context import attach, detach
from opentelemetry.instrumentation.propagators import (
get_global_response_propagator,
)
-from opentelemetry.instrumentation.utils import extract_attributes_from_object
+from opentelemetry.instrumentation.utils import (
+ _SUPPRESS_INSTRUMENTATION_KEY,
+ extract_attributes_from_object,
+)
from opentelemetry.instrumentation.wsgi import add_response_attributes
from opentelemetry.instrumentation.wsgi import (
collect_request_attributes as wsgi_collect_request_attributes,
@@ -39,6 +43,7 @@ from opentelemetry.trace import (
get_current_span,
use_span,
)
+from opentelemetry.trace.status import Status, StatusCode
from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs
try:
@@ -312,3 +317,39 @@ class _DjangoMiddleware(MiddlewareMixin):
request.META.pop(self._environ_token)
return response
+
+
+class _QueryMiddleware:
+ def __init__(self, get_response):
+ self.get_response = get_response
+
+ def __call__(self, request):
+ with connection.execute_wrapper(_QueryExecuteWrapper(request)):
+ return self.get_response(request)
+
+
+class _QueryExecuteWrapper:
+
+ _tracer = None
+
+ def __init__(self, request):
+ self.request = request
+
+ def __call__(self, execute, sql, params, many, context):
+
+ span = self._tracer.start_span(sql, kind=SpanKind.CLIENT)
+ try:
+ result = execute(sql, params, many, context)
+ except Exception as exc:
+ span.set_status(
+ Status(
+ status_code=StatusCode.ERROR,
+ description=f"{type(exc).__name__}: {exc}",
+ )
+ )
+ span.record_exception(exc)
+ raise exc
+ else:
+ return result
+ finally:
+ span.end()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment