55
66package io .opentelemetry .instrumentation .api .incubator .semconv .messaging ;
77
8+ import static io .opentelemetry .instrumentation .api .internal .SemconvStability .emitOldMessagingSemconv ;
9+ import static io .opentelemetry .instrumentation .api .internal .SemconvStability .emitStableMessagingSemconv ;
10+ import static io .opentelemetry .semconv .ErrorAttributes .ERROR_TYPE ;
11+
812import io .opentelemetry .api .common .AttributeKey ;
913import io .opentelemetry .api .common .AttributesBuilder ;
1014import io .opentelemetry .context .Context ;
1721
1822/**
1923 * Extractor of <a
20- * href="https://github.com/open-telemetry/semantic-conventions/blob/main /docs/messaging/messaging-spans.md">messaging
24+ * href="https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0 /docs/messaging/messaging-spans.md">messaging
2125 * attributes</a>.
2226 *
2327 * <p>This class delegates to a type-specific {@link MessagingAttributesGetter} for individual
@@ -29,8 +33,10 @@ public final class MessagingAttributesExtractor<REQUEST, RESPONSE>
2933 // copied from MessagingIncubatingAttributes
3034 private static final AttributeKey <Long > MESSAGING_BATCH_MESSAGE_COUNT =
3135 AttributeKey .longKey ("messaging.batch.message_count" );
32- private static final AttributeKey <String > MESSAGING_CLIENT_ID =
36+ private static final AttributeKey <String > MESSAGING_CLIENT_ID_OLD =
3337 AttributeKey .stringKey ("messaging.client_id" );
38+ private static final AttributeKey <String > MESSAGING_CLIENT_ID =
39+ AttributeKey .stringKey ("messaging.client.id" );
3440 private static final AttributeKey <Boolean > MESSAGING_DESTINATION_ANONYMOUS =
3541 AttributeKey .booleanKey ("messaging.destination.anonymous" );
3642 private static final AttributeKey <String > MESSAGING_DESTINATION_NAME =
@@ -51,6 +57,10 @@ public final class MessagingAttributesExtractor<REQUEST, RESPONSE>
5157 AttributeKey .stringKey ("messaging.message.id" );
5258 private static final AttributeKey <String > MESSAGING_OPERATION =
5359 AttributeKey .stringKey ("messaging.operation" );
60+ private static final AttributeKey <String > MESSAGING_OPERATION_NAME =
61+ AttributeKey .stringKey ("messaging.operation.name" );
62+ private static final AttributeKey <String > MESSAGING_OPERATION_TYPE =
63+ AttributeKey .stringKey ("messaging.operation.type" );
5464 private static final AttributeKey <String > MESSAGING_SYSTEM =
5565 AttributeKey .stringKey ("messaging.system" );
5666
@@ -61,26 +71,51 @@ public final class MessagingAttributesExtractor<REQUEST, RESPONSE>
6171 * with default configuration.
6272 */
6373 public static <REQUEST , RESPONSE > AttributesExtractor <REQUEST , RESPONSE > create (
64- MessagingAttributesGetter <REQUEST , RESPONSE > getter , MessageOperation operation ) {
74+ MessagingAttributesGetter <REQUEST , RESPONSE > getter , @ Nullable MessageOperation operation ) {
6575 return builder (getter , operation ).build ();
6676 }
6777
78+ /**
79+ * Creates the messaging attributes extractor with a system-specific v1.43 operation name.
80+ *
81+ * <p>The {@code operationName} is emitted as {@code messaging.operation.name}. The legacy {@code
82+ * messaging.operation} value remains derived from {@code operation}.
83+ */
84+ public static <REQUEST , RESPONSE > AttributesExtractor <REQUEST , RESPONSE > create (
85+ MessagingAttributesGetter <REQUEST , RESPONSE > getter ,
86+ MessageOperation operation ,
87+ String operationName ) {
88+ return builder (getter , operation , operationName ).build ();
89+ }
90+
6891 /**
6992 * Returns a new {@link MessagingAttributesExtractorBuilder} for the given {@link MessageOperation
7093 * operation} that can be used to configure the messaging attributes extractor.
7194 */
7295 public static <REQUEST , RESPONSE > MessagingAttributesExtractorBuilder <REQUEST , RESPONSE > builder (
73- MessagingAttributesGetter <REQUEST , RESPONSE > getter , MessageOperation operation ) {
96+ MessagingAttributesGetter <REQUEST , RESPONSE > getter , @ Nullable MessageOperation operation ) {
7497 return new MessagingAttributesExtractorBuilder <>(getter , operation );
7598 }
7699
100+ /**
101+ * Returns a new {@link MessagingAttributesExtractorBuilder} with a system-specific v1.43
102+ * operation name.
103+ */
104+ public static <REQUEST , RESPONSE > MessagingAttributesExtractorBuilder <REQUEST , RESPONSE > builder (
105+ MessagingAttributesGetter <REQUEST , RESPONSE > getter ,
106+ MessageOperation operation ,
107+ String operationName ) {
108+ return new MessagingAttributesExtractorBuilder <>(
109+ getter , MessagingOperation .create (operation , operationName ));
110+ }
111+
77112 private final MessagingAttributesGetter <REQUEST , RESPONSE > getter ;
78- private final MessageOperation operation ;
113+ @ Nullable private final MessagingOperation operation ;
79114 private final List <String > capturedHeaders ;
80115
81116 MessagingAttributesExtractor (
82117 MessagingAttributesGetter <REQUEST , RESPONSE > getter ,
83- MessageOperation operation ,
118+ @ Nullable MessagingOperation operation ,
84119 List <String > capturedHeaders ) {
85120 this .getter = getter ;
86121 this .operation = operation ;
@@ -93,7 +128,12 @@ public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST
93128 boolean isTemporaryDestination = getter .isTemporaryDestination (request );
94129 if (isTemporaryDestination ) {
95130 attributes .put (MESSAGING_DESTINATION_TEMPORARY , true );
96- attributes .put (MESSAGING_DESTINATION_NAME , TEMP_DESTINATION_NAME );
131+ if (emitStableMessagingSemconv ()) {
132+ attributes .put (MESSAGING_DESTINATION_NAME , getter .getDestination (request ));
133+ attributes .put (MESSAGING_DESTINATION_TEMPLATE , getter .getDestinationTemplate (request ));
134+ } else {
135+ attributes .put (MESSAGING_DESTINATION_NAME , TEMP_DESTINATION_NAME );
136+ }
97137 } else {
98138 attributes .put (MESSAGING_DESTINATION_NAME , getter .getDestination (request ));
99139 attributes .put (MESSAGING_DESTINATION_TEMPLATE , getter .getDestinationTemplate (request ));
@@ -106,9 +146,20 @@ public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST
106146 attributes .put (MESSAGING_MESSAGE_CONVERSATION_ID , getter .getConversationId (request ));
107147 attributes .put (MESSAGING_MESSAGE_BODY_SIZE , getter .getMessageBodySize (request ));
108148 attributes .put (MESSAGING_MESSAGE_ENVELOPE_SIZE , getter .getMessageEnvelopeSize (request ));
109- attributes .put (MESSAGING_CLIENT_ID , getter .getClientId (request ));
149+ if (emitOldMessagingSemconv ()) {
150+ attributes .put (MESSAGING_CLIENT_ID_OLD , getter .getClientId (request ));
151+ }
152+ if (emitStableMessagingSemconv ()) {
153+ attributes .put (MESSAGING_CLIENT_ID , getter .getClientId (request ));
154+ }
110155 if (operation != null ) {
111- attributes .put (MESSAGING_OPERATION , operation .operationName ());
156+ if (emitOldMessagingSemconv ()) {
157+ attributes .put (MESSAGING_OPERATION , operation .operation ().operationName ());
158+ }
159+ if (emitStableMessagingSemconv ()) {
160+ attributes .put (MESSAGING_OPERATION_NAME , operation .name ());
161+ attributes .put (MESSAGING_OPERATION_TYPE , operation .type ());
162+ }
112163 }
113164 }
114165
@@ -121,6 +172,9 @@ public void onEnd(
121172 @ Nullable Throwable error ) {
122173 attributes .put (MESSAGING_MESSAGE_ID , getter .getMessageId (request , response ));
123174 attributes .put (MESSAGING_BATCH_MESSAGE_COUNT , getter .getBatchMessageCount (request , response ));
175+ if (emitStableMessagingSemconv () && error != null ) {
176+ attributes .put (ERROR_TYPE , error .getClass ().getName ());
177+ }
124178
125179 for (String name : capturedHeaders ) {
126180 List <String > values = getter .getMessageHeader (request , name );
@@ -141,7 +195,7 @@ public SpanKey internalGetSpanKey() {
141195 return null ;
142196 }
143197
144- switch (operation ) {
198+ switch (operation . operation () ) {
145199 case PUBLISH :
146200 return SpanKey .PRODUCER ;
147201 case RECEIVE :
0 commit comments