Do not require DataSourcePoolMetrics to auto-configure Hikari meters
Closes gh-13330
This commit is contained in:
parent
27267a7090
commit
68cd27c47b
|
@ -50,44 +50,50 @@ import org.springframework.util.StringUtils;
|
||||||
@Configuration
|
@Configuration
|
||||||
@AutoConfigureAfter({ MetricsAutoConfiguration.class, DataSourceAutoConfiguration.class,
|
@AutoConfigureAfter({ MetricsAutoConfiguration.class, DataSourceAutoConfiguration.class,
|
||||||
SimpleMetricsExportAutoConfiguration.class })
|
SimpleMetricsExportAutoConfiguration.class })
|
||||||
@ConditionalOnBean({ DataSource.class, DataSourcePoolMetadataProvider.class,
|
@ConditionalOnBean({ DataSource.class, MeterRegistry.class })
|
||||||
MeterRegistry.class })
|
|
||||||
public class DataSourcePoolMetricsAutoConfiguration {
|
public class DataSourcePoolMetricsAutoConfiguration {
|
||||||
|
|
||||||
private static final String DATASOURCE_SUFFIX = "dataSource";
|
@Configuration
|
||||||
|
@ConditionalOnBean(DataSourcePoolMetadataProvider.class)
|
||||||
|
static class DataSourcePoolMetadataMetricsConfiguration {
|
||||||
|
|
||||||
private final MeterRegistry registry;
|
private static final String DATASOURCE_SUFFIX = "dataSource";
|
||||||
|
|
||||||
private final Collection<DataSourcePoolMetadataProvider> metadataProviders;
|
private final MeterRegistry registry;
|
||||||
|
|
||||||
public DataSourcePoolMetricsAutoConfiguration(MeterRegistry registry,
|
private final Collection<DataSourcePoolMetadataProvider> metadataProviders;
|
||||||
Collection<DataSourcePoolMetadataProvider> metadataProviders) {
|
|
||||||
this.registry = registry;
|
|
||||||
this.metadataProviders = metadataProviders;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Autowired
|
DataSourcePoolMetadataMetricsConfiguration(MeterRegistry registry,
|
||||||
public void bindDataSourcesToRegistry(Map<String, DataSource> dataSources) {
|
Collection<DataSourcePoolMetadataProvider> metadataProviders) {
|
||||||
dataSources.forEach(this::bindDataSourceToRegistry);
|
this.registry = registry;
|
||||||
}
|
this.metadataProviders = metadataProviders;
|
||||||
|
|
||||||
private void bindDataSourceToRegistry(String beanName, DataSource dataSource) {
|
|
||||||
String dataSourceName = getDataSourceName(beanName);
|
|
||||||
new DataSourcePoolMetrics(dataSource, this.metadataProviders, dataSourceName,
|
|
||||||
Collections.emptyList()).bindTo(this.registry);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the name of a DataSource based on its {@code beanName}.
|
|
||||||
* @param beanName the name of the data source bean
|
|
||||||
* @return a name for the given data source
|
|
||||||
*/
|
|
||||||
private String getDataSourceName(String beanName) {
|
|
||||||
if (beanName.length() > DATASOURCE_SUFFIX.length()
|
|
||||||
&& StringUtils.endsWithIgnoreCase(beanName, DATASOURCE_SUFFIX)) {
|
|
||||||
return beanName.substring(0, beanName.length() - DATASOURCE_SUFFIX.length());
|
|
||||||
}
|
}
|
||||||
return beanName;
|
|
||||||
|
@Autowired
|
||||||
|
public void bindDataSourcesToRegistry(Map<String, DataSource> dataSources) {
|
||||||
|
dataSources.forEach(this::bindDataSourceToRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bindDataSourceToRegistry(String beanName, DataSource dataSource) {
|
||||||
|
String dataSourceName = getDataSourceName(beanName);
|
||||||
|
new DataSourcePoolMetrics(dataSource, this.metadataProviders, dataSourceName,
|
||||||
|
Collections.emptyList()).bindTo(this.registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of a DataSource based on its {@code beanName}.
|
||||||
|
* @param beanName the name of the data source bean
|
||||||
|
* @return a name for the given data source
|
||||||
|
*/
|
||||||
|
private String getDataSourceName(String beanName) {
|
||||||
|
if (beanName.length() > DATASOURCE_SUFFIX.length()
|
||||||
|
&& StringUtils.endsWithIgnoreCase(beanName, DATASOURCE_SUFFIX)) {
|
||||||
|
return beanName.substring(0,
|
||||||
|
beanName.length() - DATASOURCE_SUFFIX.length());
|
||||||
|
}
|
||||||
|
return beanName;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||||
|
import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider;
|
||||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
@ -53,22 +54,29 @@ public class DataSourcePoolMetricsAutoConfigurationTests {
|
||||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
.withPropertyValues("spring.datasource.generate-unique-name=true")
|
.withPropertyValues("spring.datasource.generate-unique-name=true")
|
||||||
.with(MetricsRun.simple())
|
.with(MetricsRun.simple())
|
||||||
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
|
.withConfiguration(
|
||||||
DataSourcePoolMetricsAutoConfiguration.class))
|
AutoConfigurations.of(DataSourcePoolMetricsAutoConfiguration.class))
|
||||||
.withUserConfiguration(BaseConfiguration.class);
|
.withUserConfiguration(BaseConfiguration.class);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void autoConfiguredDataSourceIsInstrumented() {
|
public void autoConfiguredDataSourceIsInstrumented() {
|
||||||
this.contextRunner.run((context) -> {
|
this.contextRunner
|
||||||
context.getBean(DataSource.class).getConnection().getMetaData();
|
.withConfiguration(
|
||||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
registry.get("jdbc.connections.max").tags("name", "dataSource").meter();
|
.run((context) -> {
|
||||||
});
|
context.getBean(DataSource.class).getConnection().getMetaData();
|
||||||
|
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||||
|
registry.get("jdbc.connections.max").tags("name", "dataSource")
|
||||||
|
.meter();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void dataSourceInstrumentationCanBeDisabled() {
|
public void dataSourceInstrumentationCanBeDisabled() {
|
||||||
this.contextRunner.withPropertyValues("management.metrics.enable.jdbc=false")
|
this.contextRunner
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
|
.withPropertyValues("management.metrics.enable.jdbc=false")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.getBean(DataSource.class).getConnection().getMetaData();
|
context.getBean(DataSource.class).getConnection().getMetaData();
|
||||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||||
|
@ -79,7 +87,10 @@ public class DataSourcePoolMetricsAutoConfigurationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void allDataSourcesCanBeInstrumented() {
|
public void allDataSourcesCanBeInstrumented() {
|
||||||
this.contextRunner.withUserConfiguration(TwoDataSourcesConfiguration.class)
|
this.contextRunner
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
|
.withUserConfiguration(TwoDataSourcesConfiguration.class)
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.getBean("firstDataSource", DataSource.class).getConnection()
|
context.getBean("firstDataSource", DataSource.class).getConnection()
|
||||||
.getMetaData();
|
.getMetaData();
|
||||||
|
@ -94,11 +105,14 @@ public class DataSourcePoolMetricsAutoConfigurationTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void autoConfiguredHikariDataSourceIsInstrumented() {
|
public void autoConfiguredHikariDataSourceIsInstrumented() {
|
||||||
this.contextRunner.run((context) -> {
|
this.contextRunner
|
||||||
context.getBean(DataSource.class).getConnection();
|
.withConfiguration(
|
||||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
registry.get("hikaricp.connections").meter();
|
.run((context) -> {
|
||||||
});
|
context.getBean(DataSource.class).getConnection();
|
||||||
|
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||||
|
registry.get("hikaricp.connections").meter();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -106,6 +120,8 @@ public class DataSourcePoolMetricsAutoConfigurationTests {
|
||||||
this.contextRunner
|
this.contextRunner
|
||||||
.withPropertyValues(
|
.withPropertyValues(
|
||||||
"spring.datasource.schema:db/create-custom-schema.sql")
|
"spring.datasource.schema:db/create-custom-schema.sql")
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.getBean(DataSource.class).getConnection();
|
context.getBean(DataSource.class).getConnection();
|
||||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||||
|
@ -116,6 +132,8 @@ public class DataSourcePoolMetricsAutoConfigurationTests {
|
||||||
@Test
|
@Test
|
||||||
public void hikariCanBeInstrumentedAfterThePoolHasBeenSealed() {
|
public void hikariCanBeInstrumentedAfterThePoolHasBeenSealed() {
|
||||||
this.contextRunner.withUserConfiguration(HikariSealingConfiguration.class)
|
this.contextRunner.withUserConfiguration(HikariSealingConfiguration.class)
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
assertThat(context).hasNotFailed();
|
assertThat(context).hasNotFailed();
|
||||||
context.getBean(DataSource.class).getConnection();
|
context.getBean(DataSource.class).getConnection();
|
||||||
|
@ -127,6 +145,8 @@ public class DataSourcePoolMetricsAutoConfigurationTests {
|
||||||
@Test
|
@Test
|
||||||
public void hikariDataSourceInstrumentationCanBeDisabled() {
|
public void hikariDataSourceInstrumentationCanBeDisabled() {
|
||||||
this.contextRunner.withPropertyValues("management.metrics.enable.hikaricp=false")
|
this.contextRunner.withPropertyValues("management.metrics.enable.hikaricp=false")
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.getBean(DataSource.class).getConnection();
|
context.getBean(DataSource.class).getConnection();
|
||||||
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||||
|
@ -137,6 +157,8 @@ public class DataSourcePoolMetricsAutoConfigurationTests {
|
||||||
@Test
|
@Test
|
||||||
public void allHikariDataSourcesCanBeInstrumented() {
|
public void allHikariDataSourcesCanBeInstrumented() {
|
||||||
this.contextRunner.withUserConfiguration(TwoHikariDataSourcesConfiguration.class)
|
this.contextRunner.withUserConfiguration(TwoHikariDataSourcesConfiguration.class)
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.getBean("firstDataSource", DataSource.class).getConnection();
|
context.getBean("firstDataSource", DataSource.class).getConnection();
|
||||||
context.getBean("secondOne", DataSource.class).getConnection();
|
context.getBean("secondOne", DataSource.class).getConnection();
|
||||||
|
@ -151,6 +173,8 @@ public class DataSourcePoolMetricsAutoConfigurationTests {
|
||||||
@Test
|
@Test
|
||||||
public void someHikariDataSourcesCanBeInstrumented() {
|
public void someHikariDataSourcesCanBeInstrumented() {
|
||||||
this.contextRunner.withUserConfiguration(MixedDataSourcesConfiguration.class)
|
this.contextRunner.withUserConfiguration(MixedDataSourcesConfiguration.class)
|
||||||
|
.withConfiguration(
|
||||||
|
AutoConfigurations.of(DataSourceAutoConfiguration.class))
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
context.getBean("firstDataSource", DataSource.class).getConnection();
|
context.getBean("firstDataSource", DataSource.class).getConnection();
|
||||||
context.getBean("secondOne", DataSource.class).getConnection();
|
context.getBean("secondOne", DataSource.class).getConnection();
|
||||||
|
@ -161,6 +185,20 @@ public class DataSourcePoolMetricsAutoConfigurationTests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hikariDataSourceIsInstrumentedWithoutMetadataProvider() {
|
||||||
|
this.contextRunner.withUserConfiguration(OneHikariDataSourceConfiguration.class)
|
||||||
|
.run((context) -> {
|
||||||
|
assertThat(context)
|
||||||
|
.doesNotHaveBean(DataSourcePoolMetadataProvider.class);
|
||||||
|
context.getBean("hikariDataSource", DataSource.class).getConnection();
|
||||||
|
MeterRegistry registry = context.getBean(MeterRegistry.class);
|
||||||
|
assertThat(registry.get("hikaricp.connections").meter().getId()
|
||||||
|
.getTags())
|
||||||
|
.containsExactly(Tag.of("pool", "hikariDataSource"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class BaseConfiguration {
|
static class BaseConfiguration {
|
||||||
|
|
||||||
|
@ -214,6 +252,20 @@ public class DataSourcePoolMetricsAutoConfigurationTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class OneHikariDataSourceConfiguration {
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
static class MixedDataSourcesConfiguration {
|
static class MixedDataSourcesConfiguration {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue