diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java index 7219958cd15..f0ca9fbaf59 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfiguration.java @@ -37,6 +37,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.DataSourceUnwrapper; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; @@ -114,9 +115,13 @@ public class DataSourcePoolMetricsAutoConfiguration { @Autowired public void bindMetricsRegistryToHikariDataSources( Collection dataSources) { - dataSources.stream().filter(HikariDataSource.class::isInstance) - .map(HikariDataSource.class::cast) - .forEach(this::bindMetricsRegistryToHikariDataSource); + for (DataSource dataSource : dataSources) { + HikariDataSource hikariDataSource = DataSourceUnwrapper.unwrap(dataSource, + HikariDataSource.class); + if (hikariDataSource != null) { + bindMetricsRegistryToHikariDataSource(hikariDataSource); + } + } } private void bindMetricsRegistryToHikariDataSource(HikariDataSource hikari) { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java index 3644314fc1a..26aa383afe7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java @@ -27,6 +27,7 @@ import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.Test; +import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; @@ -39,6 +40,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.PriorityOrdered; +import org.springframework.jdbc.datasource.DelegatingDataSource; import static org.assertj.core.api.Assertions.assertThat; @@ -185,6 +187,25 @@ public class DataSourcePoolMetricsAutoConfigurationTests { }); } + @Test + public void hikariProxiedDataSourceCanBeInstrumented() { + this.contextRunner + .withUserConfiguration(ProxiedHikariDataSourcesConfiguration.class) + .withConfiguration( + AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .run((context) -> { + context.getBean("proxiedDataSource", DataSource.class) + .getConnection(); + context.getBean("delegateDataSource", DataSource.class) + .getConnection(); + MeterRegistry registry = context.getBean(MeterRegistry.class); + registry.get("hikaricp.connections").tags("pool", "firstDataSource") + .meter(); + registry.get("hikaricp.connections").tags("pool", "secondOne") + .meter(); + }); + } + @Test public void hikariDataSourceIsInstrumentedWithoutMetadataProvider() { this.contextRunner.withUserConfiguration(OneHikariDataSourceConfiguration.class) @@ -199,6 +220,14 @@ public class DataSourcePoolMetricsAutoConfigurationTests { }); } + private static HikariDataSource createHikariDataSource(String poolName) { + String url = "jdbc:hsqldb:mem:test-" + UUID.randomUUID(); + HikariDataSource hikariDataSource = DataSourceBuilder.create().url(url) + .type(HikariDataSource.class).build(); + hikariDataSource.setPoolName(poolName); + return hikariDataSource; + } + @Configuration static class BaseConfiguration { @@ -242,12 +271,20 @@ public class DataSourcePoolMetricsAutoConfigurationTests { return createHikariDataSource("secondOne"); } - private HikariDataSource createHikariDataSource(String poolName) { - String url = "jdbc:hsqldb:mem:test-" + UUID.randomUUID(); - HikariDataSource hikariDataSource = DataSourceBuilder.create().url(url) - .type(HikariDataSource.class).build(); - hikariDataSource.setPoolName(poolName); - return hikariDataSource; + } + + @Configuration + static class ProxiedHikariDataSourcesConfiguration { + + @Bean + public DataSource proxiedDataSource() { + return (DataSource) new ProxyFactory( + createHikariDataSource("firstDataSource")).getProxy(); + } + + @Bean + public DataSource delegateDataSource() { + return new DelegatingDataSource(createHikariDataSource("secondOne")); } } @@ -257,11 +294,7 @@ public class DataSourcePoolMetricsAutoConfigurationTests { @Bean public DataSource hikariDataSource() { - String url = "jdbc:hsqldb:mem:test-" + UUID.randomUUID(); - HikariDataSource hikariDataSource = DataSourceBuilder.create().url(url) - .type(HikariDataSource.class).build(); - hikariDataSource.setPoolName("hikariDataSource"); - return hikariDataSource; + return createHikariDataSource("hikariDataSource"); } }