From 63905340e45777ddef09e1779655b45c5ed10a3a Mon Sep 17 00:00:00 2001 From: Saurabh Saraswat Date: Fri, 2 Jan 2026 10:12:40 +0000 Subject: [PATCH 1/4] opentelemetry-instrumentation-pymemcache: Remove usage of deprecated SpanAttributes --- .../instrumentation/pymemcache/__init__.py | 30 +++++++++++------- .../tests/test_pymemcache.py | 31 ++++++++++++------- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py index d763734aca..75e4a7eb8e 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py @@ -47,11 +47,17 @@ from opentelemetry.instrumentation.pymemcache.package import _instruments from opentelemetry.instrumentation.pymemcache.version import __version__ from opentelemetry.instrumentation.utils import unwrap -from opentelemetry.semconv.trace import NetTransportValues, SpanAttributes from opentelemetry.trace import SpanKind, get_tracer - +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_STATEMENT, + DB_SYSTEM, +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, +) logger = logging.getLogger(__name__) - +NET_TRANSPORT = "network.transport" COMMANDS = [ "set", @@ -115,7 +121,7 @@ def _wrap_cmd(tracer, cmd, wrapped, instance, args, kwargs): vals = _get_query_string(args[0]) query = f"{cmd}{' ' if vals else ''}{vals}" - span.set_attribute(SpanAttributes.DB_STATEMENT, query) + span.set_attribute(DB_STATEMENT, query) _set_connection_attributes(span, instance) except Exception as ex: # pylint: disable=broad-except @@ -153,22 +159,22 @@ def _get_query_string(arg): def _get_address_attributes(instance): """Attempt to get host and port from Client instance.""" address_attributes = {} - address_attributes[SpanAttributes.DB_SYSTEM] = "memcached" + address_attributes[DB_SYSTEM] = "memcached" # client.base.Client contains server attribute which is either a host/port tuple, or unix socket path string # https://github.com/pinterest/pymemcache/blob/f02ddf73a28c09256589b8afbb3ee50f1171cac7/pymemcache/client/base.py#L228 if hasattr(instance, "server"): if isinstance(instance.server, tuple): host, port = instance.server - address_attributes[SpanAttributes.NET_PEER_NAME] = host - address_attributes[SpanAttributes.NET_PEER_PORT] = port - address_attributes[SpanAttributes.NET_TRANSPORT] = ( - NetTransportValues.IP_TCP.value + address_attributes[NET_PEER_NAME] = host + address_attributes[NET_PEER_PORT] = port + address_attributes[NET_TRANSPORT] = ( + "tcp" ) elif isinstance(instance.server, str): - address_attributes[SpanAttributes.NET_PEER_NAME] = instance.server - address_attributes[SpanAttributes.NET_TRANSPORT] = ( - NetTransportValues.OTHER.value + address_attributes[NET_PEER_NAME] = instance.server + address_attributes[NET_TRANSPORT] = ( + "other" ) return address_attributes diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py b/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py index b9ad948819..2c39ec30ec 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py @@ -11,6 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + from unittest import mock import pymemcache @@ -26,12 +27,20 @@ from opentelemetry import trace as trace_api from opentelemetry.instrumentation.pymemcache import PymemcacheInstrumentor -from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase from opentelemetry.trace import get_tracer from .utils import MockSocket, _str +from opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_STATEMENT, + DB_SYSTEM, + +) +from opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_NAME, + NET_PEER_PORT, +) TEST_HOST = "localhost" TEST_PORT = 117711 @@ -83,16 +92,16 @@ def check_spans(self, spans, num_expected, queries_expected): self.assertEqual(span.name, command) self.assertIs(span.kind, trace_api.SpanKind.CLIENT) self.assertEqual( - span.attributes[SpanAttributes.NET_PEER_NAME], TEST_HOST + span.attributes[NET_PEER_NAME], TEST_HOST ) self.assertEqual( - span.attributes[SpanAttributes.NET_PEER_PORT], TEST_PORT + span.attributes[NET_PEER_PORT], TEST_PORT ) self.assertEqual( - span.attributes[SpanAttributes.DB_SYSTEM], "memcached" + span.attributes[DB_SYSTEM], "memcached" ) self.assertEqual( - span.attributes[SpanAttributes.DB_STATEMENT], query + span.attributes[DB_STATEMENT], query ) def test_set_success(self): @@ -249,10 +258,10 @@ def test_set_get(self): self.assertEqual(len(spans), 2) self.assertEqual( - spans[0].attributes[SpanAttributes.NET_PEER_NAME], TEST_HOST + spans[0].attributes[NET_PEER_NAME], TEST_HOST ) self.assertEqual( - spans[0].attributes[SpanAttributes.NET_PEER_PORT], TEST_PORT + spans[0].attributes[NET_PEER_PORT], TEST_PORT ) def test_append_stored(self): @@ -577,16 +586,16 @@ def check_spans(self, spans, num_expected, queries_expected): self.assertEqual(span.name, command) self.assertIs(span.kind, trace_api.SpanKind.CLIENT) self.assertEqual( - span.attributes[SpanAttributes.NET_PEER_NAME], TEST_HOST + span.attributes[NET_PEER_NAME], TEST_HOST ) self.assertEqual( - span.attributes[SpanAttributes.NET_PEER_PORT], TEST_PORT + span.attributes[NET_PEER_PORT], TEST_PORT ) self.assertEqual( - span.attributes[SpanAttributes.DB_SYSTEM], "memcached" + span.attributes[DB_SYSTEM], "memcached" ) self.assertEqual( - span.attributes[SpanAttributes.DB_STATEMENT], query + span.attributes[DB_STATEMENT], query ) def test_delete_many_found(self): From 5ab82010b6d95cb23e344ea5858e8ac8240bebd0 Mon Sep 17 00:00:00 2001 From: Saurabh Saraswat Date: Fri, 2 Jan 2026 10:39:52 +0000 Subject: [PATCH 2/4] Fixed linting issues --- .../src/opentelemetry/instrumentation/pymemcache/__init__.py | 3 --- .../tests/test_pymemcache.py | 1 - 2 files changed, 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py index 75e4a7eb8e..b12947c78f 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py @@ -182,10 +182,8 @@ def _get_address_attributes(instance): class PymemcacheInstrumentor(BaseInstrumentor): """An instrumentor for pymemcache See `BaseInstrumentor`""" - def instrumentation_dependencies(self) -> Collection[str]: return _instruments - def _instrument(self, **kwargs): tracer_provider = kwargs.get("tracer_provider") tracer = get_tracer( @@ -201,7 +199,6 @@ def _instrument(self, **kwargs): f"Client.{cmd}", _wrap_cmd(tracer, cmd), ) - def _uninstrument(self, **kwargs): for command in COMMANDS: unwrap(pymemcache.client.base.Client, f"{command}") diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py b/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py index 2c39ec30ec..7ce6e42a09 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py @@ -35,7 +35,6 @@ from opentelemetry.semconv._incubating.attributes.db_attributes import ( DB_STATEMENT, DB_SYSTEM, - ) from opentelemetry.semconv._incubating.attributes.net_attributes import ( NET_PEER_NAME, From d389537e88aeed1a52d88987ea724c2a6da5a197 Mon Sep 17 00:00:00 2001 From: Saurabh Saraswat Date: Mon, 5 Jan 2026 06:59:38 +0000 Subject: [PATCH 3/4] Incorporated Review Comments for usage of NET_TRANSPORT --- CHANGELOG.md | 2 ++ .../opentelemetry/instrumentation/pymemcache/__init__.py | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e991ae533a..d1702f8ee0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4068](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4068)) - `opentelemetry-instrumentation-mysqlclient`: Replace SpanAttributes with semconv constants ([#4067](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4067)) +- `opentelemetry-instrumentation-pymemcache`: Remove span attributes pymemcache + ([#4076](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4076)) ## Version 1.39.0/0.60b0 (2025-12-03) diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py index b12947c78f..ad4ab2b0f0 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py @@ -47,6 +47,7 @@ from opentelemetry.instrumentation.pymemcache.package import _instruments from opentelemetry.instrumentation.pymemcache.version import __version__ from opentelemetry.instrumentation.utils import unwrap +from opentelemetry.semconv.trace import NetTransportValues from opentelemetry.trace import SpanKind, get_tracer from opentelemetry.semconv._incubating.attributes.db_attributes import ( DB_STATEMENT, @@ -55,9 +56,9 @@ from opentelemetry.semconv._incubating.attributes.net_attributes import ( NET_PEER_NAME, NET_PEER_PORT, + NET_TRANSPORT, ) logger = logging.getLogger(__name__) -NET_TRANSPORT = "network.transport" COMMANDS = [ "set", @@ -169,12 +170,12 @@ def _get_address_attributes(instance): address_attributes[NET_PEER_NAME] = host address_attributes[NET_PEER_PORT] = port address_attributes[NET_TRANSPORT] = ( - "tcp" + NetTransportValues.IP_TCP.value ) elif isinstance(instance.server, str): address_attributes[NET_PEER_NAME] = instance.server address_attributes[NET_TRANSPORT] = ( - "other" + NetTransportValues.OTHER.value ) return address_attributes From af97ecd586e57acb6f67452e481d4faf9e3202e4 Mon Sep 17 00:00:00 2001 From: saurabh-saraswat <85618497+saurabh-saraswat@users.noreply.github.com> Date: Fri, 16 Jan 2026 18:52:45 +0530 Subject: [PATCH 4/4] Added back the empty lines --- .../src/opentelemetry/instrumentation/pymemcache/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py index ad4ab2b0f0..adb70c6a9a 100644 --- a/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/__init__.py @@ -58,8 +58,10 @@ NET_PEER_PORT, NET_TRANSPORT, ) + logger = logging.getLogger(__name__) + COMMANDS = [ "set", "set_many", @@ -183,8 +185,10 @@ def _get_address_attributes(instance): class PymemcacheInstrumentor(BaseInstrumentor): """An instrumentor for pymemcache See `BaseInstrumentor`""" + def instrumentation_dependencies(self) -> Collection[str]: return _instruments + def _instrument(self, **kwargs): tracer_provider = kwargs.get("tracer_provider") tracer = get_tracer( @@ -200,6 +204,7 @@ def _instrument(self, **kwargs): f"Client.{cmd}", _wrap_cmd(tracer, cmd), ) + def _uninstrument(self, **kwargs): for command in COMMANDS: unwrap(pymemcache.client.base.Client, f"{command}")