88import static io .opentelemetry .instrumentation .api .incubator .semconv .messaging .internal .MessagingExceptionEventExtractors .setMessagingProcessExceptionEventExtractor ;
99import static io .opentelemetry .instrumentation .api .incubator .semconv .messaging .internal .MessagingExceptionEventExtractors .setMessagingSendExceptionEventExtractor ;
1010import static io .opentelemetry .instrumentation .api .instrumenter .AttributesExtractor .constant ;
11+ import static io .opentelemetry .instrumentation .api .internal .SemconvStability .emitOldMessagingSemconv ;
12+ import static io .opentelemetry .instrumentation .api .internal .SemconvStability .emitStableMessagingSemconv ;
1113
1214import io .opentelemetry .api .OpenTelemetry ;
1315import io .opentelemetry .api .common .AttributeKey ;
14- import io .opentelemetry .instrumentation .api .incubator .semconv .messaging .MessageOperation ;
16+ import io .opentelemetry .api .common .AttributesBuilder ;
17+ import io .opentelemetry .context .Context ;
1518import io .opentelemetry .instrumentation .api .incubator .semconv .messaging .MessagingAttributesExtractor ;
1619import io .opentelemetry .instrumentation .api .incubator .semconv .messaging .MessagingAttributesGetter ;
20+ import io .opentelemetry .instrumentation .api .incubator .semconv .messaging .MessagingOperationType ;
21+ import io .opentelemetry .instrumentation .api .incubator .semconv .messaging .MessagingSpanKindExtractor ;
1722import io .opentelemetry .instrumentation .api .incubator .semconv .messaging .MessagingSpanNameExtractor ;
23+ import io .opentelemetry .instrumentation .api .incubator .semconv .messaging .internal .MessagingProcessInstrumenterFactory ;
1824import io .opentelemetry .instrumentation .api .instrumenter .AttributesExtractor ;
1925import io .opentelemetry .instrumentation .api .instrumenter .Instrumenter ;
2026import io .opentelemetry .instrumentation .api .instrumenter .InstrumenterBuilder ;
21- import io .opentelemetry .instrumentation .api .instrumenter .SpanKindExtractor ;
22- import io .opentelemetry .instrumentation .api .instrumenter .SpanLinksExtractor ;
23- import io .opentelemetry .instrumentation .api .internal .PropagatorBasedSpanLinksExtractor ;
2427import java .util .List ;
28+ import javax .annotation .Nullable ;
2529import org .apache .rocketmq .client .hook .SendMessageContext ;
2630import org .apache .rocketmq .common .message .MessageExt ;
2731
@@ -32,24 +36,30 @@ class RocketMqInstrumenterFactory {
3236 // copied from MessagingIncubatingAttributes
3337 private static final AttributeKey <String > MESSAGING_OPERATION =
3438 AttributeKey .stringKey ("messaging.operation" );
39+ private static final AttributeKey <String > MESSAGING_OPERATION_NAME =
40+ AttributeKey .stringKey ("messaging.operation.name" );
41+ private static final AttributeKey <String > MESSAGING_OPERATION_TYPE =
42+ AttributeKey .stringKey ("messaging.operation.type" );
3543 private static final AttributeKey <String > MESSAGING_SYSTEM =
3644 AttributeKey .stringKey ("messaging.system" );
45+ private static final AttributeKey <Long > MESSAGING_BATCH_MESSAGE_COUNT =
46+ AttributeKey .longKey ("messaging.batch.message_count" );
3747
3848 static Instrumenter <SendMessageContext , Void > createProducerInstrumenter (
3949 OpenTelemetry openTelemetry ,
4050 List <String > capturedHeaders ,
4151 boolean captureExperimentalSpanAttributes ) {
4252
4353 RocketMqProducerAttributeGetter getter = new RocketMqProducerAttributeGetter ();
44- MessageOperation operation = MessageOperation . PUBLISH ;
54+ MessagingOperationType operationType = MessagingOperationType . SEND ;
4555
4656 InstrumenterBuilder <SendMessageContext , Void > instrumenterBuilder =
4757 Instrumenter .<SendMessageContext , Void >builder (
4858 openTelemetry ,
4959 INSTRUMENTATION_NAME ,
50- MessagingSpanNameExtractor .create (getter , operation ))
60+ MessagingSpanNameExtractor .create (getter , operationType ))
5161 .addAttributesExtractor (
52- buildMessagingAttributesExtractor (getter , operation , capturedHeaders ));
62+ buildMessagingAttributesExtractor (getter , operationType , capturedHeaders ));
5363 if (captureExperimentalSpanAttributes ) {
5464 instrumenterBuilder .addAttributesExtractor (
5565 new RocketMqProducerExperimentalAttributeExtractor ());
@@ -64,18 +74,43 @@ static RocketMqConsumerInstrumenter createConsumerInstrumenter(
6474 List <String > capturedHeaders ,
6575 boolean captureExperimentalSpanAttributes ) {
6676
67- InstrumenterBuilder <Void , Void > batchReceiveInstrumenterBuilder =
68- Instrumenter .<Void , Void >builder (
77+ InstrumenterBuilder <Integer , Void > batchReceiveInstrumenterBuilder =
78+ Instrumenter .<Integer , Void >builder (
6979 openTelemetry , INSTRUMENTATION_NAME , RocketMqInstrumenterFactory ::spanNameOnReceive )
70- .addAttributesExtractor (constant (MESSAGING_SYSTEM , "rocketmq" ))
71- .addAttributesExtractor (constant (MESSAGING_OPERATION , "receive" ));
80+ .addAttributesExtractor (constant (MESSAGING_SYSTEM , "rocketmq" ));
81+ if (emitOldMessagingSemconv ()) {
82+ batchReceiveInstrumenterBuilder .addAttributesExtractor (
83+ constant (MESSAGING_OPERATION , "receive" ));
84+ }
85+ if (emitStableMessagingSemconv ()) {
86+ batchReceiveInstrumenterBuilder
87+ .addAttributesExtractor (constant (MESSAGING_OPERATION_NAME , "receive" ))
88+ .addAttributesExtractor (constant (MESSAGING_OPERATION_TYPE , "receive" ))
89+ .addAttributesExtractor (
90+ new AttributesExtractor <Integer , Void >() {
91+ @ Override
92+ public void onStart (
93+ AttributesBuilder attributes , Context parentContext , Integer batchSize ) {
94+ attributes .put (MESSAGING_BATCH_MESSAGE_COUNT , batchSize );
95+ }
96+
97+ @ Override
98+ public void onEnd (
99+ AttributesBuilder attributes ,
100+ Context context ,
101+ Integer batchSize ,
102+ @ Nullable Void unused ,
103+ @ Nullable Throwable error ) {}
104+ });
105+ }
72106
73107 return new RocketMqConsumerInstrumenter (
74108 createProcessInstrumenter (
75109 openTelemetry , capturedHeaders , captureExperimentalSpanAttributes , false ),
76110 createProcessInstrumenter (
77111 openTelemetry , capturedHeaders , captureExperimentalSpanAttributes , true ),
78- batchReceiveInstrumenterBuilder .buildInstrumenter (SpanKindExtractor .alwaysConsumer ()));
112+ batchReceiveInstrumenterBuilder .buildInstrumenter (
113+ MessagingSpanKindExtractor .create (MessagingOperationType .RECEIVE )));
79114 }
80115
81116 private static Instrumenter <MessageExt , Void > createProcessInstrumenter (
@@ -85,45 +120,39 @@ private static Instrumenter<MessageExt, Void> createProcessInstrumenter(
85120 boolean batch ) {
86121
87122 RocketMqConsumerAttributeGetter getter = new RocketMqConsumerAttributeGetter ();
88- MessageOperation operation = MessageOperation .PROCESS ;
123+ MessagingOperationType operationType = MessagingOperationType .PROCESS ;
89124
90125 InstrumenterBuilder <MessageExt , Void > builder =
91126 Instrumenter .builder (
92127 openTelemetry ,
93128 INSTRUMENTATION_NAME ,
94- MessagingSpanNameExtractor .create (getter , operation ));
129+ MessagingSpanNameExtractor .create (getter , operationType ));
95130
96131 builder .addAttributesExtractor (
97- buildMessagingAttributesExtractor (getter , operation , capturedHeaders ));
132+ buildMessagingAttributesExtractor (getter , operationType , capturedHeaders ));
98133 if (captureExperimentalSpanAttributes ) {
99134 builder .addAttributesExtractor (new RocketMqConsumerExperimentalAttributeExtractor ());
100135 }
101136 setMessagingProcessExceptionEventExtractor (builder );
102137
103- if (batch ) {
104- SpanLinksExtractor <MessageExt > spanLinksExtractor =
105- new PropagatorBasedSpanLinksExtractor <>(
106- openTelemetry .getPropagators ().getTextMapPropagator (), new TextMapExtractAdapter ());
107-
108- return builder
109- .addSpanLinksExtractor (spanLinksExtractor )
110- .buildInstrumenter (SpanKindExtractor .alwaysConsumer ());
111- } else {
112- return builder .buildConsumerInstrumenter (new TextMapExtractAdapter ());
113- }
138+ return MessagingProcessInstrumenterFactory .create (
139+ builder ,
140+ openTelemetry .getPropagators ().getTextMapPropagator (),
141+ new TextMapExtractAdapter (),
142+ batch );
114143 }
115144
116145 private static <T > AttributesExtractor <T , Void > buildMessagingAttributesExtractor (
117146 MessagingAttributesGetter <T , Void > getter ,
118- MessageOperation operation ,
147+ MessagingOperationType operationType ,
119148 List <String > capturedHeaders ) {
120- return MessagingAttributesExtractor .builder (getter , operation )
149+ return MessagingAttributesExtractor .builderForOperationType (getter , operationType )
121150 .setCapturedHeaders (capturedHeaders )
122151 .build ();
123152 }
124153
125- private static String spanNameOnReceive (Void unused ) {
126- return "multiple_sources receive" ;
154+ private static String spanNameOnReceive (Integer unused ) {
155+ return emitStableMessagingSemconv () ? "receive multiple_sources" : "multiple_sources receive" ;
127156 }
128157
129158 private RocketMqInstrumenterFactory () {}
0 commit comments