diff --git a/CHANGELOG.md b/CHANGELOG.md index 52bc006893..3c2c64c8b5 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 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..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 +from opentelemetry.instrumentation.aio_pika.package import ( + _instrumentation_name, + _instruments, +) from opentelemetry.instrumentation.aio_pika.publish_decorator import ( PublishDecorator, ) @@ -30,8 +33,6 @@ from opentelemetry.instrumentation.utils import unwrap from opentelemetry.trace import Tracer -_INSTRUMENTATION_MODULE_NAME = "opentelemetry.instrumentation.aio_pika" - class AioPikaInstrumentor(BaseInstrumentor): @staticmethod @@ -64,7 +65,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/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 c2dc6e5144..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 @@ -11,12 +11,25 @@ # 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 +import asyncio +from unittest import TestCase, mock import wrapt from aio_pika import Exchange, Queue from opentelemetry.instrumentation.aio_pika import AioPikaInstrumentor +from opentelemetry.test.test_base import TestBase + +from .consts import ( + AIOPIKA_VERSION_INFO, + CHANNEL_7, + CHANNEL_8, + CONNECTION_7, + EXCHANGE_NAME, + INSTRUMENTATION_NAME, + MESSAGE, + ROUTING_KEY, +) class TestPika(TestCase): @@ -32,3 +45,48 @@ def test_instrument_api(self) -> None: self.assertFalse( isinstance(Exchange.publish, wrapt.BoundFunctionWrapper) ) + + +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 in (8, 9): + exchange = Exchange(CHANNEL_8, EXCHANGE_NAME) + else: + self.fail( + f"Unsupported aio-pika major version {major} (supported: 7-9, <10)" + ) + self.loop.run_until_complete( + exchange.publish(MESSAGE, ROUTING_KEY) + ) + + spans = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans), 1) + self.assertEqual( + spans[0].instrumentation_scope.name, + INSTRUMENTATION_NAME, + )