fix(kafka): [Queue Instrumentation 35] Inject trace headers even without active span#5338
Draft
adinauer wants to merge 3 commits intofeat/queue-instrumentation-otel-messaging-mappingfrom
Draft
Conversation
Replace SentryKafkaProducerInterceptor with SentryKafkaProducer, a Producer<K,V> wrapper that records a queue.publish span around each send and finishes it when the broker ack callback fires. The span now reflects the full async send lifecycle, not just the synchronous onSend window. For Spring Boot, the SentryKafkaProducerBeanPostProcessor switches from patching KafkaTemplate.setProducerInterceptor(...) to installing a ProducerPostProcessor on every ProducerFactory bean via ProducerFactory.addPostProcessor(...). KafkaTemplate beans are no longer touched, so all customer-configured listeners, interceptors and observation settings are preserved. The console sample now wraps the raw KafkaProducer instead of setting INTERCEPTOR_CLASSES_CONFIG. Spring Boot samples need no change — the auto-configured ProducerPostProcessor is transparent. Co-Authored-By: Claude <noreply@anthropic.com>
Decouple header injection from span creation in SentryKafkaProducer so that distributed tracing works for background workers, @scheduled jobs, and startup publishers that have no active span. Restructure send() to match the SentryFeignClient/OkHttp pattern: - isIgnored: pure delegate, no headers, no span - No active span: inject headers from PropagationContext, no span - Active span: start child span, inject headers, wrap callback Also simplify the implementation: - Rename injectHeaders to maybeInjectHeaders with encapsulated try/catch (matches Feign's maybeAddTracingHeaders pattern) - Remove outer try/catch around span setup - Remove redundant span.isNoOp() early-return branch - Remove redundant isFinished() guards before finish() calls Co-Authored-By: Claude <noreply@anthropic.com>
This was referenced Apr 27, 2026
Open
Open
This was referenced Apr 27, 2026
📲 Install BuildsAndroid
|
Contributor
Performance metrics 🚀
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Stack (Queue Instrumentation)
📜 Description
Restructure
SentryKafkaProducer.send()to inject trace headers even when no active span exists, and simplify the overall flow to match theSentryFeignClient/SentryOkHttpInterceptorpattern.Before: When
scopes.getSpan()returned null (background workers,@Scheduledjobs, startup publishers),send()short-circuited to the bare delegate — nosentry-trace,baggage, orsentry-task-enqueued-timeheaders were injected. Distributed tracing silently broke for these common Kafka patterns.After: Three clean branches matching the Feign/OkHttp/RestTemplate convention:
isIgnored→ pure delegate (no headers, no span)PropagationContext, no spanAlso simplifies the implementation:
injectHeaders→maybeInjectHeaderswith encapsulated try/catch (matches Feign'smaybeAddTracingHeaders)span.isNoOp()early-return branch (wrapping a no-op span callback is harmless)isFinished()guards —Span.finish()is already idempotent viacompareAndSet💡 Motivation and Context
Addresses review finding R10-F001: producer drops trace headers when no active span exists. Background workers and
@Scheduledjobs are a primary Kafka producer pattern; losing distributed tracing for them contradicts the Queues product expectations.💚 How did you test it?
maybeInjectHeadersbehaviorSentryKafkaProducerTesttests pass📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
Continue addressing remaining review findings from the Queue Instrumentation review.