From 7e5d7fd0fd68ca330409fc824f8ac1a0161d283d Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 27 Aug 2024 17:36:04 +0200 Subject: [PATCH 01/10] add OTEL_ENABLE_SERVER_ATTRIBUTES_FOR_REQUEST_DURATION flag to add server.address and server.port for http.server.request.duration --- .../instrumentation/asgi/__init__.py | 16 ++--- .../django/middleware/otel_middleware.py | 47 ++++-------- .../instrumentation/falcon/__init__.py | 14 +++- .../instrumentation/flask/__init__.py | 13 ++-- .../tests/test_programmatic.py | 56 ++++++++++----- .../instrumentation/pyramid/callbacks.py | 12 +++- .../instrumentation/requests/__init__.py | 12 +--- .../instrumentation/urllib/__init__.py | 13 +--- .../instrumentation/urllib3/__init__.py | 13 +--- .../instrumentation/wsgi/__init__.py | 47 ++++-------- .../opentelemetry/instrumentation/_semconv.py | 72 +++++++++++++++++-- 11 files changed, 171 insertions(+), 144 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index d25ca41017..eb16e8bd6c 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -202,18 +202,14 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A from opentelemetry import context, trace from opentelemetry.instrumentation._semconv import ( - _filter_semconv_active_request_count_attr, - _filter_semconv_duration_attrs, + _filter_semconv_active_server_request_count_attr, + _filter_semconv_server_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, _report_old, - _server_active_requests_count_attrs_new, - _server_active_requests_count_attrs_old, - _server_duration_attrs_new, - _server_duration_attrs_old, _set_http_flavor_version, _set_http_host_server, _set_http_method, @@ -962,10 +958,8 @@ async def otel_send(message: dict[str, Any]): def _parse_duration_attrs( req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT ): - return _filter_semconv_duration_attrs( + return _filter_semconv_server_duration_attrs( req_attrs, - _server_duration_attrs_old, - _server_duration_attrs_new, sem_conv_opt_in_mode, ) @@ -973,9 +967,7 @@ def _parse_duration_attrs( def _parse_active_request_count_attrs( req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT ): - return _filter_semconv_active_request_count_attr( + return _filter_semconv_active_server_request_count_attr( req_attrs, - _server_active_requests_count_attrs_old, - _server_active_requests_count_attrs_new, sem_conv_opt_in_mode, ) diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py index 667d6f1091..c6e6428cdc 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py @@ -23,15 +23,11 @@ from opentelemetry.context import detach from opentelemetry.instrumentation._semconv import ( - _filter_semconv_active_request_count_attr, - _filter_semconv_duration_attrs, + _filter_semconv_active_server_request_count_attr, + _filter_semconv_server_duration_attrs, _HTTPStabilityMode, _report_new, _report_old, - _server_active_requests_count_attrs_new, - _server_active_requests_count_attrs_old, - _server_duration_attrs_new, - _server_duration_attrs_old, ) from opentelemetry.instrumentation.propagators import ( get_global_response_propagator, @@ -224,9 +220,11 @@ def process_request(self, request): attributes=attributes, ) - active_requests_count_attrs = _parse_active_request_count_attrs( - attributes, - self._sem_conv_opt_in_mode, + active_requests_count_attrs = ( + _filter_semconv_active_server_request_count_attr( + attributes, + self._sem_conv_opt_in_mode, + ) ) request.META[self._environ_active_request_attr_key] = ( @@ -424,8 +422,8 @@ def process_response(self, request, response): if request_start_time is not None: duration_s = default_timer() - request_start_time if self._duration_histogram_old: - duration_attrs_old = _parse_duration_attrs( - duration_attrs, _HTTPStabilityMode.DEFAULT + duration_attrs_old = _filter_semconv_server_duration_attrs( + duration_attrs, ) # http.target to be included in old semantic conventions target = duration_attrs.get(SpanAttributes.HTTP_TARGET) @@ -435,8 +433,9 @@ def process_response(self, request, response): max(round(duration_s * 1000), 0), duration_attrs_old ) if self._duration_histogram_new: - duration_attrs_new = _parse_duration_attrs( - duration_attrs, _HTTPStabilityMode.HTTP + duration_attrs_new = _filter_semconv_server_duration_attrs( + duration_attrs, + _HTTPStabilityMode.HTTP, ) self._duration_histogram_new.record( max(duration_s, 0), duration_attrs_new @@ -447,25 +446,3 @@ def process_response(self, request, response): request.META.pop(self._environ_token) return response - - -def _parse_duration_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT -): - return _filter_semconv_duration_attrs( - req_attrs, - _server_duration_attrs_old, - _server_duration_attrs_new, - sem_conv_opt_in_mode, - ) - - -def _parse_active_request_count_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT -): - return _filter_semconv_active_request_count_attr( - req_attrs, - _server_active_requests_count_attrs_old, - _server_active_requests_count_attrs_new, - sem_conv_opt_in_mode, - ) diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py index 2dce5f1ef5..cc8d81b1ec 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -193,6 +193,11 @@ def response_hook(span, req, resp): import opentelemetry.instrumentation.wsgi as otel_wsgi from opentelemetry import context, trace +from opentelemetry.instrumentation._semconv import ( + _filter_semconv_active_server_request_count_attr, + _filter_semconv_server_duration_attrs, + _HTTPStabilityMode, +) from opentelemetry.instrumentation.falcon.package import _instruments from opentelemetry.instrumentation.falcon.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor @@ -347,9 +352,14 @@ def __call__(self, env, start_response): ) attributes = otel_wsgi.collect_request_attributes(env) active_requests_count_attrs = ( - otel_wsgi._parse_active_request_count_attrs(attributes) + _filter_semconv_active_server_request_count_attr( + attributes, + _HTTPStabilityMode.DEFAULT, + ) + ) + duration_attrs = _filter_semconv_server_duration_attrs( + attributes, ) - duration_attrs = otel_wsgi._parse_duration_attrs(attributes) self.active_requests_counter.add(1, active_requests_count_attrs) if span.is_recording(): 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 192e044655..2f7f7311f5 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -251,6 +251,8 @@ 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 ( + _filter_semconv_active_server_request_count_attr, + _filter_semconv_server_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, @@ -334,7 +336,7 @@ def _wrapped_app(wrapped_app_environ, start_response): wrapped_app_environ, sem_conv_opt_in_mode ) active_requests_count_attrs = ( - otel_wsgi._parse_active_request_count_attrs( + _filter_semconv_active_server_request_count_attr( attributes, sem_conv_opt_in_mode, ) @@ -390,8 +392,8 @@ def _start_response(status, response_headers, *args, **kwargs): result = wsgi_app(wrapped_app_environ, _start_response) duration_s = default_timer() - start if duration_histogram_old: - duration_attrs_old = otel_wsgi._parse_duration_attrs( - attributes, _HTTPStabilityMode.DEFAULT + duration_attrs_old = _filter_semconv_server_duration_attrs( + attributes, ) if request_route: @@ -404,8 +406,9 @@ def _start_response(status, response_headers, *args, **kwargs): max(round(duration_s * 1000), 0), duration_attrs_old ) if duration_histogram_new: - duration_attrs_new = otel_wsgi._parse_duration_attrs( - attributes, _HTTPStabilityMode.HTTP + duration_attrs_new = _filter_semconv_server_duration_attrs( + attributes, + _HTTPStabilityMode.HTTP, ) if request_route: diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index 4458daae21..7e9aef8bbd 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -23,8 +23,10 @@ OTEL_SEMCONV_STABILITY_OPT_IN, _OpenTelemetrySemanticConventionStability, _server_active_requests_count_attrs_new, + _server_active_requests_count_attrs_new_with_server_attributes, _server_active_requests_count_attrs_old, _server_duration_attrs_new, + _server_duration_attrs_new_with_server_attributes, _server_duration_attrs_old, ) from opentelemetry.instrumentation.flask import FlaskInstrumentor @@ -104,8 +106,8 @@ def expected_attributes_new(override_attributes): "http.server.duration": _server_duration_attrs_old_copy, } _recommended_metrics_attrs_new = { - "http.server.active_requests": _server_active_requests_count_attrs_new, - "http.server.request.duration": _server_duration_attrs_new_copy, + "http.server.active_requests": _server_active_requests_count_attrs_new_with_server_attributes, + "http.server.request.duration": _server_duration_attrs_new_with_server_attributes, } _server_active_requests_count_attrs_both = ( _server_active_requests_count_attrs_old @@ -138,6 +140,8 @@ def setUp(self): "os.environ", { "OTEL_PYTHON_FLASK_EXCLUDED_URLS": "http://localhost/env_excluded_arg/123,env_excluded_noarg", + "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED": "true", + "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED": "true", OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, }, ) @@ -514,22 +518,25 @@ def test_flask_metrics_new_semconv(self): self.assertTrue(len(scope_metric.metrics) != 0) for metric in scope_metric.metrics: self.assertIn(metric.name, _expected_metric_names_new) - data_points = list(metric.data.data_points) - self.assertEqual(len(data_points), 1) - for point in data_points: - if isinstance(point, HistogramDataPoint): - self.assertEqual(point.count, 3) - self.assertAlmostEqual( - duration_s, point.sum, places=2 - ) - histogram_data_point_seen = True - if isinstance(point, NumberDataPoint): - number_data_point_seen = True - for attr in point.attributes: - self.assertIn( - attr, - _recommended_metrics_attrs_new[metric.name], - ) + with self.subTest(metric=metric.name): + data_points = list(metric.data.data_points) + self.assertEqual(len(data_points), 1) + for point in data_points: + if isinstance(point, HistogramDataPoint): + self.assertEqual(point.count, 3) + self.assertAlmostEqual( + duration_s, point.sum, places=2 + ) + histogram_data_point_seen = True + if isinstance(point, NumberDataPoint): + number_data_point_seen = True + for attr in point.attributes: + self.assertIn( + attr, + _recommended_metrics_attrs_new[ + metric.name + ], + ) self.assertTrue(number_data_point_seen and histogram_data_point_seen) def test_flask_metric_values(self): @@ -601,14 +608,19 @@ def test_basic_metric_success_new_semconv(self): self.client.get("/hello/756") expected_duration_attributes = { "http.request.method": "GET", + "http.route": "/hello/", "url.scheme": "http", "http.route": "/hello/", "network.protocol.version": "1.1", "http.response.status_code": 200, + "server.address": "localhost", + "server.port": 80, } expected_requests_count_attributes = { "http.request.method": "GET", "url.scheme": "http", + "server.address": "localhost", + "server.port": 80, } self._assert_basic_metric( expected_duration_attributes, @@ -646,10 +658,14 @@ def test_basic_metric_nonstandard_http_method_success_new_semconv(self): "url.scheme": "http", "network.protocol.version": "1.1", "http.response.status_code": 405, + "server.address": "localhost", + "server.port": 80, } expected_requests_count_attributes = { "http.request.method": "_OTHER", "url.scheme": "http", + "server.address": "localhost", + "server.port": 80, } self._assert_basic_metric( expected_duration_attributes, @@ -671,10 +687,14 @@ def test_basic_metric_nonstandard_http_method_allowed_success_new_semconv( "url.scheme": "http", "network.protocol.version": "1.1", "http.response.status_code": 405, + "server.address": "localhost", + "server.port": 80, } expected_requests_count_attributes = { "http.request.method": "NONSTANDARD", "url.scheme": "http", + "server.address": "localhost", + "server.port": 80, } self._assert_basic_metric( expected_duration_attributes, diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index 6a526f2235..2e0c69b216 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -23,6 +23,10 @@ import opentelemetry.instrumentation.wsgi as otel_wsgi from opentelemetry import context, trace +from opentelemetry.instrumentation._semconv import ( + _filter_semconv_active_server_request_count_attr, + _filter_semconv_server_duration_attrs, +) from opentelemetry.instrumentation.propagators import ( get_global_response_propagator, ) @@ -172,9 +176,13 @@ def trace_tween(request): request.environ[_ENVIRON_ENABLED_KEY] = True request.environ[_ENVIRON_STARTTIME_KEY] = time_ns() active_requests_count_attrs = ( - otel_wsgi._parse_active_request_count_attrs(attributes) + _filter_semconv_active_server_request_count_attr( + attributes, + ) + ) + duration_attrs = _filter_semconv_server_duration_attrs( + attributes, ) - duration_attrs = otel_wsgi._parse_duration_attrs(attributes) start = default_timer() active_requests_counter.add(1, active_requests_count_attrs) 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 db67d378d9..2e128bf82b 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -83,9 +83,7 @@ def response_hook(span, request_obj, response) from requests.structures import CaseInsensitiveDict from opentelemetry.instrumentation._semconv import ( - _client_duration_attrs_new, - _client_duration_attrs_old, - _filter_semconv_duration_attrs, + _filter_semconv_client_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, @@ -308,10 +306,8 @@ def get_or_create_headers(): metric_labels[ERROR_TYPE] = type(exception).__qualname__ if duration_histogram_old is not None: - duration_attrs_old = _filter_semconv_duration_attrs( + duration_attrs_old = _filter_semconv_client_duration_attrs( metric_labels, - _client_duration_attrs_old, - _client_duration_attrs_new, _HTTPStabilityMode.DEFAULT, ) duration_histogram_old.record( @@ -319,10 +315,8 @@ def get_or_create_headers(): attributes=duration_attrs_old, ) if duration_histogram_new is not None: - duration_attrs_new = _filter_semconv_duration_attrs( + duration_attrs_new = _filter_semconv_client_duration_attrs( metric_labels, - _client_duration_attrs_old, - _client_duration_attrs_new, _HTTPStabilityMode.HTTP, ) duration_histogram_new.record( diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py index d9072ba727..8c1241a091 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py @@ -86,9 +86,7 @@ def response_hook(span, request_obj, response) ) from opentelemetry.instrumentation._semconv import ( - _client_duration_attrs_new, - _client_duration_attrs_old, - _filter_semconv_duration_attrs, + _filter_semconv_client_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, @@ -303,16 +301,11 @@ def _instrumented_open_call( span.set_attribute(ERROR_TYPE, type(exception).__qualname__) labels[ERROR_TYPE] = type(exception).__qualname__ - duration_attrs_old = _filter_semconv_duration_attrs( + duration_attrs_old = _filter_semconv_client_duration_attrs( labels, - _client_duration_attrs_old, - _client_duration_attrs_new, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, ) - duration_attrs_new = _filter_semconv_duration_attrs( + duration_attrs_new = _filter_semconv_client_duration_attrs( labels, - _client_duration_attrs_old, - _client_duration_attrs_new, sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP, ) diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py index 1c83f3f447..c0c46205bf 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py @@ -94,9 +94,7 @@ def response_hook( import wrapt from opentelemetry.instrumentation._semconv import ( - _client_duration_attrs_new, - _client_duration_attrs_old, - _filter_semconv_duration_attrs, + _filter_semconv_client_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, @@ -523,17 +521,12 @@ def _filter_attributes_semconv( duration_attrs_old = None duration_attrs_new = None if _report_old(sem_conv_opt_in_mode): - duration_attrs_old = _filter_semconv_duration_attrs( + duration_attrs_old = _filter_semconv_client_duration_attrs( metric_attributes, - _client_duration_attrs_old, - _client_duration_attrs_new, - _HTTPStabilityMode.DEFAULT, ) if _report_new(sem_conv_opt_in_mode): - duration_attrs_new = _filter_semconv_duration_attrs( + duration_attrs_new = _filter_semconv_client_duration_attrs( metric_attributes, - _client_duration_attrs_old, - _client_duration_attrs_new, _HTTPStabilityMode.HTTP, ) 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 c0384d594b..5610fabb6e 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -214,18 +214,14 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he from opentelemetry import context, trace from opentelemetry.instrumentation._semconv import ( - _filter_semconv_active_request_count_attr, - _filter_semconv_duration_attrs, + _filter_semconv_active_server_request_count_attr, + _filter_semconv_server_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, _report_old, - _server_active_requests_count_attrs_new, - _server_active_requests_count_attrs_old, - _server_duration_attrs_new, - _server_duration_attrs_old, _set_http_flavor_version, _set_http_method, _set_http_net_host, @@ -448,28 +444,6 @@ def _parse_status_code(resp_status): return None -def _parse_active_request_count_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT -): - return _filter_semconv_active_request_count_attr( - req_attrs, - _server_active_requests_count_attrs_old, - _server_active_requests_count_attrs_new, - sem_conv_opt_in_mode, - ) - - -def _parse_duration_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT -): - return _filter_semconv_duration_attrs( - req_attrs, - _server_duration_attrs_old, - _server_duration_attrs_new, - sem_conv_opt_in_mode, - ) - - def add_response_attributes( span, start_response_status, @@ -631,9 +605,11 @@ def __call__(self, environ, start_response): req_attrs = collect_request_attributes( environ, self._sem_conv_opt_in_mode ) - active_requests_count_attrs = _parse_active_request_count_attrs( - req_attrs, - self._sem_conv_opt_in_mode, + active_requests_count_attrs = ( + _filter_semconv_active_server_request_count_attr( + req_attrs, + self._sem_conv_opt_in_mode, + ) ) span, token = _start_internal_or_server_span( @@ -684,15 +660,16 @@ def __call__(self, environ, start_response): finally: duration_s = default_timer() - start if self.duration_histogram_old: - duration_attrs_old = _parse_duration_attrs( - req_attrs, _HTTPStabilityMode.DEFAULT + duration_attrs_old = _filter_semconv_server_duration_attrs( + req_attrs, ) self.duration_histogram_old.record( max(round(duration_s * 1000), 0), duration_attrs_old ) if self.duration_histogram_new: - duration_attrs_new = _parse_duration_attrs( - req_attrs, _HTTPStabilityMode.HTTP + duration_attrs_new = _filter_semconv_server_duration_attrs( + req_attrs, + _HTTPStabilityMode.HTTP, ) self.duration_histogram_new.record( max(duration_s, 0), duration_attrs_new diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index c4e720fd04..8ac6d9c6a2 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -90,6 +90,17 @@ URL_SCHEME, ] +_server_duration_attrs_new_with_server_attributes = [ + ERROR_TYPE, + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, + HTTP_ROUTE, + NETWORK_PROTOCOL_VERSION, + URL_SCHEME, + SERVER_ADDRESS, + SERVER_PORT, +] + _server_active_requests_count_attrs_old = [ SpanAttributes.HTTP_METHOD, SpanAttributes.HTTP_HOST, @@ -101,7 +112,13 @@ _server_active_requests_count_attrs_new = [ HTTP_REQUEST_METHOD, URL_SCHEME, - # TODO: Support SERVER_ADDRESS AND SERVER_PORT +] + +_server_active_requests_count_attrs_new_with_server_attributes = [ + HTTP_REQUEST_METHOD, + URL_SCHEME, + SERVER_ADDRESS, + SERVER_PORT, ] OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN" @@ -154,6 +171,23 @@ def _initialize(cls): _OpenTelemetrySemanticConventionStability._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[ _OpenTelemetryStabilitySignalType.HTTP ] = http_opt_in + + _OpenTelemetrySemanticConventionStability.server_duration_attrs_new_effective = ( + _server_duration_attrs_new_with_server_attributes + if os.environ.get( + "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED" + ) + else _server_duration_attrs_new + ) + + _OpenTelemetrySemanticConventionStability.server_active_requests_count_attrs_new_effective = ( + _server_active_requests_count_attrs_new_with_server_attributes + if os.environ.get( + "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED" + ) + else _server_active_requests_count_attrs_new + ) + _OpenTelemetrySemanticConventionStability._initialized = True @classmethod @@ -167,6 +201,30 @@ def _get_opentelemetry_stability_opt_in_mode( ) +def _filter_semconv_client_duration_attrs( + attrs, + sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, +): + return _filter_semconv_duration_attrs( + attrs, + _client_duration_attrs_old, + _client_duration_attrs_new, + sem_conv_opt_in_mode, + ) + + +def _filter_semconv_server_duration_attrs( + attrs, + sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, +): + return _filter_semconv_duration_attrs( + attrs, + _server_duration_attrs_old, + _OpenTelemetrySemanticConventionStability.server_duration_attrs_new_effective, + sem_conv_opt_in_mode, + ) + + def _filter_semconv_duration_attrs( attrs, old_attrs, @@ -186,20 +244,22 @@ def _filter_semconv_duration_attrs( return filtered_attrs -def _filter_semconv_active_request_count_attr( +def _filter_semconv_active_server_request_count_attr( attrs, - old_attrs, - new_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, ): + filtered_attrs = {} if _report_old(sem_conv_opt_in_mode): for key, val in attrs.items(): - if key in old_attrs: + if key in _server_active_requests_count_attrs_old: filtered_attrs[key] = val if _report_new(sem_conv_opt_in_mode): for key, val in attrs.items(): - if key in new_attrs: + if ( + key + in _OpenTelemetrySemanticConventionStability.server_active_requests_count_attrs_new_effective + ): filtered_attrs[key] = val return filtered_attrs From 885d0a5fd41a064c31bfc0ce1074cf655ee1633f Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 27 Aug 2024 17:50:14 +0200 Subject: [PATCH 02/10] add changelog --- CHANGELOG.md | 7 +++++++ .../tests/test_programmatic.py | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07510f643c..3578f4a28e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Add `OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED` flag to add + `server.address` and `server.port` for `http.server.request.duration` +- Add `OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED` flag to add + `server.address` and `server.port` for `http.server.active_requests` + ## Version 1.27.0/0.48b0 () ### Added diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index 7e9aef8bbd..96afbcd5a5 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -608,7 +608,6 @@ def test_basic_metric_success_new_semconv(self): self.client.get("/hello/756") expected_duration_attributes = { "http.request.method": "GET", - "http.route": "/hello/", "url.scheme": "http", "http.route": "/hello/", "network.protocol.version": "1.1", From fdcd334c6777e3cf90ed0a56f25101311da85ab5 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 3 Sep 2024 16:47:13 +0200 Subject: [PATCH 03/10] explicit parameter --- .../instrumentation/django/middleware/otel_middleware.py | 1 + .../src/opentelemetry/instrumentation/falcon/__init__.py | 1 + .../src/opentelemetry/instrumentation/flask/__init__.py | 1 + .../src/opentelemetry/instrumentation/pyramid/callbacks.py | 2 ++ .../src/opentelemetry/instrumentation/wsgi/__init__.py | 1 + .../src/opentelemetry/instrumentation/_semconv.py | 2 +- 6 files changed, 7 insertions(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py index c6e6428cdc..4ca807aaee 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py @@ -424,6 +424,7 @@ def process_response(self, request, response): if self._duration_histogram_old: duration_attrs_old = _filter_semconv_server_duration_attrs( duration_attrs, + _HTTPStabilityMode.DEFAULT, ) # http.target to be included in old semantic conventions target = duration_attrs.get(SpanAttributes.HTTP_TARGET) diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py index cc8d81b1ec..8a891c032d 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -359,6 +359,7 @@ def __call__(self, env, start_response): ) duration_attrs = _filter_semconv_server_duration_attrs( attributes, + _HTTPStabilityMode.DEFAULT, ) self.active_requests_counter.add(1, active_requests_count_attrs) 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 2f7f7311f5..fec375ebd9 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -394,6 +394,7 @@ def _start_response(status, response_headers, *args, **kwargs): if duration_histogram_old: duration_attrs_old = _filter_semconv_server_duration_attrs( attributes, + _HTTPStabilityMode.DEFAULT, ) if request_route: diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index 2e0c69b216..a441839b55 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -26,6 +26,7 @@ from opentelemetry.instrumentation._semconv import ( _filter_semconv_active_server_request_count_attr, _filter_semconv_server_duration_attrs, + _HTTPStabilityMode, ) from opentelemetry.instrumentation.propagators import ( get_global_response_propagator, @@ -182,6 +183,7 @@ def trace_tween(request): ) duration_attrs = _filter_semconv_server_duration_attrs( attributes, + _HTTPStabilityMode.DEFAULT, ) start = default_timer() 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 5610fabb6e..7fc5512c82 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -662,6 +662,7 @@ def __call__(self, environ, start_response): if self.duration_histogram_old: duration_attrs_old = _filter_semconv_server_duration_attrs( req_attrs, + _HTTPStabilityMode.DEFAULT, ) self.duration_histogram_old.record( max(round(duration_s * 1000), 0), duration_attrs_old diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index 8ac6d9c6a2..a5f0a22dda 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -215,7 +215,7 @@ def _filter_semconv_client_duration_attrs( def _filter_semconv_server_duration_attrs( attrs, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, + sem_conv_opt_in_mode, ): return _filter_semconv_duration_attrs( attrs, From 935b64fd62ef22572797acd80362682da87b2d72 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 3 Sep 2024 18:02:07 +0200 Subject: [PATCH 04/10] pr review --- .../tests/test_programmatic.py | 41 ++++++++++++------- .../opentelemetry/instrumentation/_semconv.py | 18 ++++---- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index 96afbcd5a5..582917f6e8 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -23,10 +23,8 @@ OTEL_SEMCONV_STABILITY_OPT_IN, _OpenTelemetrySemanticConventionStability, _server_active_requests_count_attrs_new, - _server_active_requests_count_attrs_new_with_server_attributes, _server_active_requests_count_attrs_old, _server_duration_attrs_new, - _server_duration_attrs_new_with_server_attributes, _server_duration_attrs_old, ) from opentelemetry.instrumentation.flask import FlaskInstrumentor @@ -106,8 +104,8 @@ def expected_attributes_new(override_attributes): "http.server.duration": _server_duration_attrs_old_copy, } _recommended_metrics_attrs_new = { - "http.server.active_requests": _server_active_requests_count_attrs_new_with_server_attributes, - "http.server.request.duration": _server_duration_attrs_new_with_server_attributes, + "http.server.active_requests": _server_active_requests_count_attrs_new, + "http.server.request.duration": _server_duration_attrs_new_copy, } _server_active_requests_count_attrs_both = ( _server_active_requests_count_attrs_old @@ -140,8 +138,6 @@ def setUp(self): "os.environ", { "OTEL_PYTHON_FLASK_EXCLUDED_URLS": "http://localhost/env_excluded_arg/123,env_excluded_noarg", - "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED": "true", - "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED": "true", OTEL_SEMCONV_STABILITY_OPT_IN: sem_conv_mode, }, ) @@ -605,6 +601,31 @@ def test_basic_metric_success(self): ) def test_basic_metric_success_new_semconv(self): + self.client.get("/hello/756") + expected_duration_attributes = { + "http.request.method": "GET", + "url.scheme": "http", + "http.route": "/hello/", + "network.protocol.version": "1.1", + "http.response.status_code": 200, + } + expected_requests_count_attributes = { + "http.request.method": "GET", + "url.scheme": "http", + } + self._assert_basic_metric( + expected_duration_attributes, + expected_requests_count_attributes, + ) + + @patch.dict( + "os.environ", + { + "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED": "true", + "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED": "true", + }, + ) + def test_basic_metric_success_new_semconv_server_address(self): self.client.get("/hello/756") expected_duration_attributes = { "http.request.method": "GET", @@ -657,14 +678,10 @@ def test_basic_metric_nonstandard_http_method_success_new_semconv(self): "url.scheme": "http", "network.protocol.version": "1.1", "http.response.status_code": 405, - "server.address": "localhost", - "server.port": 80, } expected_requests_count_attributes = { "http.request.method": "_OTHER", "url.scheme": "http", - "server.address": "localhost", - "server.port": 80, } self._assert_basic_metric( expected_duration_attributes, @@ -686,14 +703,10 @@ def test_basic_metric_nonstandard_http_method_allowed_success_new_semconv( "url.scheme": "http", "network.protocol.version": "1.1", "http.response.status_code": 405, - "server.address": "localhost", - "server.port": 80, } expected_requests_count_attributes = { "http.request.method": "NONSTANDARD", "url.scheme": "http", - "server.address": "localhost", - "server.port": 80, } self._assert_basic_metric( expected_duration_attributes, diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index a5f0a22dda..79316dd91a 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -90,16 +90,14 @@ URL_SCHEME, ] -_server_duration_attrs_new_with_server_attributes = [ - ERROR_TYPE, - HTTP_REQUEST_METHOD, - HTTP_RESPONSE_STATUS_CODE, - HTTP_ROUTE, - NETWORK_PROTOCOL_VERSION, - URL_SCHEME, - SERVER_ADDRESS, - SERVER_PORT, -] +_server_duration_attrs_new_with_server_attributes = ( + _server_duration_attrs_new.extend( + [ + SERVER_ADDRESS, + SERVER_PORT, + ] + ) +) _server_active_requests_count_attrs_old = [ SpanAttributes.HTTP_METHOD, From e7e9b65155598e59eac0dcb92afb1a618411d86a Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 5 Sep 2024 10:48:01 +0200 Subject: [PATCH 05/10] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3578f4a28e..f85e5d593f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED` flag to add `server.address` and `server.port` for `http.server.request.duration` + ([#2597](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2597)) - Add `OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED` flag to add `server.address` and `server.port` for `http.server.active_requests` + ([#2597](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2597)) ## Version 1.27.0/0.48b0 () From e024655736175e3707d78738aecf4a539fe11707 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 5 Sep 2024 11:04:42 +0200 Subject: [PATCH 06/10] pr review --- .../src/opentelemetry/instrumentation/_semconv.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index 79316dd91a..6291526cb6 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -91,12 +91,11 @@ ] _server_duration_attrs_new_with_server_attributes = ( - _server_duration_attrs_new.extend( - [ - SERVER_ADDRESS, - SERVER_PORT, - ] - ) + _server_duration_attrs_new + + [ + SERVER_ADDRESS, + SERVER_PORT, + ] ) _server_active_requests_count_attrs_old = [ From f02358eb3c194a3b4e50481f6d89c6e76ceb2b3c Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 10 Sep 2024 14:28:42 +0200 Subject: [PATCH 07/10] try out to store state in the instrumentation --- .../instrumentation/asgi/__init__.py | 52 +++++++++++-------- .../opentelemetry/instrumentation/_semconv.py | 20 +++++++ 2 files changed, 51 insertions(+), 21 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index eb16e8bd6c..0b172ce3c8 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -202,14 +202,18 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A from opentelemetry import context, trace from opentelemetry.instrumentation._semconv import ( - _filter_semconv_active_server_request_count_attr, - _filter_semconv_server_duration_attrs, + _filter_semconv_active_request_count_attr, + _filter_semconv_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, _report_old, + _server_active_requests_count_attrs_new_effective, + _server_active_requests_count_attrs_old, + _server_duration_attrs_new_effective, + _server_duration_attrs_old, _set_http_flavor_version, _set_http_host_server, _set_http_method, @@ -551,6 +555,10 @@ def __init__( sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( _OpenTelemetryStabilitySignalType.HTTP, ) + self.server_active_requests_count_attrs_new = ( + _server_active_requests_count_attrs_new_effective + ) + self.server_duration_attrs_new = _server_duration_attrs_new_effective self.app = guarantee_single_callable(app) self.tracer = ( trace.get_tracer( @@ -694,7 +702,7 @@ async def __call__( context_getter=asgi_getter, attributes=attributes, ) - active_requests_count_attrs = _parse_active_request_count_attrs( + active_requests_count_attrs = self._parse_active_request_count_attrs( attributes, self._sem_conv_opt_in_mode, ) @@ -750,12 +758,12 @@ async def __call__( self._sem_conv_opt_in_mode, ) duration_s = default_timer() - start - duration_attrs_old = _parse_duration_attrs( + duration_attrs_old = self._parse_duration_attrs( attributes, _HTTPStabilityMode.DEFAULT ) if target: duration_attrs_old[SpanAttributes.HTTP_TARGET] = target - duration_attrs_new = _parse_duration_attrs( + duration_attrs_new = self._parse_duration_attrs( attributes, _HTTPStabilityMode.HTTP ) if self.duration_histogram_old: @@ -954,20 +962,22 @@ async def otel_send(message: dict[str, Any]): return otel_send + def _parse_duration_attrs( + self, req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT + ): + return _filter_semconv_duration_attrs( + req_attrs, + _server_duration_attrs_old, + self.server_duration_attrs_new, + sem_conv_opt_in_mode, + ) -def _parse_duration_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT -): - return _filter_semconv_server_duration_attrs( - req_attrs, - sem_conv_opt_in_mode, - ) - - -def _parse_active_request_count_attrs( - req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT -): - return _filter_semconv_active_server_request_count_attr( - req_attrs, - sem_conv_opt_in_mode, - ) + def _parse_active_request_count_attrs( + self, req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT + ): + return _filter_semconv_active_request_count_attr( + req_attrs, + _server_active_requests_count_attrs_old, + self.server_active_requests_count_attrs_new, + sem_conv_opt_in_mode, + ) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index 6291526cb6..70d22cf5a6 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -261,6 +261,26 @@ def _filter_semconv_active_server_request_count_attr( return filtered_attrs +def _server_active_requests_count_attrs_new_effective(): + return ( + _server_active_requests_count_attrs_new_with_server_attributes + if os.environ.get( + "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED" + ) + else _server_active_requests_count_attrs_new + ) + + +def _server_duration_attrs_new_effective(): + return ( + _server_duration_attrs_new_with_server_attributes + if os.environ.get( + "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED" + ) + else _server_duration_attrs_new + ) + + def set_string_attribute(result, key, value): if value: result[key] = value From 36373e4e4057ea997b82c5734a5572be890cc7d4 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 11 Sep 2024 17:47:41 +0200 Subject: [PATCH 08/10] pr review --- .../instrumentation/asgi/__init__.py | 48 ++++----- .../django/middleware/otel_middleware.py | 48 ++++++--- .../instrumentation/falcon/__init__.py | 15 +-- .../instrumentation/flask/__init__.py | 14 +-- .../instrumentation/pyramid/callbacks.py | 14 +-- .../instrumentation/requests/__init__.py | 12 ++- .../instrumentation/urllib/__init__.py | 13 ++- .../instrumentation/urllib3/__init__.py | 13 ++- .../instrumentation/wsgi/__init__.py | 48 ++++++--- .../opentelemetry/instrumentation/_semconv.py | 102 +++++------------- 10 files changed, 159 insertions(+), 168 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index 0b172ce3c8..f0a8dd818e 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -555,10 +555,6 @@ def __init__( sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( _OpenTelemetryStabilitySignalType.HTTP, ) - self.server_active_requests_count_attrs_new = ( - _server_active_requests_count_attrs_new_effective - ) - self.server_duration_attrs_new = _server_duration_attrs_new_effective self.app = guarantee_single_callable(app) self.tracer = ( trace.get_tracer( @@ -702,7 +698,7 @@ async def __call__( context_getter=asgi_getter, attributes=attributes, ) - active_requests_count_attrs = self._parse_active_request_count_attrs( + active_requests_count_attrs = _parse_active_request_count_attrs( attributes, self._sem_conv_opt_in_mode, ) @@ -758,12 +754,12 @@ async def __call__( self._sem_conv_opt_in_mode, ) duration_s = default_timer() - start - duration_attrs_old = self._parse_duration_attrs( + duration_attrs_old = _parse_duration_attrs( attributes, _HTTPStabilityMode.DEFAULT ) if target: duration_attrs_old[SpanAttributes.HTTP_TARGET] = target - duration_attrs_new = self._parse_duration_attrs( + duration_attrs_new = _parse_duration_attrs( attributes, _HTTPStabilityMode.HTTP ) if self.duration_histogram_old: @@ -962,22 +958,24 @@ async def otel_send(message: dict[str, Any]): return otel_send - def _parse_duration_attrs( - self, req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT - ): - return _filter_semconv_duration_attrs( - req_attrs, - _server_duration_attrs_old, - self.server_duration_attrs_new, - sem_conv_opt_in_mode, - ) - def _parse_active_request_count_attrs( - self, req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT - ): - return _filter_semconv_active_request_count_attr( - req_attrs, - _server_active_requests_count_attrs_old, - self.server_active_requests_count_attrs_new, - sem_conv_opt_in_mode, - ) +def _parse_duration_attrs( + req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +): + return _filter_semconv_duration_attrs( + req_attrs, + _server_duration_attrs_old, + _server_duration_attrs_new_effective, + sem_conv_opt_in_mode, + ) + + +def _parse_active_request_count_attrs( + req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +): + return _filter_semconv_active_request_count_attr( + req_attrs, + _server_active_requests_count_attrs_old, + _server_active_requests_count_attrs_new_effective, + sem_conv_opt_in_mode, + ) diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py index 4ca807aaee..84ccdda544 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py @@ -23,11 +23,15 @@ from opentelemetry.context import detach from opentelemetry.instrumentation._semconv import ( - _filter_semconv_active_server_request_count_attr, - _filter_semconv_server_duration_attrs, + _filter_semconv_active_request_count_attr, + _filter_semconv_duration_attrs, _HTTPStabilityMode, _report_new, _report_old, + _server_active_requests_count_attrs_new_effective, + _server_active_requests_count_attrs_old, + _server_duration_attrs_new_effective, + _server_duration_attrs_old, ) from opentelemetry.instrumentation.propagators import ( get_global_response_propagator, @@ -220,11 +224,9 @@ def process_request(self, request): attributes=attributes, ) - active_requests_count_attrs = ( - _filter_semconv_active_server_request_count_attr( - attributes, - self._sem_conv_opt_in_mode, - ) + active_requests_count_attrs = _parse_active_request_count_attrs( + attributes, + self._sem_conv_opt_in_mode, ) request.META[self._environ_active_request_attr_key] = ( @@ -422,9 +424,8 @@ def process_response(self, request, response): if request_start_time is not None: duration_s = default_timer() - request_start_time if self._duration_histogram_old: - duration_attrs_old = _filter_semconv_server_duration_attrs( - duration_attrs, - _HTTPStabilityMode.DEFAULT, + duration_attrs_old = _parse_duration_attrs( + duration_attrs, _HTTPStabilityMode.DEFAULT ) # http.target to be included in old semantic conventions target = duration_attrs.get(SpanAttributes.HTTP_TARGET) @@ -434,9 +435,8 @@ def process_response(self, request, response): max(round(duration_s * 1000), 0), duration_attrs_old ) if self._duration_histogram_new: - duration_attrs_new = _filter_semconv_server_duration_attrs( - duration_attrs, - _HTTPStabilityMode.HTTP, + duration_attrs_new = _parse_duration_attrs( + duration_attrs, _HTTPStabilityMode.HTTP ) self._duration_histogram_new.record( max(duration_s, 0), duration_attrs_new @@ -447,3 +447,25 @@ def process_response(self, request, response): request.META.pop(self._environ_token) return response + + +def _parse_duration_attrs( + req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +): + return _filter_semconv_duration_attrs( + req_attrs, + _server_duration_attrs_old, + _server_duration_attrs_new_effective, + sem_conv_opt_in_mode, + ) + + +def _parse_active_request_count_attrs( + req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +): + return _filter_semconv_active_request_count_attr( + req_attrs, + _server_active_requests_count_attrs_old, + _server_active_requests_count_attrs_new_effective, + sem_conv_opt_in_mode, + ) diff --git a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py index 8a891c032d..2dce5f1ef5 100644 --- a/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-falcon/src/opentelemetry/instrumentation/falcon/__init__.py @@ -193,11 +193,6 @@ def response_hook(span, req, resp): import opentelemetry.instrumentation.wsgi as otel_wsgi from opentelemetry import context, trace -from opentelemetry.instrumentation._semconv import ( - _filter_semconv_active_server_request_count_attr, - _filter_semconv_server_duration_attrs, - _HTTPStabilityMode, -) from opentelemetry.instrumentation.falcon.package import _instruments from opentelemetry.instrumentation.falcon.version import __version__ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor @@ -352,15 +347,9 @@ def __call__(self, env, start_response): ) attributes = otel_wsgi.collect_request_attributes(env) active_requests_count_attrs = ( - _filter_semconv_active_server_request_count_attr( - attributes, - _HTTPStabilityMode.DEFAULT, - ) - ) - duration_attrs = _filter_semconv_server_duration_attrs( - attributes, - _HTTPStabilityMode.DEFAULT, + otel_wsgi._parse_active_request_count_attrs(attributes) ) + duration_attrs = otel_wsgi._parse_duration_attrs(attributes) self.active_requests_counter.add(1, active_requests_count_attrs) if span.is_recording(): 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 fec375ebd9..192e044655 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py @@ -251,8 +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 ( - _filter_semconv_active_server_request_count_attr, - _filter_semconv_server_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, @@ -336,7 +334,7 @@ def _wrapped_app(wrapped_app_environ, start_response): wrapped_app_environ, sem_conv_opt_in_mode ) active_requests_count_attrs = ( - _filter_semconv_active_server_request_count_attr( + otel_wsgi._parse_active_request_count_attrs( attributes, sem_conv_opt_in_mode, ) @@ -392,9 +390,8 @@ def _start_response(status, response_headers, *args, **kwargs): result = wsgi_app(wrapped_app_environ, _start_response) duration_s = default_timer() - start if duration_histogram_old: - duration_attrs_old = _filter_semconv_server_duration_attrs( - attributes, - _HTTPStabilityMode.DEFAULT, + duration_attrs_old = otel_wsgi._parse_duration_attrs( + attributes, _HTTPStabilityMode.DEFAULT ) if request_route: @@ -407,9 +404,8 @@ def _start_response(status, response_headers, *args, **kwargs): max(round(duration_s * 1000), 0), duration_attrs_old ) if duration_histogram_new: - duration_attrs_new = _filter_semconv_server_duration_attrs( - attributes, - _HTTPStabilityMode.HTTP, + duration_attrs_new = otel_wsgi._parse_duration_attrs( + attributes, _HTTPStabilityMode.HTTP ) if request_route: diff --git a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py index a441839b55..6a526f2235 100644 --- a/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py +++ b/instrumentation/opentelemetry-instrumentation-pyramid/src/opentelemetry/instrumentation/pyramid/callbacks.py @@ -23,11 +23,6 @@ import opentelemetry.instrumentation.wsgi as otel_wsgi from opentelemetry import context, trace -from opentelemetry.instrumentation._semconv import ( - _filter_semconv_active_server_request_count_attr, - _filter_semconv_server_duration_attrs, - _HTTPStabilityMode, -) from opentelemetry.instrumentation.propagators import ( get_global_response_propagator, ) @@ -177,14 +172,9 @@ def trace_tween(request): request.environ[_ENVIRON_ENABLED_KEY] = True request.environ[_ENVIRON_STARTTIME_KEY] = time_ns() active_requests_count_attrs = ( - _filter_semconv_active_server_request_count_attr( - attributes, - ) - ) - duration_attrs = _filter_semconv_server_duration_attrs( - attributes, - _HTTPStabilityMode.DEFAULT, + otel_wsgi._parse_active_request_count_attrs(attributes) ) + duration_attrs = otel_wsgi._parse_duration_attrs(attributes) start = default_timer() active_requests_counter.add(1, active_requests_count_attrs) 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 2e128bf82b..db67d378d9 100644 --- a/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py @@ -83,7 +83,9 @@ def response_hook(span, request_obj, response) from requests.structures import CaseInsensitiveDict from opentelemetry.instrumentation._semconv import ( - _filter_semconv_client_duration_attrs, + _client_duration_attrs_new, + _client_duration_attrs_old, + _filter_semconv_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, @@ -306,8 +308,10 @@ def get_or_create_headers(): metric_labels[ERROR_TYPE] = type(exception).__qualname__ if duration_histogram_old is not None: - duration_attrs_old = _filter_semconv_client_duration_attrs( + duration_attrs_old = _filter_semconv_duration_attrs( metric_labels, + _client_duration_attrs_old, + _client_duration_attrs_new, _HTTPStabilityMode.DEFAULT, ) duration_histogram_old.record( @@ -315,8 +319,10 @@ def get_or_create_headers(): attributes=duration_attrs_old, ) if duration_histogram_new is not None: - duration_attrs_new = _filter_semconv_client_duration_attrs( + duration_attrs_new = _filter_semconv_duration_attrs( metric_labels, + _client_duration_attrs_old, + _client_duration_attrs_new, _HTTPStabilityMode.HTTP, ) duration_histogram_new.record( diff --git a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py index 8c1241a091..d9072ba727 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py @@ -86,7 +86,9 @@ def response_hook(span, request_obj, response) ) from opentelemetry.instrumentation._semconv import ( - _filter_semconv_client_duration_attrs, + _client_duration_attrs_new, + _client_duration_attrs_old, + _filter_semconv_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, @@ -301,11 +303,16 @@ def _instrumented_open_call( span.set_attribute(ERROR_TYPE, type(exception).__qualname__) labels[ERROR_TYPE] = type(exception).__qualname__ - duration_attrs_old = _filter_semconv_client_duration_attrs( + duration_attrs_old = _filter_semconv_duration_attrs( labels, + _client_duration_attrs_old, + _client_duration_attrs_new, + sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, ) - duration_attrs_new = _filter_semconv_client_duration_attrs( + duration_attrs_new = _filter_semconv_duration_attrs( labels, + _client_duration_attrs_old, + _client_duration_attrs_new, sem_conv_opt_in_mode=_HTTPStabilityMode.HTTP, ) diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py index c0c46205bf..1c83f3f447 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py @@ -94,7 +94,9 @@ def response_hook( import wrapt from opentelemetry.instrumentation._semconv import ( - _filter_semconv_client_duration_attrs, + _client_duration_attrs_new, + _client_duration_attrs_old, + _filter_semconv_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, @@ -521,12 +523,17 @@ def _filter_attributes_semconv( duration_attrs_old = None duration_attrs_new = None if _report_old(sem_conv_opt_in_mode): - duration_attrs_old = _filter_semconv_client_duration_attrs( + duration_attrs_old = _filter_semconv_duration_attrs( metric_attributes, + _client_duration_attrs_old, + _client_duration_attrs_new, + _HTTPStabilityMode.DEFAULT, ) if _report_new(sem_conv_opt_in_mode): - duration_attrs_new = _filter_semconv_client_duration_attrs( + duration_attrs_new = _filter_semconv_duration_attrs( metric_attributes, + _client_duration_attrs_old, + _client_duration_attrs_new, _HTTPStabilityMode.HTTP, ) 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 7fc5512c82..9c5e1ed160 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -214,14 +214,18 @@ def response_hook(span: Span, environ: WSGIEnvironment, status: str, response_he from opentelemetry import context, trace from opentelemetry.instrumentation._semconv import ( - _filter_semconv_active_server_request_count_attr, - _filter_semconv_server_duration_attrs, + _filter_semconv_active_request_count_attr, + _filter_semconv_duration_attrs, _get_schema_url, _HTTPStabilityMode, _OpenTelemetrySemanticConventionStability, _OpenTelemetryStabilitySignalType, _report_new, _report_old, + _server_active_requests_count_attrs_new_effective, + _server_active_requests_count_attrs_old, + _server_duration_attrs_new_effective, + _server_duration_attrs_old, _set_http_flavor_version, _set_http_method, _set_http_net_host, @@ -444,6 +448,28 @@ def _parse_status_code(resp_status): return None +def _parse_active_request_count_attrs( + req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +): + return _filter_semconv_active_request_count_attr( + req_attrs, + _server_active_requests_count_attrs_old, + _server_active_requests_count_attrs_new_effective, + sem_conv_opt_in_mode, + ) + + +def _parse_duration_attrs( + req_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT +): + return _filter_semconv_duration_attrs( + req_attrs, + _server_duration_attrs_old, + _server_duration_attrs_new_effective, + sem_conv_opt_in_mode, + ) + + def add_response_attributes( span, start_response_status, @@ -605,11 +631,9 @@ def __call__(self, environ, start_response): req_attrs = collect_request_attributes( environ, self._sem_conv_opt_in_mode ) - active_requests_count_attrs = ( - _filter_semconv_active_server_request_count_attr( - req_attrs, - self._sem_conv_opt_in_mode, - ) + active_requests_count_attrs = _parse_active_request_count_attrs( + req_attrs, + self._sem_conv_opt_in_mode, ) span, token = _start_internal_or_server_span( @@ -660,17 +684,15 @@ def __call__(self, environ, start_response): finally: duration_s = default_timer() - start if self.duration_histogram_old: - duration_attrs_old = _filter_semconv_server_duration_attrs( - req_attrs, - _HTTPStabilityMode.DEFAULT, + duration_attrs_old = _parse_duration_attrs( + req_attrs, _HTTPStabilityMode.DEFAULT ) self.duration_histogram_old.record( max(round(duration_s * 1000), 0), duration_attrs_old ) if self.duration_histogram_new: - duration_attrs_new = _filter_semconv_server_duration_attrs( - req_attrs, - _HTTPStabilityMode.HTTP, + duration_attrs_new = _parse_duration_attrs( + req_attrs, _HTTPStabilityMode.HTTP ) self.duration_histogram_new.record( max(duration_s, 0), duration_attrs_new diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index 70d22cf5a6..d481698d34 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -111,12 +111,29 @@ URL_SCHEME, ] -_server_active_requests_count_attrs_new_with_server_attributes = [ - HTTP_REQUEST_METHOD, - URL_SCHEME, - SERVER_ADDRESS, - SERVER_PORT, -] +_server_active_requests_count_attrs_new_with_server_attributes = ( + _server_active_requests_count_attrs_new + + [ + SERVER_ADDRESS, + SERVER_PORT, + ] +) + +_server_active_requests_count_attrs_new_effective = ( + _server_active_requests_count_attrs_new_with_server_attributes + if os.environ.get( + "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED" + ) + else _server_active_requests_count_attrs_new +) + +_server_duration_attrs_new_effective = ( + _server_duration_attrs_new_with_server_attributes + if os.environ.get( + "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED" + ) + else _server_duration_attrs_new +) OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN" @@ -168,23 +185,6 @@ def _initialize(cls): _OpenTelemetrySemanticConventionStability._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[ _OpenTelemetryStabilitySignalType.HTTP ] = http_opt_in - - _OpenTelemetrySemanticConventionStability.server_duration_attrs_new_effective = ( - _server_duration_attrs_new_with_server_attributes - if os.environ.get( - "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED" - ) - else _server_duration_attrs_new - ) - - _OpenTelemetrySemanticConventionStability.server_active_requests_count_attrs_new_effective = ( - _server_active_requests_count_attrs_new_with_server_attributes - if os.environ.get( - "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED" - ) - else _server_active_requests_count_attrs_new - ) - _OpenTelemetrySemanticConventionStability._initialized = True @classmethod @@ -198,30 +198,6 @@ def _get_opentelemetry_stability_opt_in_mode( ) -def _filter_semconv_client_duration_attrs( - attrs, - sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, -): - return _filter_semconv_duration_attrs( - attrs, - _client_duration_attrs_old, - _client_duration_attrs_new, - sem_conv_opt_in_mode, - ) - - -def _filter_semconv_server_duration_attrs( - attrs, - sem_conv_opt_in_mode, -): - return _filter_semconv_duration_attrs( - attrs, - _server_duration_attrs_old, - _OpenTelemetrySemanticConventionStability.server_duration_attrs_new_effective, - sem_conv_opt_in_mode, - ) - - def _filter_semconv_duration_attrs( attrs, old_attrs, @@ -241,46 +217,24 @@ def _filter_semconv_duration_attrs( return filtered_attrs -def _filter_semconv_active_server_request_count_attr( +def _filter_semconv_active_request_count_attr( attrs, + old_attrs, + new_attrs, sem_conv_opt_in_mode=_HTTPStabilityMode.DEFAULT, ): - filtered_attrs = {} if _report_old(sem_conv_opt_in_mode): for key, val in attrs.items(): - if key in _server_active_requests_count_attrs_old: + 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 _OpenTelemetrySemanticConventionStability.server_active_requests_count_attrs_new_effective - ): + if key in new_attrs: filtered_attrs[key] = val return filtered_attrs -def _server_active_requests_count_attrs_new_effective(): - return ( - _server_active_requests_count_attrs_new_with_server_attributes - if os.environ.get( - "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED" - ) - else _server_active_requests_count_attrs_new - ) - - -def _server_duration_attrs_new_effective(): - return ( - _server_duration_attrs_new_with_server_attributes - if os.environ.get( - "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED" - ) - else _server_duration_attrs_new - ) - - def set_string_attribute(result, key, value): if value: result[key] = value From 4237917a43cb7e5c6546ba3a063ede359d7e0944 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 11 Sep 2024 18:46:46 +0200 Subject: [PATCH 09/10] pr review --- .../instrumentation/asgi/__init__.py | 4 +-- .../django/middleware/otel_middleware.py | 4 +-- .../tests/test_programmatic.py | 6 ++-- .../instrumentation/wsgi/__init__.py | 4 +-- .../opentelemetry/instrumentation/_semconv.py | 33 ++++++++++++------- .../src/opentelemetry/util/http/__init__.py | 7 ++++ 6 files changed, 38 insertions(+), 20 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py index f0a8dd818e..e5fbdee542 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -965,7 +965,7 @@ def _parse_duration_attrs( return _filter_semconv_duration_attrs( req_attrs, _server_duration_attrs_old, - _server_duration_attrs_new_effective, + _server_duration_attrs_new_effective(), sem_conv_opt_in_mode, ) @@ -976,6 +976,6 @@ def _parse_active_request_count_attrs( return _filter_semconv_active_request_count_attr( req_attrs, _server_active_requests_count_attrs_old, - _server_active_requests_count_attrs_new_effective, + _server_active_requests_count_attrs_new_effective(), sem_conv_opt_in_mode, ) diff --git a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py index 84ccdda544..ff308ccf5f 100644 --- a/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py @@ -455,7 +455,7 @@ def _parse_duration_attrs( return _filter_semconv_duration_attrs( req_attrs, _server_duration_attrs_old, - _server_duration_attrs_new_effective, + _server_duration_attrs_new_effective(), sem_conv_opt_in_mode, ) @@ -466,6 +466,6 @@ def _parse_active_request_count_attrs( return _filter_semconv_active_request_count_attr( req_attrs, _server_active_requests_count_attrs_old, - _server_active_requests_count_attrs_new_effective, + _server_active_requests_count_attrs_new_effective(), sem_conv_opt_in_mode, ) diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index 582917f6e8..5b7af0471a 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -46,6 +46,8 @@ OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, + OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED, + OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED, OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS, get_excluded_urls, ) @@ -621,8 +623,8 @@ def test_basic_metric_success_new_semconv(self): @patch.dict( "os.environ", { - "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED": "true", - "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED": "true", + OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED: "1", + OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED: "1", }, ) def test_basic_metric_success_new_semconv_server_address(self): 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 9c5e1ed160..75b4c279a9 100644 --- a/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py @@ -454,7 +454,7 @@ def _parse_active_request_count_attrs( return _filter_semconv_active_request_count_attr( req_attrs, _server_active_requests_count_attrs_old, - _server_active_requests_count_attrs_new_effective, + _server_active_requests_count_attrs_new_effective(), sem_conv_opt_in_mode, ) @@ -465,7 +465,7 @@ def _parse_duration_attrs( return _filter_semconv_duration_attrs( req_attrs, _server_duration_attrs_old, - _server_duration_attrs_new_effective, + _server_duration_attrs_new_effective(), sem_conv_opt_in_mode, ) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index d481698d34..08ff79f7cb 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -46,6 +46,10 @@ ) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace.status import Status, StatusCode +from opentelemetry.util.http import ( + OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED, + OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED, +) # These lists represent attributes for metrics that are currently supported @@ -119,21 +123,26 @@ ] ) -_server_active_requests_count_attrs_new_effective = ( - _server_active_requests_count_attrs_new_with_server_attributes - if os.environ.get( - "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED" + +def _server_active_requests_count_attrs_new_effective(): + return ( + _server_active_requests_count_attrs_new_with_server_attributes + if os.environ.get( + OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED + ) + else _server_active_requests_count_attrs_new ) - else _server_active_requests_count_attrs_new -) -_server_duration_attrs_new_effective = ( - _server_duration_attrs_new_with_server_attributes - if os.environ.get( - "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED" + +def _server_duration_attrs_new_effective(): + return ( + _server_duration_attrs_new_with_server_attributes + if os.environ.get( + OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED + ) + else _server_duration_attrs_new ) - else _server_duration_attrs_new -) + OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN" diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py index f5dacf0fff..4fa4510f9b 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py @@ -38,6 +38,13 @@ "OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS" ) +OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED = ( + "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED" +) +OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED = ( + "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED" +) + # List of recommended metrics attributes _duration_attrs = { SpanAttributes.HTTP_METHOD, From c7da9e57c7d32a1e87475e37054b1b73d3d4a387 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 12 Sep 2024 10:12:41 +0200 Subject: [PATCH 10/10] fix dependencies --- .../tests/test_programmatic.py | 4 ++-- .../src/opentelemetry/instrumentation/_semconv.py | 9 ++++++--- .../src/opentelemetry/util/http/__init__.py | 7 ------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py index 5b7af0471a..6f4cb7c344 100644 --- a/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py +++ b/instrumentation/opentelemetry-instrumentation-flask/tests/test_programmatic.py @@ -20,6 +20,8 @@ from opentelemetry import trace from opentelemetry.instrumentation._semconv import ( + OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED, + OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED, OTEL_SEMCONV_STABILITY_OPT_IN, _OpenTelemetrySemanticConventionStability, _server_active_requests_count_attrs_new, @@ -46,8 +48,6 @@ OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, - OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED, - OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED, OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS, get_excluded_urls, ) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py index 08ff79f7cb..1136a1c3bb 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/_semconv.py @@ -46,9 +46,12 @@ ) from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.trace.status import Status, StatusCode -from opentelemetry.util.http import ( - OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED, - OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED, + +OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED = ( + "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED" +) +OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED = ( + "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED" ) # These lists represent attributes for metrics that are currently supported diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py index 4fa4510f9b..f5dacf0fff 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py @@ -38,13 +38,6 @@ "OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS" ) -OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED = ( - "OTEL_PYTHON_HTTP_SERVER_ACTIVE_REQUESTS_COUNT_SERVER_ATTRIBUTES_ENABLED" -) -OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED = ( - "OTEL_PYTHON_HTTP_SERVER_REQUEST_DURATION_SERVER_ATTRIBUTES_ENABLED" -) - # List of recommended metrics attributes _duration_attrs = { SpanAttributes.HTTP_METHOD,