about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/_semconv.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/_semconv.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/_semconv.py')
-rw-r--r--.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/_semconv.py435
1 files changed, 435 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/_semconv.py b/.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/_semconv.py
new file mode 100644
index 00000000..091c8765
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/opentelemetry/instrumentation/_semconv.py
@@ -0,0 +1,435 @@
+# 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.
+
+import os
+import threading
+from enum import Enum
+
+from opentelemetry.instrumentation.utils import http_status_to_status_code
+from opentelemetry.semconv.attributes.client_attributes import (
+    CLIENT_ADDRESS,
+    CLIENT_PORT,
+)
+from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE
+from opentelemetry.semconv.attributes.http_attributes import (
+    HTTP_REQUEST_METHOD,
+    HTTP_REQUEST_METHOD_ORIGINAL,
+    HTTP_RESPONSE_STATUS_CODE,
+    HTTP_ROUTE,
+)
+from opentelemetry.semconv.attributes.network_attributes import (
+    NETWORK_PROTOCOL_VERSION,
+)
+from opentelemetry.semconv.attributes.server_attributes import (
+    SERVER_ADDRESS,
+    SERVER_PORT,
+)
+from opentelemetry.semconv.attributes.url_attributes import (
+    URL_FULL,
+    URL_PATH,
+    URL_QUERY,
+    URL_SCHEME,
+)
+from opentelemetry.semconv.attributes.user_agent_attributes import (
+    USER_AGENT_ORIGINAL,
+)
+from opentelemetry.semconv.trace import SpanAttributes
+from opentelemetry.trace.status import Status, StatusCode
+
+# These lists represent attributes for metrics that are currently supported
+
+_client_duration_attrs_old = [
+    SpanAttributes.HTTP_STATUS_CODE,
+    SpanAttributes.HTTP_HOST,
+    SpanAttributes.NET_PEER_PORT,
+    SpanAttributes.NET_PEER_NAME,
+    SpanAttributes.HTTP_METHOD,
+    SpanAttributes.HTTP_FLAVOR,
+    SpanAttributes.HTTP_SCHEME,
+]
+
+_client_duration_attrs_new = [
+    ERROR_TYPE,
+    HTTP_REQUEST_METHOD,
+    HTTP_RESPONSE_STATUS_CODE,
+    NETWORK_PROTOCOL_VERSION,
+    SERVER_ADDRESS,
+    SERVER_PORT,
+    # TODO: Support opt-in for scheme in new semconv
+    # URL_SCHEME,
+]
+
+_server_duration_attrs_old = [
+    SpanAttributes.HTTP_METHOD,
+    SpanAttributes.HTTP_HOST,
+    SpanAttributes.HTTP_SCHEME,
+    SpanAttributes.HTTP_STATUS_CODE,
+    SpanAttributes.HTTP_FLAVOR,
+    SpanAttributes.HTTP_SERVER_NAME,
+    SpanAttributes.NET_HOST_NAME,
+    SpanAttributes.NET_HOST_PORT,
+]
+
+_server_duration_attrs_new = [
+    ERROR_TYPE,
+    HTTP_REQUEST_METHOD,
+    HTTP_RESPONSE_STATUS_CODE,
+    HTTP_ROUTE,
+    NETWORK_PROTOCOL_VERSION,
+    URL_SCHEME,
+]
+
+_server_active_requests_count_attrs_old = [
+    SpanAttributes.HTTP_METHOD,
+    SpanAttributes.HTTP_HOST,
+    SpanAttributes.HTTP_SCHEME,
+    SpanAttributes.HTTP_FLAVOR,
+    SpanAttributes.HTTP_SERVER_NAME,
+]
+
+_server_active_requests_count_attrs_new = [
+    HTTP_REQUEST_METHOD,
+    URL_SCHEME,
+    # TODO: Support SERVER_ADDRESS AND SERVER_PORT
+]
+
+OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN"
+
+
+class _OpenTelemetryStabilitySignalType:
+    HTTP = "http"
+    DATABASE = "database"
+
+
+class _StabilityMode(Enum):
+    DEFAULT = "default"
+    HTTP = "http"
+    HTTP_DUP = "http/dup"
+    DATABASE = "database"
+    DATABASE_DUP = "database/dup"
+
+
+def _report_new(mode: _StabilityMode):
+    return mode != _StabilityMode.DEFAULT
+
+
+def _report_old(mode: _StabilityMode):
+    return mode not in (_StabilityMode.HTTP, _StabilityMode.DATABASE)
+
+
+class _OpenTelemetrySemanticConventionStability:
+    _initialized = False
+    _lock = threading.Lock()
+    _OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING = {}
+
+    @classmethod
+    def _initialize(cls):
+        with cls._lock:
+            if cls._initialized:
+                return
+
+            # Users can pass in comma delimited string for opt-in options
+            # Only values for http and database stability are supported for now
+            opt_in = os.environ.get(OTEL_SEMCONV_STABILITY_OPT_IN)
+
+            if not opt_in:
+                # early return in case of default
+                cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING = {
+                    _OpenTelemetryStabilitySignalType.HTTP: _StabilityMode.DEFAULT,
+                    _OpenTelemetryStabilitySignalType.DATABASE: _StabilityMode.DEFAULT,
+                }
+                cls._initialized = True
+                return
+
+            opt_in_list = [s.strip() for s in opt_in.split(",")]
+
+            cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[
+                _OpenTelemetryStabilitySignalType.HTTP
+            ] = cls._filter_mode(
+                opt_in_list, _StabilityMode.HTTP, _StabilityMode.HTTP_DUP
+            )
+
+            cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[
+                _OpenTelemetryStabilitySignalType.DATABASE
+            ] = cls._filter_mode(
+                opt_in_list,
+                _StabilityMode.DATABASE,
+                _StabilityMode.DATABASE_DUP,
+            )
+
+            cls._initialized = True
+
+    @staticmethod
+    def _filter_mode(opt_in_list, stable_mode, dup_mode):
+        # Process semconv stability opt-in
+        # http/dup,database/dup has higher precedence over http,database
+        if dup_mode.value in opt_in_list:
+            return dup_mode
+
+        return (
+            stable_mode
+            if stable_mode.value in opt_in_list
+            else _StabilityMode.DEFAULT
+        )
+
+    @classmethod
+    def _get_opentelemetry_stability_opt_in_mode(
+        cls, signal_type: _OpenTelemetryStabilitySignalType
+    ) -> _StabilityMode:
+        # Get OpenTelemetry opt-in mode based off of signal type (http, messaging, etc.)
+        return cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING.get(
+            signal_type, _StabilityMode.DEFAULT
+        )
+
+
+def _filter_semconv_duration_attrs(
+    attrs,
+    old_attrs,
+    new_attrs,
+    sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
+):
+    filtered_attrs = {}
+    # duration is two different metrics depending on sem_conv_opt_in_mode, so no DUP attributes
+    allowed_attributes = (
+        new_attrs if sem_conv_opt_in_mode == _StabilityMode.HTTP else old_attrs
+    )
+    for key, val in attrs.items():
+        if key in allowed_attributes:
+            filtered_attrs[key] = val
+    return filtered_attrs
+
+
+def _filter_semconv_active_request_count_attr(
+    attrs,
+    old_attrs,
+    new_attrs,
+    sem_conv_opt_in_mode=_StabilityMode.DEFAULT,
+):
+    filtered_attrs = {}
+    if _report_old(sem_conv_opt_in_mode):
+        for key, val in attrs.items():
+            if key in old_attrs:
+                filtered_attrs[key] = val
+    if _report_new(sem_conv_opt_in_mode):
+        for key, val in attrs.items():
+            if key in new_attrs:
+                filtered_attrs[key] = val
+    return filtered_attrs
+
+
+def set_string_attribute(result, key, value):
+    if value:
+        result[key] = value
+
+
+def set_int_attribute(result, key, value):
+    if value:
+        try:
+            result[key] = int(value)
+        except ValueError:
+            return
+
+
+def _set_http_method(result, original, normalized, sem_conv_opt_in_mode):
+    original = original.strip()
+    normalized = normalized.strip()
+    # See https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#common-attributes
+    # Method is case sensitive. "http.request.method_original" should not be sanitized or automatically capitalized.
+    if original != normalized and _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, HTTP_REQUEST_METHOD_ORIGINAL, original)
+
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.HTTP_METHOD, normalized)
+    if _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, HTTP_REQUEST_METHOD, normalized)
+
+
+def _set_http_status_code(result, code, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_int_attribute(result, SpanAttributes.HTTP_STATUS_CODE, code)
+    if _report_new(sem_conv_opt_in_mode):
+        set_int_attribute(result, HTTP_RESPONSE_STATUS_CODE, code)
+
+
+def _set_http_url(result, url, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.HTTP_URL, url)
+    if _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, URL_FULL, url)
+
+
+def _set_http_scheme(result, scheme, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.HTTP_SCHEME, scheme)
+    if _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, URL_SCHEME, scheme)
+
+
+def _set_http_flavor_version(result, version, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.HTTP_FLAVOR, version)
+    if _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version)
+
+
+def _set_http_user_agent(result, user_agent, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(
+            result, SpanAttributes.HTTP_USER_AGENT, user_agent
+        )
+    if _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, USER_AGENT_ORIGINAL, user_agent)
+
+
+# Client
+
+
+def _set_http_host_client(result, host, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.HTTP_HOST, host)
+    if _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, SERVER_ADDRESS, host)
+
+
+def _set_http_net_peer_name_client(result, peer_name, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.NET_PEER_NAME, peer_name)
+    if _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, SERVER_ADDRESS, peer_name)
+
+
+def _set_http_peer_port_client(result, port, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_int_attribute(result, SpanAttributes.NET_PEER_PORT, port)
+    if _report_new(sem_conv_opt_in_mode):
+        set_int_attribute(result, SERVER_PORT, port)
+
+
+def _set_http_network_protocol_version(result, version, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.HTTP_FLAVOR, version)
+    if _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version)
+
+
+# Server
+
+
+def _set_http_net_host(result, host, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.NET_HOST_NAME, host)
+    if _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, SERVER_ADDRESS, host)
+
+
+def _set_http_net_host_port(result, port, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_int_attribute(result, SpanAttributes.NET_HOST_PORT, port)
+    if _report_new(sem_conv_opt_in_mode):
+        set_int_attribute(result, SERVER_PORT, port)
+
+
+def _set_http_target(result, target, path, query, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.HTTP_TARGET, target)
+    if _report_new(sem_conv_opt_in_mode):
+        if path:
+            set_string_attribute(result, URL_PATH, path)
+        if query:
+            set_string_attribute(result, URL_QUERY, query)
+
+
+def _set_http_host_server(result, host, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.HTTP_HOST, host)
+    if _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, CLIENT_ADDRESS, host)
+
+
+# net.peer.ip -> net.sock.peer.addr
+# https://github.com/open-telemetry/semantic-conventions/blob/40db676ca0e735aa84f242b5a0fb14e49438b69b/schemas/1.15.0#L18
+# net.sock.peer.addr -> client.socket.address for server spans (TODO) AND client.address if missing
+# https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/CHANGELOG.md#v1210-2023-07-13
+# https://github.com/open-telemetry/semantic-conventions/blob/main/docs/non-normative/http-migration.md#common-attributes-across-http-client-and-server-spans
+def _set_http_peer_ip_server(result, ip, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.NET_PEER_IP, ip)
+    if _report_new(sem_conv_opt_in_mode):
+        # Only populate if not already populated
+        if not result.get(CLIENT_ADDRESS):
+            set_string_attribute(result, CLIENT_ADDRESS, ip)
+
+
+def _set_http_peer_port_server(result, port, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_int_attribute(result, SpanAttributes.NET_PEER_PORT, port)
+    if _report_new(sem_conv_opt_in_mode):
+        set_int_attribute(result, CLIENT_PORT, port)
+
+
+def _set_http_net_peer_name_server(result, name, sem_conv_opt_in_mode):
+    if _report_old(sem_conv_opt_in_mode):
+        set_string_attribute(result, SpanAttributes.NET_PEER_NAME, name)
+    if _report_new(sem_conv_opt_in_mode):
+        set_string_attribute(result, CLIENT_ADDRESS, name)
+
+
+def _set_status(
+    span,
+    metrics_attributes: dict,
+    status_code: int,
+    status_code_str: str,
+    server_span: bool = True,
+    sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT,
+):
+    if status_code < 0:
+        if _report_new(sem_conv_opt_in_mode):
+            metrics_attributes[ERROR_TYPE] = status_code_str
+        if span.is_recording():
+            if _report_new(sem_conv_opt_in_mode):
+                span.set_attribute(ERROR_TYPE, status_code_str)
+            span.set_status(
+                Status(
+                    StatusCode.ERROR,
+                    "Non-integer HTTP status: " + status_code_str,
+                )
+            )
+    else:
+        status = http_status_to_status_code(
+            status_code, server_span=server_span
+        )
+
+        if _report_old(sem_conv_opt_in_mode):
+            if span.is_recording():
+                span.set_attribute(
+                    SpanAttributes.HTTP_STATUS_CODE, status_code
+                )
+            metrics_attributes[SpanAttributes.HTTP_STATUS_CODE] = status_code
+        if _report_new(sem_conv_opt_in_mode):
+            if span.is_recording():
+                span.set_attribute(HTTP_RESPONSE_STATUS_CODE, status_code)
+            metrics_attributes[HTTP_RESPONSE_STATUS_CODE] = status_code
+            if status == StatusCode.ERROR:
+                if span.is_recording():
+                    span.set_attribute(ERROR_TYPE, status_code_str)
+                metrics_attributes[ERROR_TYPE] = status_code_str
+        if span.is_recording():
+            span.set_status(Status(status))
+
+
+# Get schema version based off of opt-in mode
+def _get_schema_url(mode: _StabilityMode) -> str:
+    if mode is _StabilityMode.DEFAULT:
+        return "https://opentelemetry.io/schemas/1.11.0"
+    return SpanAttributes.SCHEMA_URL