Add observation for message channels (#3944)
* Add observation for message channels * Add observation for message channels The `MessageChannel.send()` is, essentially, only the point in Spring Integration where we produce a message and can emit a `PRODUCER` kind span. * Implement `IntegrationObservation.PRODUCER` infrastructure based on the `MessageSenderContext` * Implement an observation emission in the `AbstractMessageChannel` based on the mentioned `IntegrationObservation.PRODUCER` * Build a `MutableMessage.of(message)` to be able to modify message header in the `MessageSenderContext` via tracer `Propagator` or other tracing injection instrument * Document which components are instrumented with an `ObservationRegistry` * Fix language in docs Co-authored-by: Gary Russell <grussell@vmware.com> Co-authored-by: Gary Russell <grussell@vmware.com>
This commit is contained in:
@@ -58,10 +58,8 @@ import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.config.GlobalChannelInterceptor;
|
||||
import org.springframework.integration.handler.BridgeHandler;
|
||||
import org.springframework.integration.support.MutableMessage;
|
||||
import org.springframework.integration.support.MutableMessageBuilder;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.support.management.observation.IntegrationObservation;
|
||||
import org.springframework.integration.support.management.observation.MessageSenderContext;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
@@ -215,13 +213,12 @@ public class ObservationPropagationChannelInterceptorTests {
|
||||
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
|
||||
MutableMessage<String> message =
|
||||
(MutableMessage<String>) MutableMessageBuilder.withPayload("test")
|
||||
Message<String> message =
|
||||
MessageBuilder.withPayload("test")
|
||||
.setHeader(MessageHeaders.REPLY_CHANNEL, replyChannel)
|
||||
.build();
|
||||
|
||||
Observation.createNotStarted("sending", () -> new MessageSenderContext(message), this.observationRegistry)
|
||||
.observe(() -> this.testTracingChannel.send(message));
|
||||
this.testTracingChannel.send(message);
|
||||
|
||||
Message<?> receive = replyChannel.receive();
|
||||
|
||||
@@ -238,7 +235,11 @@ public class ObservationPropagationChannelInterceptorTests {
|
||||
.reportedSpans()
|
||||
.hasSize(2)
|
||||
.satisfies(simpleSpans -> SpansAssert.assertThat(simpleSpans)
|
||||
.hasASpanWithName("sending")
|
||||
.assertThatASpanWithNameEqualTo("testTracingChannel send")
|
||||
.hasTag("spring.integration.type", "producer")
|
||||
.hasTag("spring.integration.name", "testTracingChannel")
|
||||
.hasKindEqualTo(Span.Kind.PRODUCER)
|
||||
.backToSpans()
|
||||
.assertThatASpanWithNameEqualTo("testBridge receive")
|
||||
.hasTag("foo", "some foo value")
|
||||
.hasTag("bar", "some bar value")
|
||||
@@ -315,8 +316,10 @@ public class ObservationPropagationChannelInterceptorTests {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExecutorChannel testTracingChannel() {
|
||||
return new ExecutorChannel(Executors.newSingleThreadExecutor());
|
||||
public ExecutorChannel testTracingChannel(ObservationRegistry observationRegistry) {
|
||||
ExecutorChannel channel = new ExecutorChannel(Executors.newSingleThreadExecutor());
|
||||
channel.registerObservationRegistry(observationRegistry);
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -92,7 +92,11 @@ public class IntegrationObservabilityZipkinTests extends SampleTestRunner {
|
||||
.hasTag(IntegrationObservation.HandlerTags.COMPONENT_NAME.asString(), "observedEndpoint")
|
||||
.hasTag(IntegrationObservation.HandlerTags.COMPONENT_TYPE.asString(), "handler")
|
||||
.hasKindEqualTo(Span.Kind.CONSUMER))
|
||||
.hasSize(2);
|
||||
.hasASpanWithName("queueChannel send", spanAssert -> spanAssert
|
||||
.hasTag(IntegrationObservation.ProducerTags.COMPONENT_NAME.asString(), "queueChannel")
|
||||
.hasTag(IntegrationObservation.ProducerTags.COMPONENT_TYPE.asString(), "producer")
|
||||
.hasKindEqualTo(Span.Kind.PRODUCER))
|
||||
.hasSize(3);
|
||||
|
||||
MeterRegistryAssert.assertThat(getMeterRegistry())
|
||||
.hasTimerWithNameAndTags("spring.integration.handler",
|
||||
@@ -108,7 +112,7 @@ public class IntegrationObservabilityZipkinTests extends SampleTestRunner {
|
||||
@EnableIntegration
|
||||
@EnableIntegrationManagement(
|
||||
observationPatterns = {
|
||||
"${spring.integration.management.observation-patterns:observedEndpoint,testInboundGateway}",
|
||||
"${spring.integration.management.observation-patterns:testInboundGateway,queueChannel,observedEndpoint}",
|
||||
"${spring.integration.management.observation-patterns:}"
|
||||
})
|
||||
public static class ObservationIntegrationTestConfiguration {
|
||||
|
||||
Reference in New Issue
Block a user