Skip to content

Commit 0321a8a

Browse files
committed
Configure ObservationRegistry on JmsListener
Prior to this commit, we set in gh-37388 the ObservationRegistry on the auto-configured JmsTemplate bean. This enables observations and context propagation when sending JMS messages. This commit applies the same to the `DefaultJmsListenerContainerFactory` and the `DefaultJmsListenerContainerFactoryConfigurer`, in order to enable observations on `@JmsListener` annotated methods. This commit also refactors the support implemented in gh-37388 to avoid relying on a bean post processor and instead set the observation registry directly in the main auto-configuration: while Micrometer core is an actuator-only dependency, Micrometer Observation API is a compile dependnecy for spring-jms itself and there is no need to separate concerns there. Fixes gh-38613
1 parent d172b22 commit 0321a8a

File tree

10 files changed

+54
-169
lines changed

10 files changed

+54
-169
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/jms/JmsTemplateObservationAutoConfiguration.java

-72
This file was deleted.

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/jms/package-info.java

-20
This file was deleted.

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetri
7171
org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront.WavefrontMetricsExportAutoConfiguration
7272
org.springframework.boot.actuate.autoconfigure.observation.batch.BatchObservationAutoConfiguration
7373
org.springframework.boot.actuate.autoconfigure.observation.graphql.GraphQlObservationAutoConfiguration
74-
org.springframework.boot.actuate.autoconfigure.observation.jms.JmsTemplateObservationAutoConfiguration
7574
org.springframework.boot.actuate.autoconfigure.metrics.integration.IntegrationMetricsAutoConfiguration
7675
org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration
7776
org.springframework.boot.actuate.autoconfigure.metrics.jersey.JerseyServerMetricsAutoConfiguration

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/jms/JmsTemplateObservationAutoConfigurationTests.java

-70
This file was deleted.

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/DefaultJmsListenerContainerFactoryConfigurer.java

+13
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.time.Duration;
2020

21+
import io.micrometer.observation.ObservationRegistry;
2122
import jakarta.jms.ConnectionFactory;
2223
import jakarta.jms.ExceptionListener;
2324

@@ -49,6 +50,8 @@ public final class DefaultJmsListenerContainerFactoryConfigurer {
4950

5051
private JmsProperties jmsProperties;
5152

53+
private ObservationRegistry observationRegistry;
54+
5255
/**
5356
* Set the {@link DestinationResolver} to use or {@code null} if no destination
5457
* resolver should be associated with the factory by default.
@@ -93,6 +96,15 @@ void setJmsProperties(JmsProperties jmsProperties) {
9396
this.jmsProperties = jmsProperties;
9497
}
9598

99+
/**
100+
* Set the {@link ObservationRegistry} to use.
101+
* @param observationRegistry the {@link ObservationRegistry}
102+
* @since 3.2.1
103+
*/
104+
public void setObservationRegistry(ObservationRegistry observationRegistry) {
105+
this.observationRegistry = observationRegistry;
106+
}
107+
96108
/**
97109
* Configure the specified jms listener container factory. The factory can be further
98110
* tuned and default settings can be overridden.
@@ -115,6 +127,7 @@ public void configure(DefaultJmsListenerContainerFactory factory, ConnectionFact
115127
if (this.transactionManager == null && sessionProperties.getTransacted() == null) {
116128
factory.setSessionTransacted(true);
117129
}
130+
map.from(this.observationRegistry).to(factory::setObservationRegistry);
118131
map.from(sessionProperties::getTransacted).to(factory::setSessionTransacted);
119132
map.from(listenerProperties::isAutoStartup).to(factory::setAutoStartup);
120133
map.from(listenerProperties::formatConcurrency).to(factory::setConcurrency);

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsAnnotationDrivenConfiguration.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.autoconfigure.jms;
1818

19+
import io.micrometer.observation.ObservationRegistry;
1920
import jakarta.jms.ConnectionFactory;
2021
import jakarta.jms.ExceptionListener;
2122

@@ -53,15 +54,19 @@ class JmsAnnotationDrivenConfiguration {
5354

5455
private final ObjectProvider<ExceptionListener> exceptionListener;
5556

57+
private final ObjectProvider<ObservationRegistry> observationRegistry;
58+
5659
private final JmsProperties properties;
5760

5861
JmsAnnotationDrivenConfiguration(ObjectProvider<DestinationResolver> destinationResolver,
5962
ObjectProvider<JtaTransactionManager> transactionManager, ObjectProvider<MessageConverter> messageConverter,
60-
ObjectProvider<ExceptionListener> exceptionListener, JmsProperties properties) {
63+
ObjectProvider<ExceptionListener> exceptionListener,
64+
ObjectProvider<ObservationRegistry> observationRegistry, JmsProperties properties) {
6165
this.destinationResolver = destinationResolver;
6266
this.transactionManager = transactionManager;
6367
this.messageConverter = messageConverter;
6468
this.exceptionListener = exceptionListener;
69+
this.observationRegistry = observationRegistry;
6570
this.properties = properties;
6671
}
6772

@@ -73,6 +78,7 @@ DefaultJmsListenerContainerFactoryConfigurer jmsListenerContainerFactoryConfigur
7378
configurer.setTransactionManager(this.transactionManager.getIfUnique());
7479
configurer.setMessageConverter(this.messageConverter.getIfUnique());
7580
configurer.setExceptionListener(this.exceptionListener.getIfUnique());
81+
configurer.setObservationRegistry(this.observationRegistry.getIfUnique());
7682
configurer.setJmsProperties(this.properties);
7783
return configurer;
7884
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfiguration.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.time.Duration;
2020
import java.util.List;
2121

22+
import io.micrometer.observation.ObservationRegistry;
2223
import jakarta.jms.ConnectionFactory;
2324
import jakarta.jms.Message;
2425

@@ -74,12 +75,16 @@ protected static class JmsTemplateConfiguration {
7475

7576
private final ObjectProvider<MessageConverter> messageConverter;
7677

78+
private final ObjectProvider<ObservationRegistry> observationRegistry;
79+
7780
public JmsTemplateConfiguration(JmsProperties properties,
7881
ObjectProvider<DestinationResolver> destinationResolver,
79-
ObjectProvider<MessageConverter> messageConverter) {
82+
ObjectProvider<MessageConverter> messageConverter,
83+
ObjectProvider<ObservationRegistry> observationRegistry) {
8084
this.properties = properties;
8185
this.destinationResolver = destinationResolver;
8286
this.messageConverter = messageConverter;
87+
this.observationRegistry = observationRegistry;
8388
}
8489

8590
@Bean
@@ -91,6 +96,7 @@ public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
9196
template.setPubSubDomain(this.properties.isPubSubDomain());
9297
map.from(this.destinationResolver::getIfUnique).whenNonNull().to(template::setDestinationResolver);
9398
map.from(this.messageConverter::getIfUnique).whenNonNull().to(template::setMessageConverter);
99+
map.from(this.observationRegistry::getIfUnique).whenNonNull().to(template::setObservationRegistry);
94100
mapTemplateProperties(this.properties.getTemplate(), template);
95101
return template;
96102
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfigurationTests.java

+23
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.IOException;
2020

21+
import io.micrometer.observation.ObservationRegistry;
2122
import jakarta.jms.ConnectionFactory;
2223
import jakarta.jms.ExceptionListener;
2324
import jakarta.jms.Session;
@@ -258,6 +259,17 @@ void testDefaultContainerFactoryWithExceptionListener() {
258259
});
259260
}
260261

262+
@Test
263+
void testDefaultContainerFactoryWithObservationRegistry() {
264+
ObservationRegistry observationRegistry = mock(ObservationRegistry.class);
265+
this.contextRunner.withUserConfiguration(EnableJmsConfiguration.class)
266+
.withBean(ObservationRegistry.class, () -> observationRegistry)
267+
.run((context) -> {
268+
DefaultMessageListenerContainer container = getContainer(context, "jmsListenerContainerFactory");
269+
assertThat(container.getObservationRegistry()).isSameAs(observationRegistry);
270+
});
271+
}
272+
261273
@Test
262274
void testCustomContainerFactoryWithConfigurer() {
263275
this.contextRunner.withUserConfiguration(TestConfiguration9.class, EnableJmsConfiguration.class)
@@ -290,6 +302,17 @@ void testJmsTemplateWithDestinationResolver() {
290302
.isSameAs(context.getBean("myDestinationResolver")));
291303
}
292304

305+
@Test
306+
void testJmsTemplateWithObservationRegistry() {
307+
ObservationRegistry observationRegistry = mock(ObservationRegistry.class);
308+
this.contextRunner.withUserConfiguration(EnableJmsConfiguration.class)
309+
.withBean(ObservationRegistry.class, () -> observationRegistry)
310+
.run((context) -> {
311+
JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
312+
assertThat(jmsTemplate).extracting("observationRegistry").isSameAs(observationRegistry);
313+
});
314+
}
315+
293316
@Test
294317
void testJmsTemplateFullCustomization() {
295318
this.contextRunner.withUserConfiguration(MessageConvertersConfiguration.class)

spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc

+3-4
Original file line numberDiff line numberDiff line change
@@ -745,10 +745,9 @@ Metrics are tagged by the name of the executor, which is derived from the bean n
745745

746746
[[actuator.metrics.supported.jms]]
747747
==== JMS Metrics
748-
Auto-configuration enables the instrumentation of all available `JmsTemplate` beans.
749-
`JmsMessagingTemplate` instances built with instrumented `JmsTemplate` beans will also record observations.
750-
See the {spring-framework-docs}/integration/observability.html#observability.jms.publish[Spring Framework reference documentation for more information on produced observations].
751-
748+
Auto-configuration enables the instrumentation of all available `JmsTemplate` beans and `@JmsListener` annotated methods.
749+
This will produce `"jms.message.publish"` and `"jms.message.process"` metrics respectively.
750+
See the {spring-framework-docs}/integration/observability.html#observability.jms[Spring Framework reference documentation for more information on produced observations].
752751

753752

754753
[[actuator.metrics.supported.spring-mvc]]

src/checkstyle/import-control.xml

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?xml version="1.0"?>
22
<!DOCTYPE import-control PUBLIC "-//Checkstyle//DTD ImportControl Configuration 1.4//EN" "https://checkstyle.org/dtds/import_control_1_4.dtd">
33
<import-control pkg="org.springframework.boot">
4+
<allow pkg="io.micrometer.observation" />
45
<disallow pkg="io.micrometer" />
56
<disallow pkg="org.springframework.lang" />
67
<allow pkg=".*" regex="true" />

0 commit comments

Comments
 (0)