Skip to content

Commit f85b2d7

Browse files
adinauerclaude
andcommitted
fix(otel): Prefer messaging over http mapping when queue tracing enabled
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 <noreply@anthropic.com>
1 parent e3eca3f commit f85b2d7

2 files changed

Lines changed: 50 additions & 8 deletions

File tree

sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SpanDescriptionExtractor.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ public final class SpanDescriptionExtractor {
2424
final @NotNull SentryOptions options) {
2525
final @NotNull Attributes attributes = otelSpan.getAttributes();
2626

27+
if (options.isEnableQueueTracing()) {
28+
final @Nullable String messagingSystem =
29+
attributes.get(MessagingIncubatingAttributes.MESSAGING_SYSTEM);
30+
if (messagingSystem != null) {
31+
return descriptionForMessagingSystem(otelSpan);
32+
}
33+
}
34+
2735
final @Nullable String httpMethod = attributes.get(HttpAttributes.HTTP_REQUEST_METHOD);
2836
if (httpMethod != null) {
2937
return descriptionForHttpMethod(otelSpan, httpMethod);
@@ -34,14 +42,6 @@ public final class SpanDescriptionExtractor {
3442
return descriptionForDbSystem(otelSpan);
3543
}
3644

37-
if (options.isEnableQueueTracing()) {
38-
final @Nullable String messagingSystem =
39-
attributes.get(MessagingIncubatingAttributes.MESSAGING_SYSTEM);
40-
if (messagingSystem != null) {
41-
return descriptionForMessagingSystem(otelSpan);
42-
}
43-
}
44-
4545
final @NotNull String name = otelSpan.getName();
4646
final @Nullable String maybeDescription =
4747
sentrySpan != null ? sentrySpan.getDescription() : name;

sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SpanDescriptionExtractorTest.kt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,48 @@ class SpanDescriptionExtractorTest {
364364
assertEquals("my-topic publish", info.description)
365365
}
366366

367+
@Test
368+
fun `messaging mapping wins over http when both attributes present and queue tracing enabled`() {
369+
// Some OTel instrumentations (e.g. aws-sdk-2.2 SQS) attach both messaging and http
370+
// attributes to the same span. Messaging is more specific and must win.
371+
givenSpanKind(SpanKind.PRODUCER)
372+
givenAttributes(
373+
mapOf(
374+
HttpAttributes.HTTP_REQUEST_METHOD to "POST",
375+
UrlAttributes.URL_FULL to "https://sqs.us-east-1.amazonaws.com/",
376+
MessagingIncubatingAttributes.MESSAGING_SYSTEM to "aws.sqs",
377+
MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME to "my-queue",
378+
MessagingIncubatingAttributes.MESSAGING_OPERATION_TYPE to "publish",
379+
)
380+
)
381+
382+
val info = whenExtractingSpanInfo(queueTracingEnabled = true)
383+
384+
assertEquals("queue.publish", info.op)
385+
assertEquals("my-queue", info.description)
386+
assertEquals(TransactionNameSource.TASK, info.transactionNameSource)
387+
}
388+
389+
@Test
390+
fun `http mapping wins over messaging when queue tracing disabled`() {
391+
givenSpanKind(SpanKind.CLIENT)
392+
givenAttributes(
393+
mapOf(
394+
HttpAttributes.HTTP_REQUEST_METHOD to "POST",
395+
UrlAttributes.URL_FULL to "https://sqs.us-east-1.amazonaws.com/",
396+
MessagingIncubatingAttributes.MESSAGING_SYSTEM to "aws.sqs",
397+
MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME to "my-queue",
398+
MessagingIncubatingAttributes.MESSAGING_OPERATION_TYPE to "publish",
399+
)
400+
)
401+
402+
val info = whenExtractingSpanInfo(queueTracingEnabled = false)
403+
404+
assertEquals("http.client", info.op)
405+
assertEquals("POST https://sqs.us-east-1.amazonaws.com/", info.description)
406+
assertEquals(TransactionNameSource.URL, info.transactionNameSource)
407+
}
408+
367409
@Test
368410
fun `uses span name as op and description if no relevant attributes`() {
369411
givenSpanName("span name")

0 commit comments

Comments
 (0)