Skip to content

fix(otel): [Queue Instrumentation 34] Fix OTel messaging span mapping correctness#5337

Draft
adinauer wants to merge 6 commits intotest/queue-instrumentation-kafka-auto-config-filter-otelfrom
feat/queue-instrumentation-otel-messaging-mapping
Draft

fix(otel): [Queue Instrumentation 34] Fix OTel messaging span mapping correctness#5337
adinauer wants to merge 6 commits intotest/queue-instrumentation-kafka-auto-config-filter-otelfrom
feat/queue-instrumentation-otel-messaging-mapping

Conversation

@adinauer
Copy link
Copy Markdown
Member

@adinauer adinauer commented Apr 27, 2026

PR Stack (Queue Instrumentation)


📜 Description

Follow-up fixes to the OTel messaging span mapping introduced in [Queue Instrumentation 33]:

  • Gate ordering — when enableQueueTracing is on, check messaging.system before http.request.method so OTel AWS SDK SQS spans (which carry both attributes) are classified as queue spans, not HTTP spans.
  • create mapping — map the "create" operation type to queue.create instead of queue.publish, matching the spec.
  • settle mapping — add explicit "settle"queue.settle arm.
  • Javadoc — clarify enableQueueTracing getter/setter docs.
  • Sample cleanup — remove verbose explanatory comment block from sample application-kafka.properties.

💡 Motivation and Context

Review of Queue Instrumentation 33 surfaced several correctness and documentation issues (F002, F004, F007, F008 from internal review). This PR addresses them as a batch of small targeted fixes.

💚 How did you test it?

  • Added unit tests for gate ordering (messaging wins over HTTP when flag on; HTTP wins when flag off)
  • Added unit tests for createqueue.create and settlequeue.settle mappings
  • All 27 SpanDescriptionExtractorTest tests pass

📝 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

Continue addressing remaining review findings (F001, F005, F006, F009–F017).

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

#skip-changelog

adinauer and others added 6 commits April 27, 2026 05:15
…ans to Sentry queue ops

Wire OTel messaging spans into the Sentry Queues product when
`sentry.enable-queue-tracing=true` so OTel-only setups (e.g. the
agentless Spring Boot Jakarta sample) populate queue dashboards without
needing the Sentry-native Kafka interceptors.

`SpanDescriptionExtractor` now recognizes spans carrying
`messaging.system` and maps them to `queue.publish` / `queue.process` /
`queue.receive` ops, using the destination name as the description and
`TransactionNameSource.TASK`. Op selection prefers
`messaging.operation.type` (current OTel semconv), falls back to the
deprecated `messaging.operation`, and only as a last resort consults
`SpanKind` — `SpanKind.CONSUMER` is overloaded for both `receive` and
`process`, so attribute-driven mapping is required to disambiguate. The
extractor takes `SentryOptions` so the mapping stays gated; when the
flag is off, behavior is unchanged.

`SentrySpanExporter` additionally transfers the messaging attributes
(`system`, `destination.name`, `operation.type`, `message.id`,
`message.body.size`, `message.envelope.size`) onto root transactions.
Root transactions don't bulk-copy OTel attributes the way child spans
do, but the Queues product reads `trace.data.messaging.*`, so consumer
root transactions need them propagated explicitly. These are operational
metadata only (no payload contents), so the transfer is unconditional.

Add `MESSAGING_OPERATION_TYPE` and `MESSAGING_MESSAGE_ENVELOPE_SIZE` to
`SpanDataConvention` for use by the exporter and downstream
integrations. Document the OTel-mode behavior in the two Jakarta OTel
sample `application-kafka.properties` so users know the flag activates
the OTel remapping path here, not the Sentry-native Kafka auto-config
(which stays suppressed by its `@ConditionalOnMissingClass` OTel guard).
Some OTel instrumentations (notably aws-sdk-2.2 SQS) attach both
`http.request.method` and `messaging.system` to the same span. With the
previous gate order, those spans resolved to http.client and the Sentry
Queues product never lit up for one of the most common OTel-coexistence
targets.

When `enableQueueTracing` is true and `messaging.system` is present, map
to a queue.* op before the http and db checks. When the flag is off, the
existing http-first ordering is preserved.

Co-Authored-By: Claude <[email protected]>
…blish

The OTel messaging semconv defines "create" and "publish" as distinct
operations: "create" represents message construction, "publish" the
network send. Folding both into queue.publish risks double-counting
producer transactions on instrumentations that emit a separate create
span (per OTel semconv guidance).

Per the Sentry Queues telemetry spec
(https://develop.sentry.dev/sdk/telemetry/traces/modules/queues/),
queue.create is a canonical op distinct from queue.publish, so map
"create" to its spec-correct destination rather than dropping it.

Empirically, current Kafka OTel instrumentation does not emit a
separate create span, so this is a no-op for Kafka users today; the
change future-proofs other systems and any future Kafka OTel version.

Co-Authored-By: Claude <[email protected]>
The setEnableQueueTracing Javadoc said only "Whether queue operations
(publish, process) should be traced." — silent on the fact that the
flag also drives OTel messaging-span transformation when
sentry-opentelemetry is on the classpath.

Reword on both the getter and setter to make explicit that the flag
both emits Sentry-native queue spans and transforms OTel messaging
spans to match Sentry's queue conventions, so customers grepping
their IDE see what the flag does in either integration mode.

Co-Authored-By: Claude <[email protected]>
OTel messaging semconv defines messaging.operation.type=settle for
consumer ack/nack/reject spans (JMS, RabbitMQ, Pulsar acknowledge).
The switch had no case for "settle", so settle spans on
SpanKind.CONSUMER were falling through to the SpanKind fallback and
becoming queue.process — duplicating the real process span — while
on SpanKind.CLIENT they became the generic "queue" default.

queue.settle is one of the canonical Queues telemetry ops per
https://develop.sentry.dev/sdk/telemetry/traces/modules/queues/, so
add the explicit mapping.

Co-Authored-By: Claude <[email protected]>
The OTel Kafka sample properties carried a 10-line comment explaining
the OTel->Sentry remapping mechanism and SentryKafkaQueueConfiguration
suppression behavior. That belongs in the SDK docs, not in a sample
config — drop it so the property line speaks for itself.

Co-Authored-By: Claude <[email protected]>
@sentry
Copy link
Copy Markdown

sentry Bot commented Apr 27, 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

@github-actions
Copy link
Copy Markdown
Contributor

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 393.90 ms 465.78 ms 71.88 ms
Size 0 B 0 B 0 B

Baseline results on branch: test/queue-instrumentation-kafka-auto-config-filter-otel

Startup times

Revision Plain With Sentry Diff
89ac8f7 316.17 ms 354.36 ms 38.19 ms

App size

Revision Plain With Sentry Diff
89ac8f7 0 B 0 B 0 B

This was referenced Apr 27, 2026
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