From 5b6b52fb2fd30f7b810c6fc9d8064ecd52646e91 Mon Sep 17 00:00:00 2001 From: 42Questions Date: Sat, 7 Feb 2026 14:25:55 +0000 Subject: [PATCH 1/5] Added _instrumentation in package.py pattern for aio_pika --- .../aio_pika/aio_pika_instrumentor.py | 5 ++--- .../instrumentation/aio_pika/package.py | 4 +++- .../tests/test_aio_pika_instrumentation.py | 15 ++++++++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py index 48a936dc61..1854ae6b8b 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py @@ -21,7 +21,7 @@ from opentelemetry.instrumentation.aio_pika.callback_decorator import ( CallbackDecorator, ) -from opentelemetry.instrumentation.aio_pika.package import _instruments +from opentelemetry.instrumentation.aio_pika.package import _instruments, _instrumentation_name from opentelemetry.instrumentation.aio_pika.publish_decorator import ( PublishDecorator, ) @@ -30,7 +30,6 @@ from opentelemetry.instrumentation.utils import unwrap from opentelemetry.trace import Tracer -_INSTRUMENTATION_MODULE_NAME = "opentelemetry.instrumentation.aio_pika" class AioPikaInstrumentor(BaseInstrumentor): @@ -64,7 +63,7 @@ async def wrapper(wrapped, instance, args, kwargs): def _instrument(self, **kwargs): tracer_provider = kwargs.get("tracer_provider", None) tracer = trace.get_tracer( - _INSTRUMENTATION_MODULE_NAME, + _instrumentation_name, __version__, tracer_provider, schema_url="https://opentelemetry.io/schemas/1.11.0", diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/package.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/package.py index 8069323f7c..3c1097ab96 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/package.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/package.py @@ -11,6 +11,8 @@ # 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 typing import Collection +from typing import Collection, Final _instruments: Collection[str] = ("aio_pika >= 7.2.0, < 10.0.0",) + +_instrumentation_name: Final[str] = "opentelemetry.instrumentation.aio_pika" diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.py b/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.py index c2dc6e5144..0f7fa46b74 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.py @@ -11,12 +11,15 @@ # 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 TestCase +from unittest import TestCase, mock import wrapt from aio_pika import Exchange, Queue from opentelemetry.instrumentation.aio_pika import AioPikaInstrumentor +from opentelemetry.instrumentation.aio_pika.package import ( + _instrumentation_name, +) class TestPika(TestCase): @@ -32,3 +35,13 @@ def test_instrument_api(self) -> None: self.assertFalse( isinstance(Exchange.publish, wrapt.BoundFunctionWrapper) ) + + def test_instrumentation_name(self) -> None: + with mock.patch("opentelemetry.trace.get_tracer") as mock_get_tracer: + instrumentation = AioPikaInstrumentor() + instrumentation.instrument() + mock_get_tracer.assert_called_once() + self.assertEqual( + mock_get_tracer.call_args[0][0], _instrumentation_name + ) + instrumentation.uninstrument() From 699f07f306c8a5ac8e04460ab7879b6e8b26947c Mon Sep 17 00:00:00 2001 From: 42Questions Date: Sat, 7 Feb 2026 14:37:22 +0000 Subject: [PATCH 2/5] Added changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1853b73414..9bf2c8d804 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `opentelemetry-instrumentation-aio-pika`: Add test to verify tracer uses correct `_instrumentation_name` + ([#4178](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4178)) - `opentelemetry-instrumentation-asgi`: Add exemplars for `http.server.request.duration` and `http.server.duration` metrics ([#3739](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3739)) - `opentelemetry-instrumentation-wsgi`: Add exemplars for `http.server.request.duration` and `http.server.duration` metrics From 004da7ef7c903d9ff02204aa35d033327d88edc2 Mon Sep 17 00:00:00 2001 From: 42Questions Date: Mon, 9 Feb 2026 11:53:35 +0000 Subject: [PATCH 3/5] Changed test to use TestBase --- .../tests/test_aio_pika_instrumentation.py | 59 ++++++++++++++++--- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.py b/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.py index 0f7fa46b74..3ed09d4745 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.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. +import asyncio from unittest import TestCase, mock import wrapt @@ -20,6 +21,17 @@ from opentelemetry.instrumentation.aio_pika.package import ( _instrumentation_name, ) +from opentelemetry.test.test_base import TestBase + +from .consts import ( + AIOPIKA_VERSION_INFO, + CHANNEL_7, + CHANNEL_8, + CONNECTION_7, + EXCHANGE_NAME, + MESSAGE, + ROUTING_KEY, +) class TestPika(TestCase): @@ -36,12 +48,43 @@ def test_instrument_api(self) -> None: isinstance(Exchange.publish, wrapt.BoundFunctionWrapper) ) - def test_instrumentation_name(self) -> None: - with mock.patch("opentelemetry.trace.get_tracer") as mock_get_tracer: - instrumentation = AioPikaInstrumentor() - instrumentation.instrument() - mock_get_tracer.assert_called_once() - self.assertEqual( - mock_get_tracer.call_args[0][0], _instrumentation_name + +class TestInstrumentationScopeName(TestBase): + """Test instrumentation scope via actual span output (not mocking internals).""" + + def setUp(self): + super().setUp() + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(self.loop) + + def tearDown(self): + with self.disable_logging(): + AioPikaInstrumentor().uninstrument() + self.loop.close() + super().tearDown() + + def test_instrumentation_scope_name(self): + """Verify instrumentation scope via the real instrument() path.""" + async def _noop_publish(self, *args, **kwargs): + return None + + with mock.patch.object(Exchange, "publish", new=_noop_publish): + AioPikaInstrumentor().instrument( + tracer_provider=self.tracer_provider + ) + major = AIOPIKA_VERSION_INFO[0] + if major == 7: + exchange = Exchange(CONNECTION_7, CHANNEL_7, EXCHANGE_NAME) + elif major == 8: + exchange = Exchange(CHANNEL_8, EXCHANGE_NAME) + else: + self.fail(f"Unsupported aio-pika version: {AIOPIKA_VERSION_INFO}") + self.loop.run_until_complete( + exchange.publish(MESSAGE, ROUTING_KEY) ) - instrumentation.uninstrument() + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual( + spans[0].instrumentation_scope.name, _instrumentation_name + ) From ca77ca7d8c3ded034e93941009ce6345539abce0 Mon Sep 17 00:00:00 2001 From: 42Questions Date: Tue, 10 Feb 2026 10:01:47 +0000 Subject: [PATCH 4/5] Added aio-pika 9 suport in tests, added hardcode in consts --- .../tests/consts.py | 1 + .../tests/test_aio_pika_instrumentation.py | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/tests/consts.py b/instrumentation/opentelemetry-instrumentation-aio-pika/tests/consts.py index 9be41cc844..db9f624884 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/tests/consts.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/tests/consts.py @@ -8,6 +8,7 @@ CORRELATION_ID = "correlation_id" MESSAGING_SYSTEM_VALUE = "rabbitmq" EXCHANGE_NAME = "exchange_name" +INSTRUMENTATION_NAME = "opentelemetry.instrumentation.aio_pika" QUEUE_NAME = "queue_name" ROUTING_KEY = "routing_key" SERVER_HOST = "localhost" diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.py b/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.py index 3ed09d4745..cc444e2eb3 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/tests/test_aio_pika_instrumentation.py @@ -18,9 +18,6 @@ from aio_pika import Exchange, Queue from opentelemetry.instrumentation.aio_pika import AioPikaInstrumentor -from opentelemetry.instrumentation.aio_pika.package import ( - _instrumentation_name, -) from opentelemetry.test.test_base import TestBase from .consts import ( @@ -29,6 +26,7 @@ CHANNEL_8, CONNECTION_7, EXCHANGE_NAME, + INSTRUMENTATION_NAME, MESSAGE, ROUTING_KEY, ) @@ -65,6 +63,7 @@ def tearDown(self): def test_instrumentation_scope_name(self): """Verify instrumentation scope via the real instrument() path.""" + async def _noop_publish(self, *args, **kwargs): return None @@ -75,10 +74,12 @@ async def _noop_publish(self, *args, **kwargs): major = AIOPIKA_VERSION_INFO[0] if major == 7: exchange = Exchange(CONNECTION_7, CHANNEL_7, EXCHANGE_NAME) - elif major == 8: + elif major in (8, 9): exchange = Exchange(CHANNEL_8, EXCHANGE_NAME) else: - self.fail(f"Unsupported aio-pika version: {AIOPIKA_VERSION_INFO}") + self.fail( + f"Unsupported aio-pika major version {major} (supported: 7-9, <10)" + ) self.loop.run_until_complete( exchange.publish(MESSAGE, ROUTING_KEY) ) @@ -86,5 +87,6 @@ async def _noop_publish(self, *args, **kwargs): spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 1) self.assertEqual( - spans[0].instrumentation_scope.name, _instrumentation_name + spans[0].instrumentation_scope.name, + INSTRUMENTATION_NAME, ) From 0909d029329a8500a517b828416a3d5559235f9b Mon Sep 17 00:00:00 2001 From: 42Questions Date: Thu, 12 Feb 2026 18:53:37 +0000 Subject: [PATCH 5/5] Pre-commit now passing --- .../instrumentation/aio_pika/aio_pika_instrumentor.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py index 1854ae6b8b..2d17ae7403 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/aio_pika_instrumentor.py @@ -21,7 +21,10 @@ from opentelemetry.instrumentation.aio_pika.callback_decorator import ( CallbackDecorator, ) -from opentelemetry.instrumentation.aio_pika.package import _instruments, _instrumentation_name +from opentelemetry.instrumentation.aio_pika.package import ( + _instrumentation_name, + _instruments, +) from opentelemetry.instrumentation.aio_pika.publish_decorator import ( PublishDecorator, ) @@ -31,7 +34,6 @@ from opentelemetry.trace import Tracer - class AioPikaInstrumentor(BaseInstrumentor): @staticmethod def _instrument_queue(tracer: Tracer):