Skip to content

Commit 8a9f68d

Browse files
committed
Migrate RabbitMQ messaging telemetry to v1.43
1 parent 9b5ec57 commit 8a9f68d

18 files changed

Lines changed: 724 additions & 137 deletions

File tree

instrumentation/rabbitmq-2.7/javaagent/build.gradle.kts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,14 @@ tasks {
4444
systemProperty("metadataConfig", "otel.instrumentation.rabbitmq.experimental-span-attributes=true")
4545
}
4646

47+
val testMessagingPreview = register<Test>("testMessagingPreview") {
48+
testClassesDirs = sourceSets.test.get().output.classesDirs
49+
classpath = sourceSets.test.get().runtimeClasspath
50+
jvmArgs("-Dotel.semconv-stability.preview=messaging")
51+
systemProperty("metadataConfig", "otel.semconv-stability.preview=messaging")
52+
}
53+
4754
check {
48-
dependsOn(testExperimental)
55+
dependsOn(testExperimental, testMessagingPreview)
4956
}
5057
}

instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/v2_7/RabbitChannelNetAttributesGetter.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,25 @@
66
package io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7;
77

88
import io.opentelemetry.instrumentation.api.semconv.network.NetworkAttributesGetter;
9+
import io.opentelemetry.instrumentation.api.semconv.network.ServerAttributesGetter;
910
import java.net.Inet4Address;
1011
import java.net.Inet6Address;
1112
import java.net.InetAddress;
1213
import javax.annotation.Nullable;
1314

14-
class RabbitChannelNetAttributesGetter implements NetworkAttributesGetter<ChannelAndMethod, Void> {
15+
class RabbitChannelNetAttributesGetter
16+
implements NetworkAttributesGetter<ChannelAndMethod, Void>,
17+
ServerAttributesGetter<ChannelAndMethod> {
18+
19+
@Override
20+
public String getServerAddress(ChannelAndMethod channelAndMethod) {
21+
return channelAndMethod.getChannel().getConnection().getAddress().getHostAddress();
22+
}
23+
24+
@Override
25+
public Integer getServerPort(ChannelAndMethod channelAndMethod) {
26+
return channelAndMethod.getChannel().getConnection().getPort();
27+
}
1528

1629
@Nullable
1730
@Override

instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/v2_7/RabbitDeliveryAttributesGetter.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
package io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7;
77

8+
import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableMessagingSemconv;
9+
import static io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7.RabbitInstrumenterHelper.consumerDestinationName;
10+
import static io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7.RabbitInstrumenterHelper.isGeneratedQueueName;
811
import static java.util.Collections.emptyList;
912
import static java.util.Collections.singletonList;
1013

@@ -24,11 +27,13 @@ public String getSystem(DeliveryRequest request) {
2427
@Nullable
2528
@Override
2629
public String getDestination(DeliveryRequest request) {
27-
if (request.getEnvelope() != null) {
28-
return normalizeExchangeName(request.getEnvelope().getExchange());
29-
} else {
30-
return null;
30+
if (emitStableMessagingSemconv()) {
31+
return consumerDestinationName(
32+
request.getEnvelope().getExchange(),
33+
request.getEnvelope().getRoutingKey(),
34+
request.getQueue());
3135
}
36+
return normalizeExchangeName(request.getEnvelope().getExchange());
3237
}
3338

3439
@Nullable
@@ -48,7 +53,7 @@ public boolean isTemporaryDestination(DeliveryRequest request) {
4853

4954
@Override
5055
public boolean isAnonymousDestination(DeliveryRequest request) {
51-
return false;
56+
return isGeneratedQueueName(request.getQueue());
5257
}
5358

5459
@Nullable

instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/v2_7/RabbitDeliveryExtraAttributesExtractor.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,22 @@
55

66
package io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7;
77

8+
import static io.opentelemetry.api.common.AttributeKey.longKey;
9+
import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableMessagingSemconv;
810
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY;
911

1012
import com.rabbitmq.client.Envelope;
13+
import io.opentelemetry.api.common.AttributeKey;
1114
import io.opentelemetry.api.common.AttributesBuilder;
1215
import io.opentelemetry.context.Context;
1316
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
1417
import javax.annotation.Nullable;
1518

1619
class RabbitDeliveryExtraAttributesExtractor implements AttributesExtractor<DeliveryRequest, Void> {
1720

21+
private static final AttributeKey<Long> MESSAGING_RABBITMQ_MESSAGE_DELIVERY_TAG =
22+
longKey("messaging.rabbitmq.message.delivery_tag");
23+
1824
@Override
1925
public void onStart(
2026
AttributesBuilder attributes, Context parentContext, DeliveryRequest request) {
@@ -23,6 +29,9 @@ public void onStart(
2329
if (routingKey != null && !routingKey.isEmpty()) {
2430
attributes.put(MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY, routingKey);
2531
}
32+
if (emitStableMessagingSemconv()) {
33+
attributes.put(MESSAGING_RABBITMQ_MESSAGE_DELIVERY_TAG, envelope.getDeliveryTag());
34+
}
2635
}
2736

2837
@Override

instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/v2_7/RabbitDeliveryNetAttributesGetter.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,25 @@
66
package io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7;
77

88
import io.opentelemetry.instrumentation.api.semconv.network.NetworkAttributesGetter;
9+
import io.opentelemetry.instrumentation.api.semconv.network.ServerAttributesGetter;
910
import java.net.Inet4Address;
1011
import java.net.Inet6Address;
1112
import java.net.InetAddress;
1213
import javax.annotation.Nullable;
1314

14-
class RabbitDeliveryNetAttributesGetter implements NetworkAttributesGetter<DeliveryRequest, Void> {
15+
class RabbitDeliveryNetAttributesGetter
16+
implements NetworkAttributesGetter<DeliveryRequest, Void>,
17+
ServerAttributesGetter<DeliveryRequest> {
18+
19+
@Override
20+
public String getServerAddress(DeliveryRequest request) {
21+
return request.getConnection().getAddress().getHostAddress();
22+
}
23+
24+
@Override
25+
public Integer getServerPort(DeliveryRequest request) {
26+
return request.getConnection().getPort();
27+
}
1528

1629
@Nullable
1730
@Override

instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/v2_7/RabbitInstrumenterHelper.java

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
package io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7;
77

8+
import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableMessagingSemconv;
89
import static io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7.RabbitSingletons.CHANNEL_AND_METHOD_CONTEXT_KEY;
10+
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_DESTINATION_ANONYMOUS;
911
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME;
1012
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY;
1113

@@ -17,6 +19,7 @@
1719
import io.opentelemetry.context.Context;
1820
import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil;
1921
import java.util.Map;
22+
import javax.annotation.Nullable;
2023

2124
public class RabbitInstrumenterHelper {
2225
static final AttributeKey<String> RABBITMQ_COMMAND = AttributeKey.stringKey("rabbitmq.command");
@@ -33,8 +36,19 @@ public static RabbitInstrumenterHelper helper() {
3336

3437
public void onPublish(Span span, String exchange, String routingKey) {
3538
String exchangeName = normalizeExchangeName(exchange);
36-
span.setAttribute(MESSAGING_DESTINATION_NAME, exchangeName);
37-
span.updateName(exchangeName + " publish");
39+
if (emitStableMessagingSemconv()) {
40+
String destinationName = producerDestinationName(exchange, routingKey);
41+
span.setAttribute(MESSAGING_DESTINATION_NAME, destinationName);
42+
boolean anonymousDestination =
43+
isDefaultExchange(exchange) && isGeneratedQueueName(routingKey);
44+
if (anonymousDestination) {
45+
span.setAttribute(MESSAGING_DESTINATION_ANONYMOUS, true);
46+
}
47+
span.updateName(anonymousDestination ? "publish" : "publish " + destinationName);
48+
} else {
49+
span.setAttribute(MESSAGING_DESTINATION_NAME, exchangeName);
50+
span.updateName(exchangeName + " publish");
51+
}
3852
if (routingKey != null && !routingKey.isEmpty()) {
3953
span.setAttribute(MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY, routingKey);
4054
}
@@ -58,7 +72,66 @@ public void onProps(Context context, Span span, AMQP.BasicProperties props) {
5872
}
5973

6074
private static String normalizeExchangeName(String exchange) {
61-
return exchange == null || exchange.isEmpty() ? "<default>" : exchange;
75+
return isDefaultExchange(exchange) ? "<default>" : exchange;
76+
}
77+
78+
private static boolean isDefaultExchange(@Nullable String exchange) {
79+
return exchange == null || exchange.isEmpty();
80+
}
81+
82+
static boolean isGeneratedQueueName(@Nullable String queue) {
83+
if (queue == null) {
84+
return false;
85+
}
86+
if (queue.startsWith("amq.gen-") || queue.startsWith("spring.gen-")) {
87+
return true;
88+
}
89+
return isCanonicalUuid(queue);
90+
}
91+
92+
private static boolean isCanonicalUuid(String value) {
93+
if (value.length() != 36) {
94+
return false;
95+
}
96+
for (int i = 0; i < value.length(); i++) {
97+
char ch = value.charAt(i);
98+
if (i == 8 || i == 13 || i == 18 || i == 23) {
99+
if (ch != '-') {
100+
return false;
101+
}
102+
} else if (!((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f'))) {
103+
return false;
104+
}
105+
}
106+
return true;
107+
}
108+
109+
static String producerDestinationName(String exchange, String routingKey) {
110+
StringBuilder destination = new StringBuilder();
111+
appendDestinationPart(destination, exchange);
112+
appendDestinationPart(destination, routingKey);
113+
return destination.length() == 0 ? "amq.default" : destination.toString();
114+
}
115+
116+
@Nullable
117+
static String consumerDestinationName(String exchange, String routingKey, String queue) {
118+
StringBuilder destination = new StringBuilder();
119+
appendDestinationPart(destination, exchange);
120+
appendDestinationPart(destination, routingKey);
121+
if (queue != null && !queue.equals(routingKey)) {
122+
appendDestinationPart(destination, queue);
123+
}
124+
return destination.length() == 0 ? null : destination.toString();
125+
}
126+
127+
private static void appendDestinationPart(StringBuilder destination, String part) {
128+
if (part == null || part.isEmpty()) {
129+
return;
130+
}
131+
if (destination.length() != 0) {
132+
destination.append(':');
133+
}
134+
destination.append(part);
62135
}
63136

64137
public static void onCommand(Span span, Command command) {

instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/v2_7/RabbitReceiveAttributesGetter.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
package io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7;
77

8+
import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableMessagingSemconv;
9+
import static io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7.RabbitInstrumenterHelper.consumerDestinationName;
10+
import static io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7.RabbitInstrumenterHelper.isGeneratedQueueName;
811
import static java.util.Collections.emptyList;
912
import static java.util.Collections.singletonList;
1013

@@ -25,11 +28,17 @@ public String getSystem(ReceiveRequest request) {
2528
@Nullable
2629
@Override
2730
public String getDestination(ReceiveRequest request) {
28-
if (request.getResponse() != null) {
29-
return normalizeExchangeName(request.getResponse().getEnvelope().getExchange());
30-
} else {
31+
GetResponse response = request.getResponse();
32+
if (emitStableMessagingSemconv()) {
33+
return consumerDestinationName(
34+
response == null ? null : response.getEnvelope().getExchange(),
35+
response == null ? null : response.getEnvelope().getRoutingKey(),
36+
request.getQueue());
37+
}
38+
if (response == null) {
3139
return null;
3240
}
41+
return normalizeExchangeName(response.getEnvelope().getExchange());
3342
}
3443

3544
@Nullable
@@ -49,7 +58,7 @@ public boolean isTemporaryDestination(ReceiveRequest request) {
4958

5059
@Override
5160
public boolean isAnonymousDestination(ReceiveRequest request) {
52-
return false;
61+
return isGeneratedQueueName(request.getQueue());
5362
}
5463

5564
@Nullable
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7;
7+
8+
import static io.opentelemetry.api.common.AttributeKey.longKey;
9+
import static io.opentelemetry.instrumentation.api.internal.SemconvStability.emitStableMessagingSemconv;
10+
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY;
11+
12+
import com.rabbitmq.client.GetResponse;
13+
import io.opentelemetry.api.common.AttributeKey;
14+
import io.opentelemetry.api.common.AttributesBuilder;
15+
import io.opentelemetry.context.Context;
16+
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
17+
import javax.annotation.Nullable;
18+
19+
class RabbitReceiveExtraAttributesExtractor
20+
implements AttributesExtractor<ReceiveRequest, GetResponse> {
21+
22+
private static final AttributeKey<Long> MESSAGING_RABBITMQ_MESSAGE_DELIVERY_TAG =
23+
longKey("messaging.rabbitmq.message.delivery_tag");
24+
25+
@Override
26+
public void onStart(
27+
AttributesBuilder attributes, Context parentContext, ReceiveRequest request) {}
28+
29+
@Override
30+
public void onEnd(
31+
AttributesBuilder attributes,
32+
Context context,
33+
ReceiveRequest request,
34+
@Nullable GetResponse response,
35+
@Nullable Throwable error) {
36+
if (response == null) {
37+
response = request.getResponse();
38+
if (response == null) {
39+
return;
40+
}
41+
}
42+
String routingKey = response.getEnvelope().getRoutingKey();
43+
if (routingKey != null && !routingKey.isEmpty()) {
44+
attributes.put(MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY, routingKey);
45+
}
46+
if (emitStableMessagingSemconv()) {
47+
attributes.put(
48+
MESSAGING_RABBITMQ_MESSAGE_DELIVERY_TAG, response.getEnvelope().getDeliveryTag());
49+
}
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.rabbitmq.v2_7;
7+
8+
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_BATCH_MESSAGE_COUNT;
9+
10+
import com.rabbitmq.client.GetResponse;
11+
import io.opentelemetry.api.common.AttributesBuilder;
12+
import io.opentelemetry.context.Context;
13+
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
14+
import javax.annotation.Nullable;
15+
16+
final class RabbitReceiveMessageCountAttributesExtractor
17+
implements AttributesExtractor<ReceiveRequest, GetResponse> {
18+
19+
@Override
20+
public void onStart(
21+
AttributesBuilder attributes, Context parentContext, ReceiveRequest request) {}
22+
23+
@Override
24+
public void onEnd(
25+
AttributesBuilder attributes,
26+
Context context,
27+
ReceiveRequest request,
28+
@Nullable GetResponse response,
29+
@Nullable Throwable error) {
30+
attributes.put(MESSAGING_BATCH_MESSAGE_COUNT, request.getResponse() == null ? 0 : 1);
31+
}
32+
}

instrumentation/rabbitmq-2.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rabbitmq/v2_7/RabbitReceiveNetAttributesGetter.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,25 @@
77

88
import com.rabbitmq.client.GetResponse;
99
import io.opentelemetry.instrumentation.api.semconv.network.NetworkAttributesGetter;
10+
import io.opentelemetry.instrumentation.api.semconv.network.ServerAttributesGetter;
1011
import java.net.Inet4Address;
1112
import java.net.Inet6Address;
1213
import java.net.InetAddress;
1314
import javax.annotation.Nullable;
1415

1516
class RabbitReceiveNetAttributesGetter
16-
implements NetworkAttributesGetter<ReceiveRequest, GetResponse> {
17+
implements NetworkAttributesGetter<ReceiveRequest, GetResponse>,
18+
ServerAttributesGetter<ReceiveRequest> {
19+
20+
@Override
21+
public String getServerAddress(ReceiveRequest request) {
22+
return request.getConnection().getAddress().getHostAddress();
23+
}
24+
25+
@Override
26+
public Integer getServerPort(ReceiveRequest request) {
27+
return request.getConnection().getPort();
28+
}
1729

1830
@Nullable
1931
@Override

0 commit comments

Comments
 (0)