Skip to content

ref(kafka): [Queue Instrumentation 20] Log Kafka instrumentation failures#5315

Draft
adinauer wants to merge 1 commit intoref/queue-instrumentation-kafka-sample-autoconfigfrom
ref/queue-instrumentation-kafka-log-failures
Draft

ref(kafka): [Queue Instrumentation 20] Log Kafka instrumentation failures#5315
adinauer wants to merge 1 commit intoref/queue-instrumentation-kafka-sample-autoconfigfrom
ref/queue-instrumentation-kafka-log-failures

Conversation

@adinauer
Copy link
Copy Markdown
Member

@adinauer adinauer commented Apr 21, 2026

PR Stack (Queue Instrumentation)


📜 Description

Log Throwables caught inside Kafka instrumentation instead of silently swallowing them.

Affected catch sites:

  • SentryKafkaProducerInterceptor.onSend(...) — wrapping span creation and header injection.
  • SentryKafkaConsumerTracing.withTracingImpl(...) — forking scopes + makeCurrent().
  • SentryKafkaConsumerTracing.startTransaction(...) — transaction creation.
  • SentryKafkaConsumerTracing.finishTransaction(...) — transaction finish.

All catches still swallow the throwable so instrumentation failures never break the customer's Kafka send or record processing. The only change is that the failure is now reported to the SDK's own logger at SentryLevel.ERROR (same pattern already used in RequestPayloadExtractor).

SentryKafkaRecordInterceptor (Spring Jakarta) was audited alongside — it does not wrap instrumentation in catch (Throwable) blocks, so there is nothing silent to log. The existing NumberFormatException branches on malformed sentry-task-enqueued-time headers are expected input, not instrumentation faults, and remain silent both in the Spring interceptor and in SentryKafkaConsumerTracing.receiveLatency(...).

💡 Motivation and Context

The raw Kafka instrumentation in sentry-kafka deliberately fails open: if anything throws while Sentry tries to start/finish a span or inject tracing headers, the customer's Kafka operation still succeeds. That behavior is correct and is preserved here.

What was missing was any trace of such a failure. With catch (Throwable ignored), an instrumentation bug would be invisible in production — neither the customer nor us would know the SDK was quietly failing. Surfacing it through the SDK logger matches how other integrations report unexpected internal failures (e.g. RequestPayloadExtractor in Spring Jakarta) and makes these paths debuggable without changing fail-open semantics.

💚 How did you test it?

  • ./gradlew :sentry-kafka:compileJava — clean.
  • ./gradlew :sentry-kafka:test — all tests pass, including the existing SentryKafkaConsumerTracingTest and SentryKafkaProducerInterceptorTest suites.
  • ./gradlew spotlessApply apiDump — clean.

Behavior verified by reading: catches still swallow the throwable and fall back exactly as before; only additional effect is a single logger.log(ERROR, msg, t) call per caught throwable.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

If the NumberFormatException header-parse branches ever prove useful to debug, they could be downgraded to DEBUG logs. Leaving silent for now since a malformed sentry-task-enqueued-time header is a data-shape issue, not an SDK fault.

#skip-changelog

⚠️ Merge this PR using a merge commit (not squash). Only the collection branch is squash-merged into main.

…ures

Previously `SentryKafkaProducerInterceptor.onSend(...)` and
`SentryKafkaConsumerTracing` silently swallowed any `Throwable` thrown
while instrumenting a Kafka record. That protects customer Kafka I/O
from breakage, but makes instrumentation bugs invisible.

Log each caught `Throwable` to the SDK logger at `SentryLevel.ERROR`
(matching the existing pattern in `RequestPayloadExtractor`) before
continuing the fail-open path:

- `SentryKafkaProducerInterceptor`: producer span creation / header injection
- `SentryKafkaConsumerTracing`: scope fork + `makeCurrent`, transaction
  start, transaction finish

No behavior change for customer callbacks or Kafka send/receive: the
catches still swallow the throwable, they now just surface it via the
SDK's own logger.

`SentryKafkaRecordInterceptor` (Spring) was reviewed and intentionally
left as-is — it does not wrap its instrumentation in `catch (Throwable)`
blocks, so there is nothing silent to log. The `NumberFormatException`
branches on malformed `sentry-task-enqueued-time` headers are expected
input, not instrumentation faults, and remain silent.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 21, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


This PR will not appear in the changelog.


🤖 This preview updates automatically when you update the PR.

This was referenced Apr 21, 2026
@sentry
Copy link
Copy Markdown

sentry bot commented Apr 21, 2026

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.37.1 (1) release

⚙️ sentry-android Build Distribution Settings

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant