Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
168 commits
Select commit Hold shift + click to select a range
7224607
collection: Queue Instrumentation
adinauer Mar 31, 2026
76a907e
feat(core): Add enableQueueTracing option and messaging span data con…
adinauer Mar 31, 2026
5f063c1
changelog
adinauer Mar 31, 2026
f44c735
feat(samples): Add Kafka producer and consumer to Spring Boot 3 sampl…
adinauer Apr 1, 2026
be5af44
feat(spring-jakarta): Add Kafka producer instrumentation
adinauer Apr 1, 2026
5049ffc
changelog
adinauer Apr 1, 2026
6099047
feat(spring-jakarta): Add Kafka consumer instrumentation
adinauer Apr 1, 2026
1f00027
changelog
adinauer Apr 1, 2026
572dc2d
feat(spring-boot-jakarta): Add Kafka queue auto-configuration
adinauer Apr 1, 2026
04a4689
changelog
adinauer Apr 1, 2026
271fb8b
test(samples): Add Kafka queue system tests for Spring Boot 3
adinauer Apr 2, 2026
02f2007
docs: Add rule against force-pushing stack branches
adinauer Apr 2, 2026
6f90ea7
docs: Also prohibit --amend on stack branches
adinauer Apr 2, 2026
10a5c63
feat(samples): Add Kafka producer and consumer to Spring Boot 3 OTel …
adinauer Apr 7, 2026
ce2ea96
fix(spring-boot-jakarta): Disable Sentry Kafka instrumentation when O…
adinauer Apr 7, 2026
414b118
fix(core): Add Kafka span origins to ignored list for OpenTelemetry
adinauer Apr 7, 2026
915e42b
ref(spring-jakarta): Replace SentryKafkaProducerWrapper with SentryPr…
adinauer Apr 9, 2026
2b74bab
Merge branch 'feat/queue-instrumentation-producer' into feat/queue-in…
adinauer Apr 9, 2026
be3a2ba
fix(spring-jakarta): Update consumer references and add reflection wa…
adinauer Apr 9, 2026
ce87037
Merge branch 'feat/queue-instrumentation-consumer' into feat/queue-in…
adinauer Apr 9, 2026
5d297ac
Merge branch 'feat/queue-instrumentation-autoconfig' into feat/queue-…
adinauer Apr 9, 2026
4fa767e
Merge branch 'feat/queue-instrumentation-e2e' into feat/queue-instrum…
adinauer Apr 9, 2026
fb7e217
Merge branch 'feat/queue-instrumentation-otel-samples' into fix/queue…
adinauer Apr 9, 2026
fdb3a03
fix(spring-jakarta): Initialize Sentry in SentryProducerInterceptorTest
adinauer Apr 9, 2026
6450f63
Merge branch 'feat/queue-instrumentation-producer' into feat/queue-in…
adinauer Apr 9, 2026
f92f47c
fix(spring-jakarta): Initialize Sentry in consumer test, fix API file…
adinauer Apr 9, 2026
b8ead5f
Merge branch 'feat/queue-instrumentation-consumer' into feat/queue-in…
adinauer Apr 9, 2026
e607d67
Merge branch 'feat/queue-instrumentation-autoconfig' into feat/queue-…
adinauer Apr 9, 2026
cf9ba0c
Merge branch 'feat/queue-instrumentation-e2e' into feat/queue-instrum…
adinauer Apr 9, 2026
24348b2
Merge branch 'feat/queue-instrumentation-otel-samples' into fix/queue…
adinauer Apr 9, 2026
2501e57
fix(spring-jakarta): Clean up stale ThreadLocal context in Kafka cons…
adinauer Apr 10, 2026
320e805
fix(spring-jakarta): Fork root scopes and skip when OTel is active in…
adinauer Apr 10, 2026
6d91bdc
fix(spring-jakarta): Guard entire span lifecycle in Kafka producer in…
adinauer Apr 10, 2026
e86169f
fix(spring-jakarta): [Queue Instrumentation 12] Add Kafka retry count…
adinauer Apr 10, 2026
24cff6d
fix(spring-jakarta): [Queue Instrumentation 13] Align enqueue time wi…
adinauer Apr 10, 2026
ca69447
ref(kafka): Extract sentry-kafka module from spring-jakarta
adinauer Apr 13, 2026
0734938
changelog
adinauer Apr 13, 2026
007d27f
feat(kafka): Add no-arg producer interceptor for Kafka config
adinauer Apr 13, 2026
82cfc37
feat(kafka): Add consumer demo to console sample
adinauer Apr 13, 2026
cb4d2ac
ref(samples): Extract Kafka console showcase into dedicated class
adinauer Apr 13, 2026
33c4c79
feat(samples): Add opt-in Kafka console e2e coverage
adinauer Apr 13, 2026
58b67b2
ref(samples): Move KafkaShowcase to kafka subpackage
adinauer Apr 13, 2026
daeba53
Update KafkaShowcase.java
adinauer Apr 13, 2026
a222362
Update KafkaShowcase.java
adinauer Apr 13, 2026
7661f6c
Update KafkaShowcase.java
adinauer Apr 13, 2026
e02a907
Format code
getsentry-bot Apr 13, 2026
efd8727
fix
adinauer Apr 14, 2026
540ea07
ref(samples): Clarify Kafka setup in console showcase
adinauer Apr 14, 2026
2844be7
Merge remote-tracking branch 'origin/feat/queue-instrumentation-kafka…
adinauer Apr 14, 2026
327df95
fix(test): Enable Kafka profile for Spring Kafka system tests
adinauer Apr 14, 2026
bd9d3b5
fix(spring): Guard Kafka auto-config on sentry-kafka
adinauer Apr 17, 2026
1f848a7
feat(kafka): [Queue Instrumentation 17] Add manual consumer tracing h…
adinauer Apr 20, 2026
c52b8ad
ref(kafka): Remove raw consumer interceptor
adinauer Apr 20, 2026
74430c0
ref(samples): Clarify Kafka consumer tracing sample
adinauer Apr 20, 2026
d2f4d8c
fix(kafka): Honor ignored producer span origins
adinauer Apr 20, 2026
97d82f3
ref(spring): Use injected scopes in Kafka interceptor
adinauer Apr 20, 2026
1af29a3
ref(samples): [Queue Instrumentation 18] Move Kafka sources into queu…
adinauer Apr 21, 2026
118d244
ref(samples): [Queue Instrumentation 19] Drop Kafka auto-config exclu…
adinauer Apr 21, 2026
adf85eb
ref(kafka): [Queue Instrumentation 20] Log Kafka instrumentation fail…
adinauer Apr 21, 2026
df91d0c
fix(kafka): [Queue Instrumentation 21] Preserve third-party baggage o…
adinauer Apr 21, 2026
80058bb
test(spring-boot-jakarta): [Queue Instrumentation 22] Cover spring-ka…
adinauer Apr 21, 2026
19cb740
fix(spring-jakarta): [Queue Instrumentation 23] Install Kafka context…
adinauer Apr 22, 2026
f020319
fix(kafka): [Queue Instrumentation 24] Read all baggage headers on co…
adinauer Apr 22, 2026
d0b2380
fix(kafka): [Queue Instrumentation 25] Finish producer spans on failures
adinauer Apr 22, 2026
08e6da2
fix(kafka): [Queue Instrumentation 26] Mark producer interceptor expe…
adinauer Apr 22, 2026
47b2d2f
fix(spring-jakarta): [Queue Instrumentation 27] Delegate Kafka record…
adinauer Apr 22, 2026
e0bb87f
test(samples): Cover OTel Jakarta Kafka coexistence end-to-end
adinauer Apr 22, 2026
4a48e54
fix(spring-jakarta): [Queue Instrumentation 29] Set body_size on Spri…
adinauer Apr 22, 2026
7384727
test(spring-jakarta): [Queue Instrumentation 30] Cover Kafka record i…
adinauer Apr 23, 2026
a001e25
fix(kafka): [Queue Instrumentation 31] Write enqueued-time header as …
adinauer Apr 23, 2026
39f67f3
changelog
adinauer Apr 23, 2026
bbed2d2
test(spring-boot-jakarta): [Queue Instrumentation 32] Filter OTel in …
adinauer Apr 23, 2026
e3eca3f
feat(opentelemetry): [Queue Instrumentation 33] Map OTel messaging sp…
adinauer Apr 27, 2026
f85b2d7
fix(otel): Prefer messaging over http mapping when queue tracing enabled
adinauer Apr 27, 2026
26f4229
fix(otel): Map messaging "create" to queue.create instead of queue.pu…
adinauer Apr 27, 2026
6040247
docs(options): Clarify enableQueueTracing covers native + OTel paths
adinauer Apr 27, 2026
b0f802a
fix(otel): Map messaging "settle" to queue.settle
adinauer Apr 27, 2026
cac8c1f
chore(samples): Drop verbose comment above sentry.enable-queue-tracing
adinauer Apr 27, 2026
fc23438
feat(kafka): [Queue Instrumentation 34] Wrap Producer for send spans
adinauer Apr 27, 2026
925ab2b
fix(kafka): Inject trace headers even without active span
adinauer Apr 27, 2026
1e293c6
changelog
adinauer Apr 27, 2026
0ca42c8
ref(kafka): Reimplement SentryKafkaProducer as a dynamic Proxy
adinauer Apr 27, 2026
5e0629d
fix(spring-jakarta): Warn when Kafka producer tracing silently fails
adinauer Apr 27, 2026
c1ccbf7
fix(kafka): Preserve existing consumer interceptor on reflection failure
adinauer Apr 28, 2026
db18ff8
fix(spring-boot-jakarta): Skip Kafka autoconfig for OTel agent
adinauer Apr 29, 2026
1411bb7
fix(spring-jakarta): Close leaked Kafka interceptor scope
adinauer Apr 29, 2026
00d11a0
fix(test): Remove stale Kafka container before startup
adinauer Apr 29, 2026
3eeacb5
test(otel): Add send and deliver mapping coverage
adinauer Apr 29, 2026
b21192b
Merge branch 'feat/queue-instrumentation-otel-messaging-mapping' into…
adinauer Apr 29, 2026
7f9aae6
Merge branch 'feat/kafka-producer-wrapper' into fix/kafka-consumer-in…
adinauer Apr 29, 2026
599fe0d
Merge branch 'fix/kafka-consumer-interceptor-reflection' into fix/kaf…
adinauer Apr 29, 2026
c41d255
Merge branch 'fix/kafka-otel-agent-autoconfig' into fix/kafka-interce…
adinauer Apr 29, 2026
f28916d
Merge branch 'fix/kafka-interceptor-lifecycle-token' into fix/kafka-s…
adinauer Apr 29, 2026
18e05fa
test(kafka): Add no-op producer span coverage
adinauer Apr 29, 2026
81ee869
Merge branch 'feat/kafka-producer-wrapper' into fix/kafka-consumer-in…
adinauer Apr 29, 2026
6b17593
Merge branch 'fix/kafka-consumer-interceptor-reflection' into fix/kaf…
adinauer Apr 29, 2026
1c5485d
Merge branch 'fix/kafka-otel-agent-autoconfig' into fix/kafka-interce…
adinauer Apr 29, 2026
d68da53
Merge branch 'fix/kafka-interceptor-lifecycle-token' into fix/kafka-s…
adinauer Apr 29, 2026
fc022d0
fix(kafka): Pass consumer interceptor log throwable correctly
adinauer Apr 29, 2026
22922ac
Merge branch 'fix/kafka-consumer-interceptor-reflection' into fix/kaf…
adinauer Apr 29, 2026
fd1f92c
Merge branch 'fix/kafka-otel-agent-autoconfig' into fix/kafka-interce…
adinauer Apr 29, 2026
72afedf
Merge branch 'fix/kafka-interceptor-lifecycle-token' into fix/kafka-s…
adinauer Apr 29, 2026
934fed9
test(kafka): Exercise consumer interceptor reflection failure
adinauer Apr 29, 2026
35f42d7
Merge branch 'fix/kafka-consumer-interceptor-reflection' into fix/kaf…
adinauer Apr 29, 2026
93c7e2e
Merge branch 'fix/kafka-otel-agent-autoconfig' into fix/kafka-interce…
adinauer Apr 29, 2026
9234efd
Merge branch 'fix/kafka-interceptor-lifecycle-token' into fix/kafka-s…
adinauer Apr 29, 2026
60d8460
fix(test): Set SENTRY_ENABLE_QUEUE_TRACING for Kafka system tests
adinauer Apr 29, 2026
cfd524c
feat(spring): Add Kafka queue tracing for Spring Boot 4
adinauer Apr 29, 2026
11a211c
changelog
adinauer Apr 29, 2026
1d87dde
feat(spring): Add Kafka queue tracing for Spring Boot 2
adinauer Apr 29, 2026
703d631
Merge pull request #5250 from getsentry/feat/queue-instrumentation-op…
adinauer Apr 29, 2026
007d23f
Merge pull request #5253 from getsentry/feat/queue-instrumentation-sa…
adinauer Apr 29, 2026
9830c0c
Merge pull request #5254 from getsentry/feat/queue-instrumentation-pr…
adinauer Apr 29, 2026
a57d7aa
Merge pull request #5255 from getsentry/feat/queue-instrumentation-co…
adinauer Apr 29, 2026
46225de
Merge pull request #5259 from getsentry/feat/queue-instrumentation-au…
adinauer Apr 29, 2026
e3ca6ef
Merge pull request #5260 from getsentry/feat/queue-instrumentation-e2e
adinauer Apr 29, 2026
4b8feb0
Merge pull request #5265 from getsentry/feat/queue-instrumentation-ot…
adinauer Apr 29, 2026
ccd7c49
Merge pull request #5274 from getsentry/fix/queue-instrumentation-ote…
adinauer Apr 29, 2026
f5b6353
Merge pull request #5279 from getsentry/fix/queue-instrumentation-thr…
adinauer Apr 29, 2026
0e5c3c0
Merge pull request #5280 from getsentry/fix/queue-instrumentation-roo…
adinauer Apr 29, 2026
69f38d4
Merge pull request #5281 from getsentry/fix/queue-instrumentation-pro…
adinauer Apr 29, 2026
8355a1e
Merge pull request #5282 from getsentry/fix/queue-instrumentation-ret…
adinauer Apr 29, 2026
55c5586
Merge pull request #5283 from getsentry/fix/queue-instrumentation-enq…
adinauer Apr 29, 2026
592a210
Merge pull request #5288 from getsentry/feat/queue-instrumentation-ka…
adinauer Apr 29, 2026
9080e31
docs(rules): Add queue tracing cursor rules
adinauer Apr 30, 2026
b850263
changelog
adinauer Apr 30, 2026
d764864
Merge pull request #5289 from getsentry/feat/queue-instrumentation-ka…
adinauer May 5, 2026
d819a4a
Merge pull request #5291 from getsentry/fix/queue-instrumentation-kaf…
adinauer May 5, 2026
b85d088
Merge pull request #5312 from getsentry/feat/queue-instrumentation-ka…
adinauer May 5, 2026
da700e7
Merge pull request #5313 from getsentry/ref/queue-instrumentation-kaf…
adinauer May 5, 2026
741c645
Merge pull request #5314 from getsentry/ref/queue-instrumentation-kaf…
adinauer May 5, 2026
a2b2bc1
Merge pull request #5315 from getsentry/ref/queue-instrumentation-kaf…
adinauer May 5, 2026
06070f4
Merge pull request #5316 from getsentry/fix/queue-instrumentation-kaf…
adinauer May 5, 2026
09a6512
Merge pull request #5318 from getsentry/test/queue-instrumentation-ka…
adinauer May 5, 2026
6186aca
Merge pull request #5319 from getsentry/fix/queue-instrumentation-kaf…
adinauer May 5, 2026
37b7d28
Merge pull request #5320 from getsentry/fix/queue-instrumentation-kaf…
adinauer May 5, 2026
3ac6cd3
Merge pull request #5321 from getsentry/fix/queue-instrumentation-kaf…
adinauer May 5, 2026
29f7f02
Merge pull request #5322 from getsentry/fix/queue-instrumentation-kaf…
adinauer May 5, 2026
a4417eb
Merge pull request #5323 from getsentry/fix/queue-instrumentation-kaf…
adinauer May 5, 2026
e511e86
Merge pull request #5324 from getsentry/fix/queue-instrumentation-kaf…
adinauer May 5, 2026
97b9216
Merge pull request #5325 from getsentry/fix/queue-instrumentation-spr…
adinauer May 5, 2026
9d95566
Merge pull request #5327 from getsentry/test/queue-instrumentation-ka…
adinauer May 5, 2026
0f8eedd
Merge pull request #5328 from getsentry/fix/queue-instrumentation-kaf…
adinauer May 5, 2026
79d93ae
Merge pull request #5330 from getsentry/test/queue-instrumentation-ka…
adinauer May 5, 2026
2064336
Merge pull request #5337 from getsentry/feat/queue-instrumentation-ot…
adinauer May 5, 2026
6c836c1
Merge pull request #5338 from getsentry/feat/kafka-producer-wrapper
adinauer May 5, 2026
4ec3244
Merge pull request #5341 from getsentry/fix/kafka-consumer-intercepto…
adinauer May 5, 2026
3aa0975
Merge pull request #5343 from getsentry/fix/kafka-otel-agent-autoconfig
adinauer May 5, 2026
d1b0233
Merge pull request #5345 from getsentry/fix/kafka-interceptor-lifecyc…
adinauer May 5, 2026
22bca33
Merge pull request #5347 from getsentry/fix/kafka-system-test-stale-c…
adinauer May 5, 2026
2d69bcd
build(samples): Use Spring Boot Kafka starter in Boot 4 samples
adinauer May 5, 2026
85019fe
Merge branch 'feat/queue-instrumentation-spring-boot-4' into feat/que…
adinauer May 5, 2026
941a8c1
fix(queue): Apply queue instrumentation review changes
adinauer May 5, 2026
557686a
test(spring): Address Kafka tracing review comments
adinauer May 5, 2026
c96a904
Merge branch 'feat/queue-instrumentation-spring-boot-4' into feat/que…
adinauer May 5, 2026
265084a
Merge branch 'feat/queue-instrumentation-spring-boot-2' into fix/queu…
adinauer May 5, 2026
4c3f5cd
test(spring): Initialize Sentry in Kafka BPP tests
adinauer May 5, 2026
e4725b8
Merge branch 'feat/queue-instrumentation-spring-boot-4' into feat/que…
adinauer May 5, 2026
6204fd6
Merge branch 'feat/queue-instrumentation-spring-boot-2' into fix/queu…
adinauer May 5, 2026
a4b2016
test(spring): Address Kafka review comments
adinauer May 5, 2026
0174f15
Merge branch 'feat/queue-instrumentation-spring-boot-2' into fix/queu…
adinauer May 5, 2026
c171d68
test(spring): Isolate capture exception advice scopes
adinauer May 6, 2026
ce746d1
Merge pull request #5348 from getsentry/feat/queue-instrumentation-sp…
adinauer May 6, 2026
5a245f0
Merge pull request #5352 from getsentry/feat/queue-instrumentation-sp…
adinauer May 6, 2026
d0cd5a4
Merge pull request #5368 from getsentry/fix/queue-instrumentation-rev…
adinauer May 6, 2026
2f528bf
Merge branch 'main' into feat/queue-instrumentation
adinauer May 6, 2026
3bfba65
changelog entry
adinauer May 6, 2026
c825d7e
fix README changes
adinauer May 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .cursor/rules/overview_dev.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ Use the `fetch_rules` tool to include these rules when working on specific areas
- `SentryMetricsEvent`, `SentryMetricsEvents`
- `SentryOptions.getMetrics()`, `beforeSend` callback

- **`queues`**: Use when working with:
- Sentry Queues product data or messaging span conventions
- Queue tracing spans/transactions (`queue.publish`, `queue.process`)
- `enableQueueTracing` option and `sentry.enable-queue-tracing`
- Kafka instrumentation (`sentry-kafka`, `SentryKafkaProducer`, `SentryKafkaConsumerTracing`)
- Spring Kafka queue auto-instrumentation and `SentryKafkaRecordInterceptor`
- Messaging span data (`messaging.system`, `messaging.destination.name`, receive latency, retry count)
- `sentry-task-enqueued-time` header and distributed trace propagation through queues

- **`continuous_profiling_jvm`**: Use when working with:
- JVM continuous profiling (`sentry-async-profiler` module)
- `IContinuousProfiler`, `JavaContinuousProfiler`
Expand Down Expand Up @@ -118,6 +127,7 @@ Use the `fetch_rules` tool to include these rules when working on specific areas
- System test/e2e/sample → `e2e_tests`
- Feature flag/addFeatureFlag/flag evaluation → `feature_flags`
- Metrics/count/distribution/gauge → `metrics`
- Queues/queue tracing/Kafka/Spring Kafka/queue.publish/queue.process/enableQueueTracing/messaging spans → `queues`
- PR/pull request/stacked PR/stack → `pr`
- JVM continuous profiling/async-profiler/JFR/ProfileChunk → `continuous_profiling_jvm`
- Android continuous profiling/AndroidProfiler/frame metrics/method tracing → no dedicated rule yet; inspect the code directly
2 changes: 2 additions & 0 deletions .cursor/rules/pr.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,5 @@ git push
**Never merge into the collection branch.** Syncing only happens between stack PR branches. The collection branch is untouched until the user merges PRs through GitHub.

Prefer merge over rebase — it preserves commit history, doesn't invalidate existing review comments, and avoids the need for force-pushing. Only rebase if explicitly requested.

**Never amend or force-push stack branches.** Do not use `git commit --amend`, `--force`, or `--force-with-lease` on branches that are part of a stack. Amending a pushed commit requires a force-push, which can cause GitHub to auto-merge or auto-close other PRs in the stack. If a commit needs fixing, add a new fixup commit instead.
82 changes: 82 additions & 0 deletions .cursor/rules/queues.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
alwaysApply: false
description: Sentry Queues module and Java SDK queue tracing
---
# Sentry Queues and Java SDK Queue Tracing

## Product model

Sentry Queues is built from tracing data. SDKs mark queue work with queue-specific span operations and messaging span data so Sentry can identify producers, consumers, destinations, latency, and failures.

The important concepts are:
- `queue.publish`: a span for enqueueing/publishing a message to a queue or topic.
- `queue.process`: a transaction for processing a dequeued message.
- Messaging span data, especially:
- `messaging.system` (for example `kafka`)
- `messaging.destination.name` (queue/topic name)
- `messaging.message.id`
- `messaging.message.retry.count`
- `messaging.message.body.size`
- `messaging.message.envelope.size`
- `messaging.message.receive.latency`
- Distributed tracing headers (`sentry-trace` and `baggage`) link producer-side work to consumer-side processing.
- Queue receive latency is the time a message spent waiting between publish/enqueue and processing. For Java Kafka, this comes from the `sentry-task-enqueued-time` header that the producer writes and the consumer reads.

The Queues UI is not backed by a separate Java event type. The Java SDK contributes data through spans/transactions with the expected operations, trace context, statuses, and messaging attributes.

## Java SDK implementation

Queue tracing is opt-in. `SentryOptions.isEnableQueueTracing()` defaults to `false` and can be enabled with `setEnableQueueTracing(true)` or external config key `enable-queue-tracing` (`sentry.enable-queue-tracing` in Spring Boot). Captured queue spans/transactions still depend on tracing being enabled and sampled.

Kafka support lives in `sentry-kafka`:
- `SentryKafkaProducer.wrap(Producer)` wraps Kafka `Producer.send(...)` calls.
- Creates a `queue.publish` child span when there is an active span.
- Sets `messaging.system=kafka` and `messaging.destination.name=<topic>`.
- Injects `sentry-trace`, `baggage`, and `sentry-task-enqueued-time` headers.
- Still injects tracing/enqueued-time headers when queue tracing is enabled but there is no active span, so background producers can link to consumers.
- Finishes the span from the Kafka callback with `OK` or `INTERNAL_ERROR`.
- `SentryKafkaConsumerTracing.withTracing(record, callback)` is the manual raw-Kafka consumer helper.
- Forks root scopes for the processing lifecycle and makes them current.
- Continues the trace from Kafka headers.
- Starts a `queue.process` transaction bound to scope when tracing is enabled.
- Sets Kafka messaging data, body size, retry count, and receive latency when available.
- Finishes with `OK` or `INTERNAL_ERROR` and never lets instrumentation failures break customer processing.

Spring Kafka support lives in `sentry-spring`, `sentry-spring-jakarta`, and `sentry-spring-7`:
- `SentryKafkaProducerBeanPostProcessor` installs a producer post-processor on `DefaultKafkaProducerFactory` and wraps created producers with `SentryKafkaProducer.wrap(...)`.
- `SentryKafkaConsumerBeanPostProcessor` installs `SentryKafkaRecordInterceptor` on listener container factories.
- `SentryKafkaRecordInterceptor` starts/finishes `queue.process` transactions around listener processing, continues traces from headers, forks scopes for the record lifecycle, and preserves any existing delegate interceptor.
- Spring Boot auto-configuration registers both post-processors only when Spring Kafka and `sentry-kafka` are present and `sentry.enable-queue-tracing=true`.
- Spring Boot queue auto-configuration is disabled when Sentry OpenTelemetry integration classes are present to avoid duplicate Kafka instrumentation.

## Trace origins and suppression

Queue instrumentation sets span origins so it can be identified and suppressed with `ignoredSpanOrigins`:
- Raw Kafka producer: `auto.queue.kafka.producer`
- Raw Kafka consumer helper: `manual.queue.kafka.consumer`
- Spring Kafka producer: `auto.queue.spring.kafka.producer`, `auto.queue.spring_jakarta.kafka.producer`, `auto.queue.spring7.kafka.producer`
- Spring Kafka consumer: `auto.queue.spring.kafka.consumer`, `auto.queue.spring_jakarta.kafka.consumer`, `auto.queue.spring7.kafka.consumer`

## Files to inspect when changing queue tracing

- Core option and conventions:
- `sentry/src/main/java/io/sentry/SentryOptions.java`
- `sentry/src/main/java/io/sentry/ExternalOptions.java`
- `sentry/src/main/java/io/sentry/SpanDataConvention.java`
- Raw Kafka:
- `sentry-kafka/src/main/java/io/sentry/kafka/SentryKafkaProducer.java`
- `sentry-kafka/src/main/java/io/sentry/kafka/SentryKafkaConsumerTracing.java`
- `sentry-kafka/src/test/kotlin/io/sentry/kafka/*Test.kt`
- Spring Kafka:
- `sentry-spring*/src/main/java/io/sentry/**/kafka/*`
- `sentry-spring*/src/test/kotlin/io/sentry/**/kafka/*Test.kt`
- `sentry-spring-boot*/src/main/java/io/sentry/**/SentryAutoConfiguration.java`
- `sentry-spring-boot*/src/test/kotlin/io/sentry/**/SentryKafkaAutoConfigurationTest.kt`

## Related rules

Also fetch:
- `options` when changing `enableQueueTracing` or configuration surfaces.
- `scopes` when changing consumer scope forking/lifecycle.
- `opentelemetry` when changing coexistence with OTel auto-instrumentation.
- `api` when changing public Kafka APIs or option methods.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
.configurator { it.isUseShakeGesture = true }
.create()
```
- Add support for Kafka ([#5249](https://github.com/getsentry/sentry-java/pull/5249))
- You will need to add the `sentry-kafka` dependency and opt-in via the new option.
- Set `options.setEnableQueueTracing(true)` on `Sentry.init`
- Or set `sentry.enable-queue-tracing=true` in `application.properties`
- For Spring Boot Kafka is auto instrumented and no further configuration is needed.
- also see https://docs.sentry.io/platforms/java/guides/spring-boot/integrations/kafka/
- When using `kafka-clients` directly
- you need to wrap your `KafkaProducer` via `SentryKafkaProducer.wrap(kafkaProducer)` to get `queue.publish` spans
- and you may use our `SentryKafkaConsumerTracing.withTracing` helper to instrument the consumer side manually.
- also see https://docs.sentry.io/platforms/java/integrations/kafka/

### Fixes

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Sentry SDK for Java and Android
| sentry | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry) | 21 |
| sentry-jul | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-jul?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-jul) |
| sentry-jdbc | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-jdbc?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-jdbc) |
| sentry-kafka | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-kafka?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-kafka) |
| sentry-apollo | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-apollo?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-apollo) | 21 |
| sentry-apollo-3 | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-apollo-3?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-apollo-3) | 21 |
| sentry-apollo-4 | [![Maven Central Version](https://img.shields.io/maven-central/v/io.sentry/sentry-apollo-4?style=for-the-badge&logo=sentry&color=green)](https://central.sonatype.com/artifact/io.sentry/sentry-apollo-4) | 21 |
Expand Down
1 change: 1 addition & 0 deletions buildSrc/src/main/java/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ object Config {
val SENTRY_JCACHE_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.jcache"
val SENTRY_QUARTZ_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.quartz"
val SENTRY_JDBC_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.jdbc"
val SENTRY_KAFKA_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.kafka"
val SENTRY_OPENFEATURE_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.openfeature"
val SENTRY_LAUNCHDARKLY_SERVER_SDK_NAME = "$SENTRY_JAVA_SDK_NAME.launchdarkly-server"
val SENTRY_LAUNCHDARKLY_ANDROID_SDK_NAME = "$SENTRY_ANDROID_SDK_NAME.launchdarkly"
Expand Down
5 changes: 5 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ springboot3-starter-security = { module = "org.springframework.boot:spring-boot-
springboot3-starter-jdbc = { module = "org.springframework.boot:spring-boot-starter-jdbc", version.ref = "springboot3" }
springboot3-starter-actuator = { module = "org.springframework.boot:spring-boot-starter-actuator", version.ref = "springboot3" }
springboot3-starter-cache = { module = "org.springframework.boot:spring-boot-starter-cache", version.ref = "springboot3" }
spring-kafka2 = { module = "org.springframework.kafka:spring-kafka", version = "2.8.11" }
spring-kafka3 = { module = "org.springframework.kafka:spring-kafka", version = "3.3.5" }
spring-kafka4 = { module = "org.springframework.kafka:spring-kafka" }
kafka-clients = { module = "org.apache.kafka:kafka-clients", version = "3.8.1" }
springboot4-otel = { module = "io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter", version.ref = "otelInstrumentation" }
springboot4-resttestclient = { module = "org.springframework.boot:spring-boot-resttestclient", version.ref = "springboot4" }
springboot4-starter = { module = "org.springframework.boot:spring-boot-starter", version.ref = "springboot4" }
Expand All @@ -200,6 +204,7 @@ springboot4-starter-webclient = { module = "org.springframework.boot:spring-boot
springboot4-starter-jdbc = { module = "org.springframework.boot:spring-boot-starter-jdbc", version.ref = "springboot4" }
springboot4-starter-actuator = { module = "org.springframework.boot:spring-boot-starter-actuator", version.ref = "springboot4" }
springboot4-starter-cache = { module = "org.springframework.boot:spring-boot-starter-cache", version.ref = "springboot4" }
springboot4-starter-kafka = { module = "org.springframework.boot:spring-boot-starter-kafka", version.ref = "springboot4" }
timber = { module = "com.jakewharton.timber:timber", version = "4.7.1" }

# Animalsniffer signature
Expand Down
5 changes: 5 additions & 0 deletions sentry-kafka/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# sentry-kafka

This module provides Kafka-native queue instrumentation for applications using `kafka-clients` directly.

Spring users should use the Sentry Spring (Boot) SDKs, which provide higher-fidelity consumer instrumentation via Spring Kafka hooks.
19 changes: 19 additions & 0 deletions sentry-kafka/api/sentry-kafka.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
public final class io/sentry/kafka/BuildConfig {
public static final field SENTRY_KAFKA_SDK_NAME Ljava/lang/String;
public static final field VERSION_NAME Ljava/lang/String;
}

public final class io/sentry/kafka/SentryKafkaConsumerTracing {
public static final field TRACE_ORIGIN Ljava/lang/String;
public static fun withTracing (Lorg/apache/kafka/clients/consumer/ConsumerRecord;Ljava/lang/Runnable;)V
public static fun withTracing (Lorg/apache/kafka/clients/consumer/ConsumerRecord;Ljava/util/concurrent/Callable;)Ljava/lang/Object;
}

public final class io/sentry/kafka/SentryKafkaProducer {
public static final field SENTRY_ENQUEUED_TIME_HEADER Ljava/lang/String;
public static final field TRACE_ORIGIN Ljava/lang/String;
public static fun wrap (Lorg/apache/kafka/clients/producer/Producer;)Lorg/apache/kafka/clients/producer/Producer;
public static fun wrap (Lorg/apache/kafka/clients/producer/Producer;Lio/sentry/IScopes;)Lorg/apache/kafka/clients/producer/Producer;
public static fun wrap (Lorg/apache/kafka/clients/producer/Producer;Lio/sentry/IScopes;Ljava/lang/String;)Lorg/apache/kafka/clients/producer/Producer;
}

83 changes: 83 additions & 0 deletions sentry-kafka/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import net.ltgt.gradle.errorprone.errorprone
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
`java-library`
id("io.sentry.javadoc")
alias(libs.plugins.kotlin.jvm)
jacoco
alias(libs.plugins.errorprone)
alias(libs.plugins.gradle.versions)
alias(libs.plugins.buildconfig)
}

tasks.withType<KotlinCompile>().configureEach {
compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8
}

dependencies {
api(projects.sentry)
compileOnly(libs.kafka.clients)
compileOnly(libs.jetbrains.annotations)
compileOnly(libs.nopen.annotations)

errorprone(libs.errorprone.core)
errorprone(libs.nopen.checker)
errorprone(libs.nullaway)

// tests
testImplementation(projects.sentryTestSupport)
testImplementation(kotlin(Config.kotlinStdLib))
testImplementation(libs.kotlin.test.junit)
testImplementation(libs.mockito.kotlin)
testImplementation(libs.mockito.inline)
testImplementation(libs.kafka.clients)
}

configure<SourceSetContainer> { test { java.srcDir("src/test/java") } }

jacoco { toolVersion = libs.versions.jacoco.get() }

tasks.jacocoTestReport {
reports {
xml.required.set(true)
html.required.set(false)
}
}

tasks {
jacocoTestCoverageVerification {
violationRules { rule { limit { minimum = Config.QualityPlugins.Jacoco.minimumCoverage } } }
}
check {
dependsOn(jacocoTestCoverageVerification)
dependsOn(jacocoTestReport)
}
}

tasks.withType<JavaCompile>().configureEach {
options.errorprone {
check("NullAway", net.ltgt.gradle.errorprone.CheckSeverity.ERROR)
option("NullAway:AnnotatedPackages", "io.sentry")
}
}

buildConfig {
useJavaOutput()
packageName("io.sentry.kafka")
buildConfigField("String", "SENTRY_KAFKA_SDK_NAME", "\"${Config.Sentry.SENTRY_KAFKA_SDK_NAME}\"")
buildConfigField("String", "VERSION_NAME", "\"${project.version}\"")
}

tasks.jar {
manifest {
attributes(
"Sentry-Version-Name" to project.version,
"Sentry-SDK-Name" to Config.Sentry.SENTRY_KAFKA_SDK_NAME,
"Sentry-SDK-Package-Name" to "maven:io.sentry:sentry-kafka",
"Implementation-Vendor" to "Sentry",
"Implementation-Title" to project.name,
"Implementation-Version" to project.version,
)
}
}
Loading
Loading