Skip to content

opentelemetry-instrumentation-kafka-python: keep the producer span open across the send() call - #4935

Open
Yigtwxx wants to merge 2 commits into
open-telemetry:mainfrom
Yigtwxx:fix/kafka-python-producer-span-lifetime
Open

opentelemetry-instrumentation-kafka-python: keep the producer span open across the send() call#4935
Yigtwxx wants to merge 2 commits into
open-telemetry:mainfrom
Yigtwxx:fix/kafka-python-producer-span-lifetime

Conversation

@Yigtwxx

@Yigtwxx Yigtwxx commented Aug 7, 2026

Copy link
Copy Markdown

Description

_wrap_send closed the producer span before calling the wrapped KafkaProducer.send(), so an exception raised synchronously by send() (connection failure, serialization error) happened after the span had already ended. The exported span reported StatusCode.UNSET with no exception event, so a failed produce looked successful in traces.

This moves return func(*args, **kwargs) inside the span's context manager, which is what the confluent-kafka instrumentation already does. Header injection, the produce hook and the span attributes are unchanged.

Scoped to the producer only. #4871 also reports a consumer-side gap, but that part carries an open question to maintainers about whether receive failures should produce an errored span, so it is left out here and the issue stays open.

Related to #4871

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

Two regression tests added to tests/test_utils.py, using the real SDK (TestBase with the in-memory exporter) rather than a mock tracer, since a mock tracer cannot observe span status:

  • test_wrap_send_records_exception_raised_by_send — the exception propagates unmodified and the exported span carries StatusCode.ERROR plus an exception event. This test fails on main (StatusCode.UNSET is not StatusCode.ERROR) and passes with the fix.
  • test_wrap_send_leaves_successful_send_unchanged — span name, kind, status and the return value are unchanged on the success path.

The four existing _wrap_send / _wrap_next tests pass unmodified.

  • tox -e py311-test-instrumentation-kafka-python-latest (9 passed)
  • tox -e py311-test-instrumentation-kafka-python-oldest (9 passed)
  • tox -e lint-instrumentation-kafka-python, pre-commit run ruff

Does This PR Require a Core Repo Change?

  • Yes. - Link to PR:
  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

The producer span ended before the wrapped KafkaProducer.send() was
invoked, so an exception raised synchronously by send() happened after
the span had closed. The exported span reported StatusCode.UNSET with no
exception event, hiding the failure from traces.

Move the call inside the span's context manager, matching what the
confluent-kafka instrumentation already does. Header injection, the
produce hook and the span attributes are unaffected.

Assisted-by: Claude Opus 5
@linux-foundation-easycla

linux-foundation-easycla Bot commented Aug 7, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

@Yigtwxx
Yigtwxx requested a review from a team as a code owner August 7, 2026 16:37

@iamroylim iamroylim left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified this at head 6735b24 on Python 3.14.5 with uvx tox -e py314-test-instrumentation-kafka-python-latest: 16 tests passed. The change keeps KafkaProducer.send() inside start_as_current_span, so synchronous exceptions exit through the span context manager and produce ERROR status plus an exception event, while the successful return path remains unchanged. The Kafka future-completion path is deliberately out of scope. No blocking issue found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants