From f11f03ce6e3ab07d1d37ecbd1569f211ae0a1e76 Mon Sep 17 00:00:00 2001 From: Andre Murbach Maidl Date: Mon, 18 Aug 2025 09:39:16 -0300 Subject: [PATCH] Avoid calls to context.detach with None token (#3673) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fixes open-telemetry/opentelemetry-python-contrib#3351 * Add changelog entry about open-telemetry/opentelemetry-python-contrib#3673 --------- Co-authored-by: Emídio Neto <9735060+emdneto@users.noreply.github.com> Co-authored-by: Riccardo Magliocchetti --- CHANGELOG.md | 5 +++++ .../instrumentation/aio_pika/callback_decorator.py | 3 ++- .../instrumentation/aiohttp_client/__init__.py | 3 ++- .../src/opentelemetry/instrumentation/aiokafka/utils.py | 3 ++- .../opentelemetry/instrumentation/aws_lambda/__init__.py | 3 ++- .../src/opentelemetry/instrumentation/boto3sqs/__init__.py | 5 +++-- .../opentelemetry/instrumentation/confluent_kafka/utils.py | 3 ++- .../src/opentelemetry/instrumentation/grpc/_server.py | 3 ++- .../src/opentelemetry/instrumentation/kafka/utils.py | 3 ++- .../src/opentelemetry/instrumentation/pika/utils.py | 6 ++++-- .../src/opentelemetry/instrumentation/utils.py | 3 ++- .../src/opentelemetry/util/http/httplib.py | 3 ++- 12 files changed, 30 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f252e829..af4d00eb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Fixed + +- `opentelemetry-instrumentation`: Avoid calls to `context.detach` with `None` token. + ([#3673](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3673)) + ## Version 1.36.0/0.57b0 (2025-07-29) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/callback_decorator.py b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/callback_decorator.py index f10415bdd..07842851f 100644 --- a/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/callback_decorator.py +++ b/instrumentation/opentelemetry-instrumentation-aio-pika/src/opentelemetry/instrumentation/aio_pika/callback_decorator.py @@ -53,7 +53,8 @@ class CallbackDecorator: with trace.use_span(span, end_on_exit=True): return_value = await callback(message) finally: - context.detach(token) + if token: + context.detach(token) return return_value return decorated diff --git a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py index bee39d13b..c84839deb 100644 --- a/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py @@ -273,7 +273,8 @@ def create_trace_config( def _end_trace(trace_config_ctx: types.SimpleNamespace): elapsed_time = max(default_timer() - trace_config_ctx.start_time, 0) - context_api.detach(trace_config_ctx.token) + if trace_config_ctx.token: + context_api.detach(trace_config_ctx.token) trace_config_ctx.span.end() if trace_config_ctx.duration_histogram_old is not None: diff --git a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py index 6d8ef6d22..36bfb29ef 100644 --- a/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py +++ b/instrumentation/opentelemetry-instrumentation-aiokafka/src/opentelemetry/instrumentation/aiokafka/utils.py @@ -490,7 +490,8 @@ async def _create_consumer_span( await async_consume_hook(span, record, args, kwargs) except Exception as hook_exception: # pylint: disable=W0703 _LOG.exception(hook_exception) - context.detach(token) + if token: + context.detach(token) return span diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py index 827f3b620..ed40d4c1c 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py @@ -384,7 +384,8 @@ def _instrument( result.get("statusCode"), ) finally: - context_api.detach(token) + if token: + context_api.detach(token) now = time.time() _tracer_provider = tracer_provider or get_tracer_provider() diff --git a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/__init__.py b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/__init__.py index 83e5ed70b..028009afd 100644 --- a/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-boto3sqs/src/opentelemetry/instrumentation/boto3sqs/__init__.py @@ -180,8 +180,9 @@ class Boto3SQSInstrumentor(BaseInstrumentor): Boto3SQSInstrumentor.current_span_related_to_token == started_span ): - context.detach(Boto3SQSInstrumentor.current_context_token) - Boto3SQSInstrumentor.current_context_token = None + if Boto3SQSInstrumentor.current_context_token: + context.detach(Boto3SQSInstrumentor.current_context_token) + Boto3SQSInstrumentor.current_context_token = None started_span.end() @staticmethod diff --git a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/utils.py b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/utils.py index 60dc13e67..fd8b72848 100644 --- a/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/utils.py +++ b/instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/utils.py @@ -82,7 +82,8 @@ _kafka_getter = KafkaContextGetter() def _end_current_consume_span(instance): - context.detach(instance._current_context_token) + if instance._current_context_token: + context.detach(instance._current_context_token) instance._current_context_token = None instance._current_consume_span.end() instance._current_consume_span = None diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_server.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_server.py index 1a7d6ccc8..1d744656d 100644 --- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_server.py +++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/_server.py @@ -209,7 +209,8 @@ class OpenTelemetryServerInterceptor(grpc.ServerInterceptor): try: yield finally: - detach(token) + if token: + detach(token) else: yield diff --git a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/utils.py b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/utils.py index 3f9bd6f39..d42848759 100644 --- a/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/utils.py +++ b/instrumentation/opentelemetry-instrumentation-kafka-python/src/opentelemetry/instrumentation/kafka/utils.py @@ -196,7 +196,8 @@ def _create_consumer_span( consume_hook(span, record, args, kwargs) except Exception as hook_exception: # pylint: disable=W0703 _LOG.exception(hook_exception) - context.detach(token) + if token: + context.detach(token) def _wrap_next( diff --git a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/utils.py b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/utils.py index 2b4d1204e..2e1353d2b 100644 --- a/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/utils.py +++ b/instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/utils.py @@ -80,7 +80,8 @@ def _decorate_callback( _LOG.exception(hook_exception) retval = callback(channel, method, properties, body) finally: - context.detach(token) + if token: + context.detach(token) return retval return decorated_callback @@ -252,7 +253,8 @@ class ReadyMessagesDequeProxy(ObjectProxy): operation=MessagingOperationValues.RECEIVE, ) try: - context.detach(message_ctx_token) + if message_ctx_token: + context.detach(message_ctx_token) self._self_active_token = context.attach( trace.set_span_in_context(span) ) diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py index d5bf5db7f..e38932e28 100644 --- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py @@ -207,7 +207,8 @@ def _suppress_instrumentation(*keys: str) -> Generator[None]: try: yield finally: - context.detach(token) + if token: + context.detach(token) @contextmanager diff --git a/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py b/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py index 4f5cba957..c969710cd 100644 --- a/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py +++ b/util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py @@ -179,7 +179,8 @@ def set_ip_on_next_http_connection(span: Span): try: yield finally: - context.detach(token) + if token: + context.detach(token) else: spans = state["need_ip"] spans.append(span)