From 41976e8f4fed00aedb7c94f05d44936b50448c1d Mon Sep 17 00:00:00 2001 From: Alex Boten <223565+codeboten@users.noreply.github.com> Date: Thu, 18 Jun 2026 15:01:54 -0700 Subject: [PATCH 1/3] opentelemetry-instrumentation-urllib3: remove multiple calls to sanitize_method Instead call the method once and pass the results in where needed Signed-off-by: Alex Boten <223565+codeboten@users.noreply.github.com> --- .../benchmark-requirements.txt | 5 +++ .../test_benchmark_sanitize_method.py | 41 +++++++++++++++++++ .../instrumentation/urllib3/__init__.py | 18 ++++---- tox.ini | 3 ++ 4 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 instrumentation/opentelemetry-instrumentation-urllib3/benchmark-requirements.txt create mode 100644 instrumentation/opentelemetry-instrumentation-urllib3/benchmarks/test_benchmark_sanitize_method.py diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/benchmark-requirements.txt b/instrumentation/opentelemetry-instrumentation-urllib3/benchmark-requirements.txt new file mode 100644 index 0000000000..5ddc9d46f4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-urllib3/benchmark-requirements.txt @@ -0,0 +1,5 @@ +mocket==3.14.1 +pytest-benchmark==4.0.0 +-e opentelemetry-instrumentation +-e util/opentelemetry-util-http +-e instrumentation/opentelemetry-instrumentation-urllib3 diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/benchmarks/test_benchmark_sanitize_method.py b/instrumentation/opentelemetry-instrumentation-urllib3/benchmarks/test_benchmark_sanitize_method.py new file mode 100644 index 0000000000..5f5d5e03fd --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-urllib3/benchmarks/test_benchmark_sanitize_method.py @@ -0,0 +1,41 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import pytest +import urllib3 +from mocket import Mocketizer +from mocket.mocks.mockhttp import Entry + +from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( + InMemorySpanExporter, +) + +_URL = "http://mock/status/200" + + +@pytest.fixture +def instrumented_pool(): + exporter = InMemorySpanExporter() + provider = TracerProvider() + provider.add_span_processor(SimpleSpanProcessor(exporter)) + URLLib3Instrumentor().instrument(tracer_provider=provider) + pool = urllib3.HTTPConnectionPool("mock", port=80) + with Mocketizer(): + Entry.single_register( + Entry.GET, _URL, body="Hello!", match_querystring=False + ) + yield pool + URLLib3Instrumentor().uninstrument() + + +def test_instrumented_urlopen(benchmark, instrumented_pool): + def run(): + Entry.single_register( + Entry.GET, _URL, body="Hello!", match_querystring=False + ) + instrumented_pool.urlopen("GET", "/status/200") + + benchmark(run) 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 ab5660cc74..4728c09ba6 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/src/opentelemetry/instrumentation/urllib3/__init__.py @@ -406,11 +406,10 @@ def _uninstrument(self, **kwargs): _uninstrument() -def _get_span_name(method: str) -> str: - method = sanitize_method(method.strip()) - if method == "_OTHER": - method = "HTTP" - return method +def _get_span_name(sanitized_method: str) -> str: + if sanitized_method == "_OTHER": + return "HTTP" + return sanitized_method # pylint: disable=too-many-locals,too-many-positional-arguments @@ -457,13 +456,14 @@ def instrumented_urlopen(wrapped, instance, args, kwargs): # avoid modifying original headers on inject headers = headers.copy() if headers is not None else {} - span_name = _get_span_name(method) + sanitized_method = sanitize_method(method) + span_name = _get_span_name(sanitized_method) span_attributes = {} _set_http_method( span_attributes, method, - sanitize_method(method), + sanitized_method, sem_conv_opt_in_mode, ) _set_http_url(span_attributes, url, sem_conv_opt_in_mode) @@ -519,6 +519,7 @@ def instrumented_urlopen(wrapped, instance, args, kwargs): instance, response, method, + sanitized_method, sem_conv_opt_in_mode, ) @@ -625,6 +626,7 @@ def _set_metric_attributes( instance: urllib3.connectionpool.HTTPConnectionPool, response: urllib3.response.HTTPResponse, method: str, + sanitized_method: str, sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, ) -> None: _set_http_host_client( @@ -634,7 +636,7 @@ def _set_metric_attributes( _set_http_method( metric_attributes, method, - sanitize_method(method), + sanitized_method, sem_conv_opt_in_mode, ) _set_http_net_peer_name_client( diff --git a/tox.ini b/tox.ini index f8315f4650..b59c469210 100644 --- a/tox.ini +++ b/tox.ini @@ -202,6 +202,7 @@ envlist = pypy3-test-instrumentation-logging lint-instrumentation-logging benchmark-instrumentation-logging + benchmark-instrumentation-urllib3 ; opentelemetry-exporter-richconsole py3{10,11,12,13,14}-test-exporter-richconsole @@ -691,6 +692,7 @@ deps = logging: {[testenv]test_deps} logging: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-logging/test-requirements.txt benchmark-instrumentation-logging: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-logging/benchmark-requirements.txt + benchmark-instrumentation-urllib3: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/benchmark-requirements.txt aiohttp-client: {[testenv]test_deps} aiohttp-client: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-aiohttp-client/test-requirements.txt @@ -893,6 +895,7 @@ commands = test-instrumentation-logging: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-logging/tests {posargs} lint-instrumentation-logging: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-logging" benchmark-instrumentation-logging: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-logging/benchmarks {posargs} --benchmark-json=instrumentation-logging-benchmark.json + benchmark-instrumentation-urllib3: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-urllib3/benchmarks {posargs} --benchmark-json=instrumentation-urllib3-benchmark.json test-instrumentation-mysql: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql/tests {posargs} lint-instrumentation-mysql: sh -c "cd instrumentation && pylint --rcfile ../.pylintrc opentelemetry-instrumentation-mysql" From 0ab623486774e4079c41f17c879e4aa32a619a2e Mon Sep 17 00:00:00 2001 From: Alex Boten <223565+codeboten@users.noreply.github.com> Date: Thu, 18 Jun 2026 15:06:00 -0700 Subject: [PATCH 2/3] changelog Signed-off-by: Alex Boten <223565+codeboten@users.noreply.github.com> --- .changelog/4718.changed | 1 + 1 file changed, 1 insertion(+) create mode 100644 .changelog/4718.changed diff --git a/.changelog/4718.changed b/.changelog/4718.changed new file mode 100644 index 0000000000..190c17a7d2 --- /dev/null +++ b/.changelog/4718.changed @@ -0,0 +1 @@ +opentelemetry-instrumentation-urllib3: remove multiple calls to sanitize_method \ No newline at end of file From 9245c665523f7fe25c489b67fc11c7e9ccebc580 Mon Sep 17 00:00:00 2001 From: Alex Boten <223565+codeboten@users.noreply.github.com> Date: Thu, 18 Jun 2026 15:28:53 -0700 Subject: [PATCH 3/3] fix lint Signed-off-by: Alex Boten <223565+codeboten@users.noreply.github.com> --- .../benchmarks/test_benchmark_sanitize_method.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-urllib3/benchmarks/test_benchmark_sanitize_method.py b/instrumentation/opentelemetry-instrumentation-urllib3/benchmarks/test_benchmark_sanitize_method.py index 5f5d5e03fd..e320e3aa84 100644 --- a/instrumentation/opentelemetry-instrumentation-urllib3/benchmarks/test_benchmark_sanitize_method.py +++ b/instrumentation/opentelemetry-instrumentation-urllib3/benchmarks/test_benchmark_sanitize_method.py @@ -16,8 +16,8 @@ _URL = "http://mock/status/200" -@pytest.fixture -def instrumented_pool(): +@pytest.fixture(name="connection_pool") +def _connection_pool_fixture(): exporter = InMemorySpanExporter() provider = TracerProvider() provider.add_span_processor(SimpleSpanProcessor(exporter)) @@ -31,11 +31,13 @@ def instrumented_pool(): URLLib3Instrumentor().uninstrument() -def test_instrumented_urlopen(benchmark, instrumented_pool): +def test_instrumented_urlopen( + benchmark, connection_pool: urllib3.HTTPConnectionPool +): def run(): Entry.single_register( Entry.GET, _URL, body="Hello!", match_querystring=False ) - instrumented_pool.urlopen("GET", "/status/200") + connection_pool.urlopen("GET", "/status/200") benchmark(run)