Extend JMS observation scope to error handling
Prior to this commit, the JMS listener observations would only cover the actual listener invocation, but not the error handling phase. This means that all errors (including the handled ones) are marked as errors in the observation and that the observation is not current anymore when error handling happens. This commit aligns the behavior with the other Spring Framework instrumentations and ensures that the error handling phase is fully part of the observation recording. Closes gh-31559
This commit is contained in:
@@ -18,12 +18,15 @@ package org.springframework.jms.listener;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.tck.TestObservationRegistry;
|
||||
import jakarta.jms.MessageListener;
|
||||
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.artemis.junit.EmbeddedActiveMQExtension;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
@@ -76,6 +79,34 @@ class MessageListenerContainerObservationTests {
|
||||
listenerContainer.stop();
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "[{index}] {0}")
|
||||
@MethodSource("listenerContainers")
|
||||
void shouldHaveObservationScopeInErrorHandler(AbstractMessageListenerContainer listenerContainer) throws Exception {
|
||||
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
|
||||
jmsTemplate.convertAndSend("spring.test.observation", "message content");
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
AtomicReference<Observation> observationInErrorHandler = new AtomicReference<>();
|
||||
listenerContainer.setConnectionFactory(connectionFactory);
|
||||
listenerContainer.setObservationRegistry(registry);
|
||||
listenerContainer.setDestinationName("spring.test.observation");
|
||||
listenerContainer.setMessageListener((MessageListener) message -> {
|
||||
throw new IllegalStateException("error");
|
||||
});
|
||||
listenerContainer.setErrorHandler(error -> {
|
||||
observationInErrorHandler.set(registry.getCurrentObservation());
|
||||
latch.countDown();
|
||||
});
|
||||
listenerContainer.afterPropertiesSet();
|
||||
listenerContainer.start();
|
||||
latch.await(2, TimeUnit.SECONDS);
|
||||
Assertions.assertThat(observationInErrorHandler.get()).isNotNull();
|
||||
assertThat(registry).hasObservationWithNameEqualTo("jms.message.process")
|
||||
.that()
|
||||
.hasHighCardinalityKeyValue("messaging.destination.name", "spring.test.observation");
|
||||
listenerContainer.shutdown();
|
||||
listenerContainer.stop();
|
||||
}
|
||||
|
||||
static Stream<Arguments> listenerContainers() {
|
||||
return Stream.of(
|
||||
arguments(named(DefaultMessageListenerContainer.class.getSimpleName(), new DefaultMessageListenerContainer())),
|
||||
|
||||
Reference in New Issue
Block a user