diff --git a/CHANGELOG.md b/CHANGELOG.md index 419a8a7c63d..d9e48cd6df8 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-asgi`: Respect `suppress_http_instrumentation` context in ASGI middleware to skip server span creation when HTTP instrumentation is suppressed + ([#4375](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4375)) - `opentelemetry-instrumentation-confluent-kafka`: Loosen confluent-kafka upper bound to <3.0.0 ([#4289](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4289)) - `opentelemetry-instrumentation`: Add support for wrapt 2.x 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 59c5083ada8..e28315f502e 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py @@ -255,7 +255,10 @@ def client_response_hook(span: Span, scope: Scope, message: dict[str, Any]): from opentelemetry.instrumentation.propagators import ( get_global_response_propagator, ) -from opentelemetry.instrumentation.utils import _start_internal_or_server_span +from opentelemetry.instrumentation.utils import ( + _start_internal_or_server_span, + is_http_instrumentation_enabled, +) from opentelemetry.metrics import get_meter from opentelemetry.propagators.textmap import Getter, Setter from opentelemetry.semconv._incubating.attributes.http_attributes import ( @@ -745,7 +748,10 @@ async def __call__( send: An awaitable callable taking a single dictionary as argument. """ start = default_timer() - if scope["type"] not in ("http", "websocket"): + if not is_http_instrumentation_enabled() or scope["type"] not in ( + "http", + "websocket", + ): return await self.app(scope, receive, send) _, _, url = get_host_port_url_tuple(scope) diff --git a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py index f716c9f2f1e..b14f207d8a5 100644 --- a/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py +++ b/instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py @@ -37,6 +37,7 @@ get_global_response_propagator, set_global_response_propagator, ) +from opentelemetry.instrumentation.utils import suppress_http_instrumentation from opentelemetry.sdk import resources from opentelemetry.sdk.metrics.export import ( HistogramDataPoint, @@ -1880,6 +1881,19 @@ async def test_no_excluded_urls(self): spans = self.get_finished_spans() self.assertGreater(len(spans), 0) + async def test_suppress_http_instrumentation(self): + app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) + + async def suppression_wrapper(scope, receive, send): + with suppress_http_instrumentation(): + await app(scope, receive, send) + + self.seed_app(suppression_wrapper) + await self.send_default_request() + await self.get_all_output() + spans = self.get_finished_spans() + self.assertEqual(len(spans), 0) + class TestAsgiAttributes(unittest.TestCase): def setUp(self):