aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/django/middleware/sqlcommenter_middleware.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/django/middleware/sqlcommenter_middleware.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are hereHEADmaster
Diffstat (limited to '.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/django/middleware/sqlcommenter_middleware.py')
-rw-r--r--.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/django/middleware/sqlcommenter_middleware.py123
1 files changed, 123 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/django/middleware/sqlcommenter_middleware.py b/.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/django/middleware/sqlcommenter_middleware.py
new file mode 100644
index 00000000..ef53d5dc
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/django/middleware/sqlcommenter_middleware.py
@@ -0,0 +1,123 @@
+# Copyright The OpenTelemetry Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from contextlib import ExitStack
+from logging import getLogger
+from typing import Any, Type, TypeVar
+
+# pylint: disable=no-name-in-module
+from django import conf, get_version
+from django.db import connections
+from django.db.backends.utils import CursorDebugWrapper
+
+from opentelemetry.instrumentation.sqlcommenter_utils import _add_sql_comment
+from opentelemetry.instrumentation.utils import _get_opentelemetry_values
+from opentelemetry.trace.propagation.tracecontext import (
+ TraceContextTextMapPropagator,
+)
+
+_propagator = TraceContextTextMapPropagator()
+
+_django_version = get_version()
+_logger = getLogger(__name__)
+
+T = TypeVar("T") # pylint: disable-msg=invalid-name
+
+
+class SqlCommenter:
+ """
+ Middleware to append a comment to each database query with details about
+ the framework and the execution context.
+ """
+
+ def __init__(self, get_response) -> None:
+ self.get_response = get_response
+
+ def __call__(self, request) -> Any:
+ with ExitStack() as stack:
+ for db_alias in connections:
+ stack.enter_context(
+ connections[db_alias].execute_wrapper(
+ _QueryWrapper(request)
+ )
+ )
+ return self.get_response(request)
+
+
+class _QueryWrapper:
+ def __init__(self, request) -> None:
+ self.request = request
+
+ def __call__(self, execute: Type[T], sql, params, many, context) -> T:
+ # pylint: disable-msg=too-many-locals
+ with_framework = getattr(
+ conf.settings, "SQLCOMMENTER_WITH_FRAMEWORK", True
+ )
+ with_controller = getattr(
+ conf.settings, "SQLCOMMENTER_WITH_CONTROLLER", True
+ )
+ with_route = getattr(conf.settings, "SQLCOMMENTER_WITH_ROUTE", True)
+ with_app_name = getattr(
+ conf.settings, "SQLCOMMENTER_WITH_APP_NAME", True
+ )
+ with_opentelemetry = getattr(
+ conf.settings, "SQLCOMMENTER_WITH_OPENTELEMETRY", True
+ )
+ with_db_driver = getattr(
+ conf.settings, "SQLCOMMENTER_WITH_DB_DRIVER", True
+ )
+
+ db_driver = context["connection"].settings_dict.get("ENGINE", "")
+ resolver_match = self.request.resolver_match
+
+ sql = _add_sql_comment(
+ sql,
+ # Information about the controller.
+ controller=(
+ resolver_match.view_name
+ if resolver_match and with_controller
+ else None
+ ),
+ # route is the pattern that matched a request with a controller i.e. the regex
+ # See https://docs.djangoproject.com/en/stable/ref/urlresolvers/#django.urls.ResolverMatch.route
+ # getattr() because the attribute doesn't exist in Django < 2.2.
+ route=(
+ getattr(resolver_match, "route", None)
+ if resolver_match and with_route
+ else None
+ ),
+ # app_name is the application namespace for the URL pattern that matches the URL.
+ # See https://docs.djangoproject.com/en/stable/ref/urlresolvers/#django.urls.ResolverMatch.app_name
+ app_name=(
+ (resolver_match.app_name or None)
+ if resolver_match and with_app_name
+ else None
+ ),
+ # Framework centric information.
+ framework=f"django:{_django_version}" if with_framework else None,
+ # Information about the database and driver.
+ db_driver=db_driver if with_db_driver else None,
+ **_get_opentelemetry_values() if with_opentelemetry else {},
+ )
+
+ # TODO: MySQL truncates logs > 1024B so prepend comments
+ # instead of statements, if the engine is MySQL.
+ # See:
+ # * https://github.com/basecamp/marginalia/issues/61
+ # * https://github.com/basecamp/marginalia/pull/80
+
+ # Add the query to the query log if debugging.
+ if isinstance(context["cursor"], CursorDebugWrapper):
+ context["connection"].queries_log.append(sql)
+
+ return execute(sql, params, many, context)