From b94c5906fd9cc723ba81da965f89ae73264ec835 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 17 Jun 2024 09:20:17 -0700 Subject: [PATCH] Use generated symbols from semantic conventions package (#2611) --- CHANGELOG.md | 2 + .../instrumentation/flask/__init__.py | 8 +- .../tests/test_programmatic.py | 6 +- .../instrumentation/requests/__init__.py | 38 +++---- .../tests/test_requests_integration.py | 100 +++++++++--------- .../instrumentation/wsgi/__init__.py | 14 +-- .../tests/test_wsgi_middleware.py | 72 +++++++------ .../opentelemetry/instrumentation/_semconv.py | 93 ++++++++-------- 8 files changed, 172 insertions(+), 161 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05199a98a4..bbbf49f453 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2572](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2572)) - `opentelemetry-instrumentation-aiohttp-server`, `opentelemetry-instrumentation-httpx` Ensure consistently use of suppress_instrumentation utils ([#2590](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2590)) +- Reference symbols from generated semantic conventions + ([#2611](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2611)) ## Version 1.25.0/0.46b0 (2024-05-31) diff --git a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py index f2e0ee34cc..34e9b5ea50 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -251,7 +251,6 @@ def response_hook(span: Span, status: str, response_headers: List): import opentelemetry.instrumentation.wsgi as otel_wsgi from opentelemetry import context, trace from opentelemetry.instrumentation._semconv import ( - _METRIC_ATTRIBUTES_SERVER_DURATION_NAME, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, @@ -268,6 +267,9 @@ def response_hook(span: Span, status: str, response_headers: List): from opentelemetry.instrumentation.utils import _start_internal_or_server_span from opentelemetry.metrics import get_meter from opentelemetry.semconv.metrics import MetricInstruments +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_SERVER_REQUEST_DURATION, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.util.http import ( get_excluded_urls, @@ -553,7 +555,7 @@ def __init__(self, *args, **kwargs): duration_histogram_new = None if _report_new(_InstrumentedFlask._sem_conv_opt_in_mode): duration_histogram_new = meter.create_histogram( - name=_METRIC_ATTRIBUTES_SERVER_DURATION_NAME, + name=HTTP_SERVER_REQUEST_DURATION, unit="s", description="measures the duration of the inbound HTTP request", ) @@ -684,7 +686,7 @@ def instrument_app( duration_histogram_new = None if _report_new(sem_conv_opt_in_mode): duration_histogram_new = meter.create_histogram( - name=_METRIC_ATTRIBUTES_SERVER_DURATION_NAME, + name=HTTP_SERVER_REQUEST_DURATION, unit="s", description="measures the duration of the inbound HTTP request", ) diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index d30a100b0e..f50d3245a0 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -20,7 +20,6 @@ from opentelemetry import trace from opentelemetry.instrumentation._semconv import ( - _SPAN_ATTRIBUTES_ERROR_TYPE, OTEL_SEMCONV_STABILITY_OPT_IN, _OpenTelemetrySemanticConventionStability, _server_active_requests_count_attrs_new, @@ -40,6 +39,7 @@ NumberDataPoint, ) from opentelemetry.sdk.resources import Resource +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.wsgitestutil import WsgiTestBase from opentelemetry.util.http import ( @@ -379,7 +379,7 @@ def test_internal_error_new_semconv(self): SpanAttributes.URL_PATH: "/hello/500", SpanAttributes.HTTP_ROUTE: "/hello/", SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 500, - _SPAN_ATTRIBUTES_ERROR_TYPE: "500", + ERROR_TYPE: "500", SpanAttributes.URL_SCHEME: "http", } ) @@ -405,7 +405,7 @@ def test_internal_error_both_semconv(self): { SpanAttributes.URL_PATH: "/hello/500", SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 500, - _SPAN_ATTRIBUTES_ERROR_TYPE: "500", + ERROR_TYPE: "500", SpanAttributes.URL_SCHEME: "http", } ) diff --git a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py index 8c54482a46..18cc3e767c 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -59,10 +59,6 @@ from requests.structures import CaseInsensitiveDict from opentelemetry.instrumentation._semconv import ( - _METRIC_ATTRIBUTES_CLIENT_DURATION_NAME, - _SPAN_ATTRIBUTES_ERROR_TYPE, - _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS, - _SPAN_ATTRIBUTES_NETWORK_PEER_PORT, _client_duration_attrs_new, _client_duration_attrs_old, _filter_semconv_duration_attrs, @@ -91,7 +87,15 @@ ) from opentelemetry.metrics import Histogram, get_meter from opentelemetry.propagate import inject +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PEER_ADDRESS, + NETWORK_PEER_PORT, +) from opentelemetry.semconv.metrics import MetricInstruments +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_CLIENT_REQUEST_DURATION, +) from opentelemetry.trace import SpanKind, Tracer, get_tracer from opentelemetry.trace.span import Span from opentelemetry.trace.status import StatusCode @@ -191,9 +195,7 @@ def get_or_create_headers(): sem_conv_opt_in_mode, ) # Use semconv library when available - span_attributes[_SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS] = ( - parsed_url.hostname - ) + span_attributes[NETWORK_PEER_ADDRESS] = parsed_url.hostname if parsed_url.port: _set_http_peer_port_client( metric_labels, parsed_url.port, sem_conv_opt_in_mode @@ -203,9 +205,7 @@ def get_or_create_headers(): span_attributes, parsed_url.port, sem_conv_opt_in_mode ) # Use semconv library when available - span_attributes[_SPAN_ATTRIBUTES_NETWORK_PEER_PORT] = ( - parsed_url.port - ) + span_attributes[NETWORK_PEER_PORT] = parsed_url.port except ValueError: pass @@ -250,12 +250,8 @@ def get_or_create_headers(): _report_new(sem_conv_opt_in_mode) and status_code is StatusCode.ERROR ): - span_attributes[_SPAN_ATTRIBUTES_ERROR_TYPE] = str( - result.status_code - ) - metric_labels[_SPAN_ATTRIBUTES_ERROR_TYPE] = str( - result.status_code - ) + span_attributes[ERROR_TYPE] = str(result.status_code) + metric_labels[ERROR_TYPE] = str(result.status_code) if result.raw is not None: version = getattr(result.raw, "version", None) @@ -278,12 +274,8 @@ def get_or_create_headers(): response_hook(span, request, result) if exception is not None and _report_new(sem_conv_opt_in_mode): - span.set_attribute( - _SPAN_ATTRIBUTES_ERROR_TYPE, type(exception).__qualname__ - ) - metric_labels[_SPAN_ATTRIBUTES_ERROR_TYPE] = type( - exception - ).__qualname__ + span.set_attribute(ERROR_TYPE, type(exception).__qualname__) + metric_labels[ERROR_TYPE] = type(exception).__qualname__ if duration_histogram_old is not None: duration_attrs_old = _filter_semconv_duration_attrs( @@ -403,7 +395,7 @@ def _instrument(self, **kwargs): duration_histogram_new = None if _report_new(semconv_opt_in_mode): duration_histogram_new = meter.create_histogram( - name=_METRIC_ATTRIBUTES_CLIENT_DURATION_NAME, + name=HTTP_CLIENT_REQUEST_DURATION, unit="s", description="Duration of HTTP client requests.", ) diff --git a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py index d85d70e20e..75518fc8d3 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py +++ b/instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py @@ -23,9 +23,6 @@ import opentelemetry.instrumentation.requests from opentelemetry import trace from opentelemetry.instrumentation._semconv import ( - _SPAN_ATTRIBUTES_ERROR_TYPE, - _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS, - _SPAN_ATTRIBUTES_NETWORK_PEER_PORT, OTEL_SEMCONV_STABILITY_OPT_IN, _OpenTelemetrySemanticConventionStability, ) @@ -36,6 +33,21 @@ ) from opentelemetry.propagate import get_global_textmap, set_global_textmap from opentelemetry.sdk import resources +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, +) +from opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PEER_ADDRESS, + NETWORK_PEER_PORT, + NETWORK_PROTOCOL_VERSION, +) +from opentelemetry.semconv.attributes.server_attributes import ( + SERVER_ADDRESS, + SERVER_PORT, +) +from opentelemetry.semconv.attributes.url_attributes import URL_FULL from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.mock_textmap import MockTextMapPropagator from opentelemetry.test.test_base import TestBase @@ -176,14 +188,14 @@ def test_basic_new_semconv(self): self.assertEqual( span.attributes, { - SpanAttributes.HTTP_REQUEST_METHOD: "GET", - SpanAttributes.URL_FULL: url_with_port, - SpanAttributes.SERVER_ADDRESS: "mock", - _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS: "mock", - SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 200, - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.1", - SpanAttributes.SERVER_PORT: 80, - _SPAN_ATTRIBUTES_NETWORK_PEER_PORT: 80, + HTTP_REQUEST_METHOD: "GET", + URL_FULL: url_with_port, + SERVER_ADDRESS: "mock", + NETWORK_PEER_ADDRESS: "mock", + HTTP_RESPONSE_STATUS_CODE: 200, + NETWORK_PROTOCOL_VERSION: "1.1", + SERVER_PORT: 80, + NETWORK_PEER_PORT: 80, }, ) @@ -213,19 +225,19 @@ def test_basic_both_semconv(self): span.attributes, { SpanAttributes.HTTP_METHOD: "GET", - SpanAttributes.HTTP_REQUEST_METHOD: "GET", + HTTP_REQUEST_METHOD: "GET", SpanAttributes.HTTP_URL: url_with_port, - SpanAttributes.URL_FULL: url_with_port, + URL_FULL: url_with_port, SpanAttributes.HTTP_HOST: "mock", - SpanAttributes.SERVER_ADDRESS: "mock", - _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS: "mock", + SERVER_ADDRESS: "mock", + NETWORK_PEER_ADDRESS: "mock", SpanAttributes.NET_PEER_PORT: 80, SpanAttributes.HTTP_STATUS_CODE: 200, - SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 200, + HTTP_RESPONSE_STATUS_CODE: 200, SpanAttributes.HTTP_FLAVOR: "1.1", - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.1", - SpanAttributes.SERVER_PORT: 80, - _SPAN_ATTRIBUTES_NETWORK_PEER_PORT: 80, + NETWORK_PROTOCOL_VERSION: "1.1", + SERVER_PORT: 80, + NETWORK_PEER_PORT: 80, }, ) @@ -328,12 +340,8 @@ def test_not_foundbasic_new_semconv(self): span = self.assert_span() - self.assertEqual( - span.attributes.get(SpanAttributes.HTTP_RESPONSE_STATUS_CODE), 404 - ) - self.assertEqual( - span.attributes.get(_SPAN_ATTRIBUTES_ERROR_TYPE), "404" - ) + self.assertEqual(span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 404) + self.assertEqual(span.attributes.get(ERROR_TYPE), "404") self.assertIs( span.status.status_code, @@ -355,12 +363,8 @@ def test_not_foundbasic_both_semconv(self): self.assertEqual( span.attributes.get(SpanAttributes.HTTP_STATUS_CODE), 404 ) - self.assertEqual( - span.attributes.get(SpanAttributes.HTTP_RESPONSE_STATUS_CODE), 404 - ) - self.assertEqual( - span.attributes.get(_SPAN_ATTRIBUTES_ERROR_TYPE), "404" - ) + self.assertEqual(span.attributes.get(HTTP_RESPONSE_STATUS_CODE), 404) + self.assertEqual(span.attributes.get(ERROR_TYPE), "404") self.assertIs( span.status.status_code, @@ -527,13 +531,13 @@ def test_requests_exception_new_semconv(self, *_, **__): self.assertEqual( span.attributes, { - SpanAttributes.HTTP_REQUEST_METHOD: "GET", - SpanAttributes.URL_FULL: url_with_port, - SpanAttributes.SERVER_ADDRESS: "mock", - SpanAttributes.SERVER_PORT: 80, - _SPAN_ATTRIBUTES_NETWORK_PEER_PORT: 80, - _SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS: "mock", - _SPAN_ATTRIBUTES_ERROR_TYPE: "RequestException", + HTTP_REQUEST_METHOD: "GET", + URL_FULL: url_with_port, + SERVER_ADDRESS: "mock", + SERVER_PORT: 80, + NETWORK_PEER_PORT: 80, + NETWORK_PEER_ADDRESS: "mock", + ERROR_TYPE: "RequestException", }, ) self.assertEqual(span.status.status_code, StatusCode.ERROR) @@ -724,11 +728,11 @@ def test_basic_metric_new_semconv(self): self.perform_request(self.URL) expected_attributes = { - SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 200, - SpanAttributes.SERVER_ADDRESS: "examplehost", - SpanAttributes.SERVER_PORT: 8000, - SpanAttributes.HTTP_REQUEST_METHOD: "GET", - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.1", + HTTP_RESPONSE_STATUS_CODE: 200, + SERVER_ADDRESS: "examplehost", + SERVER_PORT: 8000, + HTTP_REQUEST_METHOD: "GET", + NETWORK_PROTOCOL_VERSION: "1.1", } for ( resource_metrics @@ -760,11 +764,11 @@ def test_basic_metric_both_semconv(self): } expected_attributes_new = { - SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 200, - SpanAttributes.SERVER_ADDRESS: "examplehost", - SpanAttributes.SERVER_PORT: 8000, - SpanAttributes.HTTP_REQUEST_METHOD: "GET", - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.1", + HTTP_RESPONSE_STATUS_CODE: 200, + SERVER_ADDRESS: "examplehost", + SERVER_PORT: 8000, + HTTP_REQUEST_METHOD: "GET", + NETWORK_PROTOCOL_VERSION: "1.1", } for ( diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py index 810a07e315..6a1883fa7e 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -214,8 +214,6 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he from opentelemetry import context, trace from opentelemetry.instrumentation._semconv import ( - _METRIC_ATTRIBUTES_SERVER_DURATION_NAME, - _SPAN_ATTRIBUTES_ERROR_TYPE, _filter_semconv_active_request_count_attr, _filter_semconv_duration_attrs, _get_schema_url, @@ -244,7 +242,11 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he from opentelemetry.instrumentation.wsgi.version import __version__ from opentelemetry.metrics import get_meter from opentelemetry.propagators.textmap import Getter +from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE from opentelemetry.semconv.metrics import MetricInstruments +from opentelemetry.semconv.metrics.http_metrics import ( + HTTP_SERVER_REQUEST_DURATION, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace.status import Status, StatusCode from opentelemetry.util.http import ( @@ -573,7 +575,7 @@ def __init__( self.duration_histogram_new = None if _report_new(sem_conv_opt_in_mode): self.duration_histogram_new = self.meter.create_histogram( - name=_METRIC_ATTRIBUTES_SERVER_DURATION_NAME, + name=HTTP_SERVER_REQUEST_DURATION, unit="s", description="measures the duration of the inbound HTTP request", ) @@ -670,11 +672,9 @@ def __call__(self, environ, start_response): return _end_span_after_iterating(iterable, span, token) except Exception as ex: if _report_new(self._sem_conv_opt_in_mode): - req_attrs[_SPAN_ATTRIBUTES_ERROR_TYPE] = type(ex).__qualname__ + req_attrs[ERROR_TYPE] = type(ex).__qualname__ if span.is_recording(): - span.set_attribute( - _SPAN_ATTRIBUTES_ERROR_TYPE, type(ex).__qualname__ - ) + span.set_attribute(ERROR_TYPE, type(ex).__qualname__) span.set_status(Status(StatusCode.ERROR, str(ex))) span.end() if token is not None: diff --git a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py index 2b26cbb5f9..777d19f41d 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py @@ -36,6 +36,23 @@ NumberDataPoint, ) from opentelemetry.sdk.resources import Resource +from opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, +) +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.trace import SpanAttributes from opentelemetry.test.test_base import TestBase from opentelemetry.test.wsgitestutil import WsgiTestBase @@ -237,11 +254,11 @@ def validate_response( SpanAttributes.NET_HOST_NAME: "127.0.0.1", } expected_attributes_new = { - SpanAttributes.SERVER_PORT: 80, - SpanAttributes.SERVER_ADDRESS: "127.0.0.1", - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.0", - SpanAttributes.HTTP_RESPONSE_STATUS_CODE: 200, - SpanAttributes.URL_SCHEME: "http", + SERVER_PORT: 80, + SERVER_ADDRESS: "127.0.0.1", + NETWORK_PROTOCOL_VERSION: "1.0", + HTTP_RESPONSE_STATUS_CODE: 200, + URL_SCHEME: "http", } if old_sem_conv: expected_attributes.update(expected_attributes_old) @@ -253,9 +270,7 @@ def validate_response( if old_sem_conv: expected_attributes[SpanAttributes.HTTP_METHOD] = http_method if new_sem_conv: - expected_attributes[SpanAttributes.HTTP_REQUEST_METHOD] = ( - http_method - ) + expected_attributes[HTTP_REQUEST_METHOD] = http_method self.assertEqual(span_list[0].attributes, expected_attributes) def test_basic_wsgi_call(self): @@ -517,13 +532,13 @@ def test_request_attributes_new_semconv(self): self.assertDictEqual( attrs, { - SpanAttributes.HTTP_REQUEST_METHOD: "GET", - SpanAttributes.SERVER_ADDRESS: "127.0.0.1", - SpanAttributes.SERVER_PORT: 80, - SpanAttributes.NETWORK_PROTOCOL_VERSION: "1.0", - SpanAttributes.URL_PATH: "/", - SpanAttributes.URL_QUERY: "foo=bar", - SpanAttributes.URL_SCHEME: "http", + HTTP_REQUEST_METHOD: "GET", + SERVER_ADDRESS: "127.0.0.1", + SERVER_PORT: 80, + NETWORK_PROTOCOL_VERSION: "1.0", + URL_PATH: "/", + URL_QUERY: "foo=bar", + URL_SCHEME: "http", }, ) @@ -543,11 +558,10 @@ def validate_url( SpanAttributes.HTTP_SERVER_NAME: parts.hostname, # Not true in the general case, but for all tests. } expected_new = { - SpanAttributes.SERVER_PORT: parts.port - or (80 if parts.scheme == "http" else 443), - SpanAttributes.SERVER_ADDRESS: parts.hostname, - SpanAttributes.URL_PATH: parts.path, - SpanAttributes.URL_QUERY: parts.query, + SERVER_PORT: parts.port or (80 if parts.scheme == "http" else 443), + SERVER_ADDRESS: parts.hostname, + URL_PATH: parts.path, + URL_QUERY: parts.query, } if old_semconv: if raw: @@ -560,17 +574,15 @@ def validate_url( expected_old[SpanAttributes.HTTP_HOST] = parts.hostname if new_semconv: if raw: - expected_new[SpanAttributes.URL_PATH] = expected_url.split( - parts.path, 1 - )[1] + expected_new[URL_PATH] = expected_url.split(parts.path, 1)[1] if parts.query: - expected_new[SpanAttributes.URL_QUERY] = ( - expected_url.split(parts.query, 1)[1] - ) + expected_new[URL_QUERY] = expected_url.split( + parts.query, 1 + )[1] else: - expected_new[SpanAttributes.HTTP_URL] = expected_url + expected_new[URL_FULL] = expected_url if has_host: - expected_new[SpanAttributes.SERVER_ADDRESS] = parts.hostname + expected_new[SERVER_ADDRESS] = parts.hostname attrs = otel_wsgi.collect_request_attributes(self.environ) self.assertGreaterEqual( @@ -720,8 +732,8 @@ def test_request_attributes_with_full_request_uri(self): SpanAttributes.HTTP_TARGET: "http://docs.python.org:80/3/library/urllib.parse.html?highlight=params#url-parsing", } expected_new = { - SpanAttributes.URL_PATH: "/3/library/urllib.parse.html", - SpanAttributes.URL_QUERY: "highlight=params", + URL_PATH: "/3/library/urllib.parse.html", + URL_QUERY: "highlight=params", } self.assertGreaterEqual( otel_wsgi.collect_request_attributes(self.environ).items(), diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index efe3c75f70..baa06ff99b 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -17,16 +17,27 @@ from enum import Enum from opentelemetry.instrumentation.utils import http_status_to_status_code +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_SCHEME, +) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace.status import Status, StatusCode -# TODO: will come through semconv package once updated -_SPAN_ATTRIBUTES_ERROR_TYPE = "error.type" -_SPAN_ATTRIBUTES_NETWORK_PEER_ADDRESS = "network.peer.address" -_SPAN_ATTRIBUTES_NETWORK_PEER_PORT = "network.peer.port" -_METRIC_ATTRIBUTES_CLIENT_DURATION_NAME = "http.client.request.duration" -_METRIC_ATTRIBUTES_SERVER_DURATION_NAME = "http.server.request.duration" - _client_duration_attrs_old = [ SpanAttributes.HTTP_STATUS_CODE, SpanAttributes.HTTP_HOST, @@ -38,14 +49,14 @@ ] _client_duration_attrs_new = [ - _SPAN_ATTRIBUTES_ERROR_TYPE, - SpanAttributes.HTTP_REQUEST_METHOD, - SpanAttributes.HTTP_RESPONSE_STATUS_CODE, - SpanAttributes.NETWORK_PROTOCOL_VERSION, - SpanAttributes.SERVER_ADDRESS, - SpanAttributes.SERVER_PORT, + 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 - # SpanAttributes.URL_SCHEME, + # URL_SCHEME, ] _server_duration_attrs_old = [ @@ -60,12 +71,12 @@ ] _server_duration_attrs_new = [ - _SPAN_ATTRIBUTES_ERROR_TYPE, - SpanAttributes.HTTP_REQUEST_METHOD, - SpanAttributes.HTTP_RESPONSE_STATUS_CODE, - SpanAttributes.HTTP_ROUTE, - SpanAttributes.NETWORK_PROTOCOL_VERSION, - SpanAttributes.URL_SCHEME, + ERROR_TYPE, + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, + HTTP_ROUTE, + NETWORK_PROTOCOL_VERSION, + URL_SCHEME, ] _server_active_requests_count_attrs_old = [ @@ -79,8 +90,8 @@ ] _server_active_requests_count_attrs_new = [ - SpanAttributes.HTTP_REQUEST_METHOD, - SpanAttributes.URL_SCHEME, + HTTP_REQUEST_METHOD, + URL_SCHEME, ] OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN" @@ -202,46 +213,40 @@ def _set_http_method(result, original, normalized, sem_conv_opt_in_mode): # 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, SpanAttributes.HTTP_REQUEST_METHOD_ORIGINAL, original - ) + 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, SpanAttributes.HTTP_REQUEST_METHOD, normalized - ) + 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, SpanAttributes.HTTP_RESPONSE_STATUS_CODE, code - ) + 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, SpanAttributes.URL_FULL, url) + 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, SpanAttributes.URL_SCHEME, scheme) + set_string_attribute(result, URL_SCHEME, scheme) def _set_http_host(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, SpanAttributes.SERVER_ADDRESS, host) + set_string_attribute(result, SERVER_ADDRESS, host) # Client @@ -251,23 +256,21 @@ 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, SpanAttributes.SERVER_ADDRESS, peer_name) + 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, SpanAttributes.SERVER_PORT, port) + 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, SpanAttributes.NETWORK_PROTOCOL_VERSION, version - ) + set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version) # Server @@ -347,8 +350,8 @@ def _set_status( ): if status_code < 0: if _report_new(sem_conv_opt_in_mode): - span.set_attribute(_SPAN_ATTRIBUTES_ERROR_TYPE, status_code_str) - metrics_attributes[_SPAN_ATTRIBUTES_ERROR_TYPE] = status_code_str + span.set_attribute(ERROR_TYPE, status_code_str) + metrics_attributes[ERROR_TYPE] = status_code_str span.set_status( Status( @@ -370,12 +373,8 @@ def _set_status( status_code ) if status == StatusCode.ERROR: - span.set_attribute( - _SPAN_ATTRIBUTES_ERROR_TYPE, status_code_str - ) - metrics_attributes[_SPAN_ATTRIBUTES_ERROR_TYPE] = ( - status_code_str - ) + span.set_attribute(ERROR_TYPE, status_code_str) + metrics_attributes[ERROR_TYPE] = status_code_str span.set_status(Status(status))