From e49d50fe9db86c7d2f1ff8a50e5fdb5d58836e2b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 12 Feb 2018 17:00:50 +0000 Subject: [PATCH] Improve testing of metrics auto-configuration Closes gh-11970 --- .../metrics/MetricsAutoConfiguration.java | 2 + ...metheusMetricsExportAutoConfiguration.java | 3 + .../SimpleMetricsExportAutoConfiguration.java | 1 - .../StatsdMetricsExportAutoConfiguration.java | 1 + ...itional-spring-configuration-metadata.json | 6 + ...ricsAutoConfigurationIntegrationTests.java | 117 ++++++ .../MetricsAutoConfigurationTests.java | 357 +++++++++++------- ...asMetricsExportAutoConfigurationTests.java | 112 ++++++ ...ogMetricsExportAutoConfigurationTests.java | 4 +- ...iaMetricsExportAutoConfigurationTests.java | 112 ++++++ ...teMetricsExportAutoConfigurationTests.java | 115 ++++++ ...uxMetricsExportAutoConfigurationTests.java | 112 ++++++ ...mxMetricsExportAutoConfigurationTests.java | 145 +++++++ ...usMetricsExportAutoConfigurationTests.java | 183 +++++++++ ...plMetricsExportAutoConfigurationTests.java | 107 ++++++ ...sdMetricsExportAutoConfigurationTests.java | 145 +++++++ ...urcePoolMetricsAutoConfigurationTests.java | 141 +++++++ .../metrics/test/MetricsRun.java | 4 + .../appendix-application-properties.adoc | 3 +- 19 files changed, 1531 insertions(+), 139 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationIntegrationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasMetricsExportAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaMetricsExportAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteMetricsExportAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxMetricsExportAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxMetricsExportAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplMetricsExportAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java index 0c162af9a56..b7f961b0dbf 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java @@ -130,6 +130,7 @@ public class MetricsAutoConfiguration { */ @Configuration @ConditionalOnClass(EnableIntegrationManagement.class) + @ConditionalOnProperty(value = "management.metrics.binders.integration.enabled", matchIfMissing = true) static class MetricsIntegrationConfiguration { @Bean(name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME) @@ -142,6 +143,7 @@ public class MetricsAutoConfiguration { } @Bean + @ConditionalOnMissingBean public SpringIntegrationMetrics springIntegrationMetrics( IntegrationManagementConfigurer configurer) { return new SpringIntegrationMetrics(configurer); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfiguration.java index 9ee56365004..5b51938b6e9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfiguration.java @@ -21,6 +21,7 @@ import io.micrometer.prometheus.PrometheusConfig; import io.micrometer.prometheus.PrometheusMeterRegistry; import io.prometheus.client.CollectorRegistry; +import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; @@ -73,6 +74,8 @@ public class PrometheusMetricsExportAutoConfiguration { public static class PrometheusScrapeEndpointConfiguration { @Bean + @ConditionalOnEnabledEndpoint + @ConditionalOnMissingBean public PrometheusScrapeEndpoint prometheusEndpoint( CollectorRegistry collectorRegistry) { return new PrometheusScrapeEndpoint(collectorRegistry); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfiguration.java index 4eaabe0e223..983f8182bfe 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfiguration.java @@ -49,7 +49,6 @@ import org.springframework.context.annotation.Configuration; public class SimpleMetricsExportAutoConfiguration { @Bean - @ConditionalOnMissingBean(MeterRegistry.class) public SimpleMeterRegistry simpleMeterRegistry(SimpleConfig config, Clock clock) { return new SimpleMeterRegistry(config, clock); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfiguration.java index eceb0c5bbfa..cbae0e601f6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfiguration.java @@ -54,6 +54,7 @@ public class StatsdMetricsExportAutoConfiguration { } @Bean + @ConditionalOnMissingBean public StatsdMeterRegistry statsdMeterRegistry(StatsdConfig statsdConfig, HierarchicalNameMapper hierarchicalNameMapper, Clock clock) { return new StatsdMeterRegistry(statsdConfig, hierarchicalNameMapper, clock); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 79c5bc529fc..9292b87717d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -178,6 +178,12 @@ { "name": "management.info.git.mode", "defaultValue": "simple" + }, + { + "name": "management.metrics.binders.integration.enabled", + "type": "java.lang.Boolean", + "description": "Whether to enable Spring Integration metrics.", + "defaultValue": true }, { "name": "management.metrics.binders.jvm.enabled", diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationIntegrationTests.java new file mode 100644 index 00000000000..0c9784b5d27 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationIntegrationTests.java @@ -0,0 +1,117 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.metrics; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.MockClock; +import io.micrometer.core.instrument.composite.CompositeMeterRegistry; +import io.micrometer.core.instrument.simple.SimpleConfig; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import io.micrometer.graphite.GraphiteMeterRegistry; +import io.micrometer.jmx.JmxMeterRegistry; +import org.junit.Test; + +import org.springframework.boot.actuate.autoconfigure.metrics.export.graphite.GraphiteMetricsExportAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxMetricsExportAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for metrics auto-configuration. + * + * @author Stephane Nicoll + */ +public class MetricsAutoConfigurationIntegrationTests { + + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .with(MetricsRun.simple()); + + @Test + public void propertyBasedMeterFilteringIsAutoConfigured() { + this.contextRunner.withPropertyValues("management.metrics.enable.my.org=false") + .run((context) -> { + MeterRegistry registry = context.getBean(MeterRegistry.class); + registry.timer("my.org.timer"); + assertThat(registry.find("my.org.timer").timer()).isNull(); + }); + } + + @Test + public void simpleMeterRegistryIsUsedAsAFallback() { + this.contextRunner + .run((context) -> assertThat(context.getBean(MeterRegistry.class)) + .isInstanceOf(SimpleMeterRegistry.class)); + } + + @Test + public void emptyCompositeIsCreatedWhenNoMeterRegistriesAreAutoConfigured() { + new ApplicationContextRunner().with(MetricsRun.limitedTo()).run((context) -> { + MeterRegistry registry = context.getBean(MeterRegistry.class); + assertThat(registry).isInstanceOf(CompositeMeterRegistry.class); + assertThat(((CompositeMeterRegistry) registry).getRegistries()).isEmpty(); + }); + } + + @Test + public void noCompositeIsCreatedWhenASingleMeterRegistryIsAutoConfigured() { + new ApplicationContextRunner() + .with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class)) + .run((context) -> assertThat(context.getBean(MeterRegistry.class)) + .isInstanceOf(GraphiteMeterRegistry.class)); + } + + @Test + public void noCompositeIsCreatedWithMultipleRegistriesAndOneThatIsPrimary() { + new ApplicationContextRunner() + .with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class, + JmxMetricsExportAutoConfiguration.class)) + .withUserConfiguration(PrimaryMeterRegistryConfiguration.class) + .run((context) -> assertThat(context.getBean(MeterRegistry.class)) + .isInstanceOf(SimpleMeterRegistry.class)); + } + + @Test + public void compositeCreatedWithMultipleRegistries() { + new ApplicationContextRunner() + .with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class, + JmxMetricsExportAutoConfiguration.class)) + .run((context) -> { + MeterRegistry registry = context.getBean(MeterRegistry.class); + assertThat(registry).isInstanceOf(CompositeMeterRegistry.class); + assertThat(((CompositeMeterRegistry) registry).getRegistries()) + .hasAtLeastOneElementOfType(GraphiteMeterRegistry.class) + .hasAtLeastOneElementOfType(JmxMeterRegistry.class); + }); + } + + @Configuration + static class PrimaryMeterRegistryConfiguration { + + @Primary + @Bean + public MeterRegistry simpleMeterRegistry() { + return new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock()); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java index dc524c57846..eec9e73695d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java @@ -16,222 +16,309 @@ package org.springframework.boot.actuate.autoconfigure.metrics; -import java.util.UUID; - -import javax.sql.DataSource; +import java.util.List; import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.MockClock; +import io.micrometer.core.instrument.binder.MeterBinder; +import io.micrometer.core.instrument.binder.jvm.JvmGcMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics; +import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; +import io.micrometer.core.instrument.binder.logging.LogbackMetrics; +import io.micrometer.core.instrument.binder.system.ProcessorMetrics; +import io.micrometer.core.instrument.binder.system.UptimeMetrics; import io.micrometer.core.instrument.composite.CompositeMeterRegistry; -import io.micrometer.core.instrument.simple.SimpleConfig; +import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import io.micrometer.graphite.GraphiteMeterRegistry; -import io.micrometer.jmx.JmxMeterRegistry; import org.junit.Test; -import org.springframework.boot.actuate.autoconfigure.metrics.export.graphite.GraphiteMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; +import org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetrics; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; +import org.springframework.integration.support.management.IntegrationManagementConfigurer; +import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; /** * Tests for {@link MetricsAutoConfiguration}. * - * @author Stephane Nicoll + * @author Andy Wilkinson */ public class MetricsAutoConfigurationTests { - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .with(MetricsRun.simple()); + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class)); @Test - public void autoConfiguredDataSourceIsInstrumented() { - this.contextRunner - .withConfiguration( - AutoConfigurations.of(DataSourceAutoConfiguration.class)) - .withPropertyValues("spring.datasource.generate-unique-name=true") - .run((context) -> { - context.getBean(DataSource.class).getConnection().getMetaData(); - MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.get("data.source.max.connections").tags("name", "dataSource") - .meter(); - }); + public void autoConfiguresAClock() { + this.runner.run((context) -> assertThat(context).hasSingleBean(Clock.class)); } @Test - public void autoConfiguredDataSourceWithCustomMetricName() { - this.contextRunner - .withConfiguration( - AutoConfigurations.of(DataSourceAutoConfiguration.class)) - .withPropertyValues("spring.datasource.generate-unique-name=true", - "management.metrics.jdbc.metric-name=custom.name") - .run((context) -> { - context.getBean(DataSource.class).getConnection().getMetaData(); - MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.get("custom.name.max.connections").tags("name", "dataSource") - .meter(); - }); + public void allowsACustomClockToBeUsed() { + this.runner.withUserConfiguration(CustomClockConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(Clock.class) + .hasBean("customClock")); } @Test - public void dataSourceInstrumentationCanBeDisabled() { - this.contextRunner - .withConfiguration( - AutoConfigurations.of(DataSourceAutoConfiguration.class)) - .withPropertyValues("spring.datasource.generate-unique-name=true", - "management.metrics.jdbc.instrument=false") - .run((context) -> { - context.getBean(DataSource.class).getConnection().getMetaData(); - MeterRegistry registry = context.getBean(MeterRegistry.class); - assertThat(registry.find("data.source.max.connections") - .tags("name", "dataSource").meter()).isNull(); - }); + public void autoConfiguresACompositeMeterRegistry() { + this.runner.run((context) -> { + assertThat(context).hasSingleBean(CompositeMeterRegistry.class); + assertThat(context.getBean(CompositeMeterRegistry.class).getRegistries()) + .isEmpty(); + }); } + @SuppressWarnings("unchecked") @Test - public void allDataSourcesCanBeInstrumented() { - this.contextRunner.withUserConfiguration(TwoDataSourcesConfiguration.class) - .withConfiguration( - AutoConfigurations.of(DataSourceAutoConfiguration.class)) + public void configuresMeterRegistries() { + this.runner.withUserConfiguration(MeterRegistryConfiguration.class) .run((context) -> { - context.getBean("firstDataSource", DataSource.class).getConnection() - .getMetaData(); - context.getBean("secondOne", DataSource.class).getConnection() - .getMetaData(); - MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.get("data.source.max.connections").tags("name", "first") - .meter(); - registry.get("data.source.max.connections").tags("name", "secondOne") - .meter(); + MeterRegistry meterRegistry = context.getBean(MeterRegistry.class); + List filters = (List) ReflectionTestUtils + .getField(meterRegistry, "filters"); + assertThat(filters).isNotEmpty(); + verify((MeterBinder) context.getBean("meterBinder")) + .bindTo(meterRegistry); + verify(context.getBean(MeterRegistryCustomizer.class)) + .customize(meterRegistry); }); } @Test - public void propertyBasedMeterFilter() { - this.contextRunner.withPropertyValues("management.metrics.enable.my.org=false") - .run((context) -> { - MeterRegistry registry = context.getBean(MeterRegistry.class); - registry.timer("my.org.timer"); - assertThat(registry.find("my.org.timer").timer()).isNull(); - }); + public void autoConfiguresJvmMetrics() { + this.runner.run((context) -> assertThat(context).hasSingleBean(JvmGcMetrics.class) + .hasSingleBean(JvmMemoryMetrics.class) + .hasSingleBean(JvmThreadMetrics.class)); } - /** - * The simple registry is off by default UNLESS there is no other registry - * implementation on the classpath, in which case it is on. - */ @Test - public void simpleWithNoCompositeCreated() { - this.contextRunner - .run((context) -> assertThat(context.getBean(MeterRegistry.class)) - .isInstanceOf(SimpleMeterRegistry.class)); + public void allowsJvmMetricsToBeDisabled() { + this.runner.withPropertyValues("management.metrics.binders.jvm.enabled=false") + .run((context) -> assertThat(context).doesNotHaveBean(JvmGcMetrics.class) + .doesNotHaveBean(JvmMemoryMetrics.class) + .doesNotHaveBean(JvmThreadMetrics.class)); } - /** - * An empty composite is created in the absence of any other registry implementation. - * This effectively no-ops instrumentation code throughout the application. - */ @Test - public void emptyCompositeCreated() { - new ApplicationContextRunner().with(MetricsRun.limitedTo()).run((context) -> { - MeterRegistry registry = context.getBean(MeterRegistry.class); - assertThat(registry).isInstanceOf(CompositeMeterRegistry.class); - assertThat(((CompositeMeterRegistry) registry).getRegistries()).isEmpty(); - }); + public void allowsCustomJvmGcMetricsToBeUsed() { + this.runner.withUserConfiguration(CustomJvmGcMetricsConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(JvmGcMetrics.class) + .hasBean("customJvmGcMetrics") + .hasSingleBean(JvmMemoryMetrics.class) + .hasSingleBean(JvmThreadMetrics.class)); } @Test - public void noCompositeCreatedWhenSingleImplementationIsEnabled() { - new ApplicationContextRunner() - .with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class)) - .run((context) -> assertThat(context.getBean(MeterRegistry.class)) - .isInstanceOf(GraphiteMeterRegistry.class)); + public void allowsCustomJvmMemoryMetricsToBeUsed() { + this.runner.withUserConfiguration(CustomJvmMemoryMetricsConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(JvmGcMetrics.class) + .hasSingleBean(JvmMemoryMetrics.class) + .hasBean("customJvmMemoryMetrics") + .hasSingleBean(JvmThreadMetrics.class)); } @Test - public void noCompositeCreatedWhenMultipleRegistriesButOneMarkedAsPrimary() { - new ApplicationContextRunner() - .with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class, - JmxMetricsExportAutoConfiguration.class)) - .withUserConfiguration(PrimarySimpleMeterRegistryConfiguration.class) - .run((context) -> assertThat(context.getBean(MeterRegistry.class)) - .isInstanceOf(SimpleMeterRegistry.class)); + public void allowsCustomJvmThreadMetricsToBeUsed() { + this.runner.withUserConfiguration(CustomJvmThreadMetricsConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(JvmGcMetrics.class) + .hasSingleBean(JvmMemoryMetrics.class) + .hasSingleBean(JvmThreadMetrics.class) + .hasBean("customJvmThreadMetrics")); } @Test - public void compositeCreatedWhenMultipleImplementationsAreEnabled() { - new ApplicationContextRunner() - .with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class, - JmxMetricsExportAutoConfiguration.class)) - .run((context) -> { - MeterRegistry registry = context.getBean(MeterRegistry.class); - assertThat(registry).isInstanceOf(CompositeMeterRegistry.class); - assertThat(((CompositeMeterRegistry) registry).getRegistries()) - .hasAtLeastOneElementOfType(GraphiteMeterRegistry.class) - .hasAtLeastOneElementOfType(JmxMeterRegistry.class); - }); + public void autoConfiguresLogbackMetrics() { + this.runner.run( + (context) -> assertThat(context).hasSingleBean(LogbackMetrics.class)); } @Test - public void autoConfiguresAClock() { - this.contextRunner.with(MetricsRun.limitedTo()) - .run((context) -> assertThat(context).hasSingleBean(Clock.class)); + public void allowsLogbackMetricsToBeDisabled() { + this.runner.withPropertyValues("management.metrics.binders.logback.enabled=false") + .run((context) -> assertThat(context) + .doesNotHaveBean(LogbackMetrics.class)); } @Test - public void allowsCustomClockToBeConfigured() { - this.contextRunner.with(MetricsRun.limitedTo()) - .withUserConfiguration(CustomClockConfiguration.class) - .run((context) -> assertThat(context).hasSingleBean(Clock.class) - .hasBean("customClock")); + public void allowsCustomLogbackMetricsToBeUsed() { + this.runner.withUserConfiguration(CustomLogbackMetricsConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(LogbackMetrics.class) + .hasBean("customLogbackMetrics")); + } + + @Test + public void autoConfiguresUptimeMetrics() { + this.runner + .run((context) -> assertThat(context).hasSingleBean(UptimeMetrics.class)); + } + + @Test + public void allowsUptimeMetricsToBeDisabled() { + this.runner.withPropertyValues("management.metrics.binders.uptime.enabled=false") + .run((context) -> assertThat(context) + .doesNotHaveBean(UptimeMetrics.class)); + } + + @Test + public void allowsCustomUptimeMetricsToBeUsed() { + this.runner.withUserConfiguration(CustomUptimeMetricsConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(UptimeMetrics.class) + .hasBean("customUptimeMetrics")); + } + + @Test + public void autoConfiguresProcessorMetrics() { + this.runner.run( + (context) -> assertThat(context).hasSingleBean(ProcessorMetrics.class)); + } + + @Test + public void allowsProcessorMetricsToBeDisabled() { + this.runner + .withPropertyValues("management.metrics.binders.processor.enabled=false") + .run((context) -> assertThat(context) + .doesNotHaveBean(ProcessorMetrics.class)); + } + + @Test + public void allowsCustomProcessorMetricsToBeUsed() { + this.runner.withUserConfiguration(CustomProcessorMetricsConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(ProcessorMetrics.class) + .hasBean("customProcessorMetrics")); + } + + @Test + public void autoConfiguresSpringIntegrationMetrics() { + this.runner.run((context) -> assertThat(context) + .hasSingleBean(SpringIntegrationMetrics.class)); + } + + @Test + public void allowsSpringIntegrationMetricsToBeDisabled() { + this.runner + .withPropertyValues( + "management.metrics.binders.integration.enabled=false") + .run((context) -> assertThat(context) + .doesNotHaveBean(SpringIntegrationMetrics.class)); + } + + @Test + public void allowsCustomSpringIntegrationMetricsToBeUsed() { + this.runner + .withUserConfiguration(CustomSpringIntegrationMetricsConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(SpringIntegrationMetrics.class) + .hasBean("customSpringIntegrationMetrics")); } @Configuration - static class PrimarySimpleMeterRegistryConfiguration { + static class CustomClockConfiguration { - @Primary @Bean - public MeterRegistry simpleMeterRegistry() { - return new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock()); + Clock customClock() { + return Clock.SYSTEM; } } @Configuration - static class TwoDataSourcesConfiguration { + static class MeterRegistryConfiguration { @Bean - public DataSource firstDataSource() { - return createDataSource(); + MeterRegistry meterRegistry() { + SimpleMeterRegistry meterRegistry = new SimpleMeterRegistry(); + return spy(meterRegistry); } @Bean - public DataSource secondOne() { - return createDataSource(); + @SuppressWarnings("rawtypes") + MeterRegistryCustomizer meterRegistryCustomizer() { + return mock(MeterRegistryCustomizer.class); } - private DataSource createDataSource() { - String url = "jdbc:hsqldb:mem:test-" + UUID.randomUUID(); - return DataSourceBuilder.create().url(url).build(); + @Bean + MeterBinder meterBinder() { + return mock(MeterBinder.class); } } @Configuration - static class CustomClockConfiguration { + static class CustomJvmGcMetricsConfiguration { @Bean - public Clock customClock() { - return Clock.SYSTEM; + JvmGcMetrics customJvmGcMetrics() { + return new JvmGcMetrics(); + } + + } + + @Configuration + static class CustomJvmMemoryMetricsConfiguration { + + @Bean + JvmMemoryMetrics customJvmMemoryMetrics() { + return new JvmMemoryMetrics(); + } + + } + + @Configuration + static class CustomJvmThreadMetricsConfiguration { + + @Bean + JvmThreadMetrics customJvmThreadMetrics() { + return new JvmThreadMetrics(); + } + + } + + @Configuration + static class CustomLogbackMetricsConfiguration { + + @Bean + LogbackMetrics customLogbackMetrics() { + return new LogbackMetrics(); + } + + } + + @Configuration + static class CustomUptimeMetricsConfiguration { + + @Bean + UptimeMetrics customUptimeMetrics() { + return new UptimeMetrics(); + } + + } + + @Configuration + static class CustomProcessorMetricsConfiguration { + + @Bean + ProcessorMetrics customProcessorMetrics() { + return new ProcessorMetrics(); + } + + } + + @Configuration + static class CustomSpringIntegrationMetricsConfiguration { + + @Bean + SpringIntegrationMetrics customSpringIntegrationMetrics( + IntegrationManagementConfigurer configurer) { + return new SpringIntegrationMetrics(configurer); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasMetricsExportAutoConfigurationTests.java new file mode 100644 index 00000000000..c1be4a74969 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/atlas/AtlasMetricsExportAutoConfigurationTests.java @@ -0,0 +1,112 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.metrics.export.atlas; + +import com.netflix.spectator.atlas.AtlasConfig; +import io.micrometer.atlas.AtlasMeterRegistry; +import io.micrometer.core.instrument.Clock; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link AtlasMetricsExportAutoConfiguration}. + * + * @author Andy Wilkinson + */ +public class AtlasMetricsExportAutoConfigurationTests { + + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(AtlasMetricsExportAutoConfiguration.class)); + + @Test + public void backsOffWithoutAClock() { + this.runner.run((context) -> assertThat(context) + .doesNotHaveBean(AtlasMeterRegistry.class)); + } + + @Test + public void autoConfiguresItsConfigAndMeterRegistry() { + this.runner.withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(AtlasMeterRegistry.class) + .hasSingleBean(AtlasConfig.class)); + } + + @Test + public void allowsCustomConfigToBeUsed() { + this.runner.withUserConfiguration(CustomConfigConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(AtlasMeterRegistry.class) + .hasSingleBean(AtlasConfig.class).hasBean("customConfig")); + } + + @Test + public void allowsCustomRegistryToBeUsed() { + this.runner.withUserConfiguration(CustomRegistryConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(AtlasMeterRegistry.class).hasBean("customRegistry") + .hasSingleBean(AtlasConfig.class)); + } + + @Configuration + static class BaseConfiguration { + + @Bean + public Clock clock() { + return Clock.SYSTEM; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomConfigConfiguration { + + @Bean + public AtlasConfig customConfig() { + return new AtlasConfig() { + + @Override + public String get(String k) { + return null; + } + + }; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomRegistryConfiguration { + + @Bean + public AtlasMeterRegistry customRegistry(AtlasConfig config, Clock clock) { + return new AtlasMeterRegistry(config, clock); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogMetricsExportAutoConfigurationTests.java index d209068fbf4..fe6253c7b96 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogMetricsExportAutoConfigurationTests.java @@ -30,7 +30,7 @@ import org.springframework.context.annotation.Import; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link DatadogMetricsExportAutoConfiguration} + * Tests for {@link DatadogMetricsExportAutoConfiguration}. * * @author Andy Wilkinson */ @@ -53,7 +53,7 @@ public class DatadogMetricsExportAutoConfigurationTests { } @Test - public void autoConfiguresItsConfigAndMeterRegistry() { + public void autoConfiguresConfigAndMeterRegistry() { this.runner.withUserConfiguration(BaseConfiguration.class) .withPropertyValues("management.metrics.export.datadog.api-key=abcde") .run((context) -> assertThat(context) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaMetricsExportAutoConfigurationTests.java new file mode 100644 index 00000000000..e920ea8d8e9 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/ganglia/GangliaMetricsExportAutoConfigurationTests.java @@ -0,0 +1,112 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia; + +import io.micrometer.core.instrument.Clock; +import io.micrometer.ganglia.GangliaConfig; +import io.micrometer.ganglia.GangliaMeterRegistry; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link GangliaMetricsExportAutoConfiguration}. + * + * @author Andy Wilkinson + */ +public class GangliaMetricsExportAutoConfigurationTests { + + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(GangliaMetricsExportAutoConfiguration.class)); + + @Test + public void backsOffWithoutAClock() { + this.runner.run((context) -> assertThat(context) + .doesNotHaveBean(GangliaMeterRegistry.class)); + } + + @Test + public void autoConfiguresItsConfigAndMeterRegistry() { + this.runner.withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(GangliaMeterRegistry.class) + .hasSingleBean(GangliaConfig.class)); + } + + @Test + public void allowsCustomConfigToBeUsed() { + this.runner.withUserConfiguration(CustomConfigConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(GangliaMeterRegistry.class) + .hasSingleBean(GangliaConfig.class).hasBean("customConfig")); + } + + @Test + public void allowsCustomRegistryToBeUsed() { + this.runner.withUserConfiguration(CustomRegistryConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(GangliaMeterRegistry.class) + .hasBean("customRegistry").hasSingleBean(GangliaConfig.class)); + } + + @Configuration + static class BaseConfiguration { + + @Bean + public Clock clock() { + return Clock.SYSTEM; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomConfigConfiguration { + + @Bean + public GangliaConfig customConfig() { + return new GangliaConfig() { + + @Override + public String get(String k) { + return null; + } + + }; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomRegistryConfiguration { + + @Bean + public GangliaMeterRegistry customRegistry(GangliaConfig config, Clock clock) { + return new GangliaMeterRegistry(config, clock); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteMetricsExportAutoConfigurationTests.java new file mode 100644 index 00000000000..158615423db --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/graphite/GraphiteMetricsExportAutoConfigurationTests.java @@ -0,0 +1,115 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.metrics.export.graphite; + +import io.micrometer.core.instrument.Clock; +import io.micrometer.graphite.GraphiteConfig; +import io.micrometer.graphite.GraphiteMeterRegistry; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link GraphiteMetricsExportAutoConfiguration}. + * + * @author Andy Wilkinson + */ +public class GraphiteMetricsExportAutoConfigurationTests { + + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(GraphiteMetricsExportAutoConfiguration.class)); + + @Test + public void backsOffWithoutAClock() { + this.runner.run((context) -> assertThat(context) + .doesNotHaveBean(GraphiteMeterRegistry.class)); + } + + @Test + public void autoConfiguresItsConfigAndMeterRegistry() { + this.runner.withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(GraphiteMeterRegistry.class) + .hasSingleBean(GraphiteConfig.class)); + } + + @Test + public void allowsCustomConfigToBeUsed() { + this.runner.withUserConfiguration(CustomConfigConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(GraphiteMeterRegistry.class) + .hasSingleBean(GraphiteConfig.class).hasBean("customConfig")); + } + + @Test + public void allowsCustomRegistryToBeUsed() { + this.runner.withUserConfiguration(CustomRegistryConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(GraphiteMeterRegistry.class) + .hasBean("customRegistry").hasSingleBean(GraphiteConfig.class)); + } + + @Configuration + static class BaseConfiguration { + + @Bean + public Clock clock() { + return Clock.SYSTEM; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomConfigConfiguration { + + @Bean + public GraphiteConfig customConfig() { + return new GraphiteConfig() { + + @Override + public String get(String k) { + if ("Graphite.apiKey".equals(k)) { + return "12345"; + } + return null; + } + + }; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomRegistryConfiguration { + + @Bean + public GraphiteMeterRegistry customRegistry(GraphiteConfig config, Clock clock) { + return new GraphiteMeterRegistry(config, clock); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxMetricsExportAutoConfigurationTests.java new file mode 100644 index 00000000000..b38e356b65e --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/influx/InfluxMetricsExportAutoConfigurationTests.java @@ -0,0 +1,112 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.metrics.export.influx; + +import io.micrometer.core.instrument.Clock; +import io.micrometer.influx.InfluxConfig; +import io.micrometer.influx.InfluxMeterRegistry; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link InfluxMetricsExportAutoConfiguration}. + * + * @author Andy Wilkinson + */ +public class InfluxMetricsExportAutoConfigurationTests { + + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(InfluxMetricsExportAutoConfiguration.class)); + + @Test + public void backsOffWithoutAClock() { + this.runner.run((context) -> assertThat(context) + .doesNotHaveBean(InfluxMeterRegistry.class)); + } + + @Test + public void autoConfiguresItsConfigAndMeterRegistry() { + this.runner.withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(InfluxMeterRegistry.class) + .hasSingleBean(InfluxConfig.class)); + } + + @Test + public void allowsCustomConfigToBeUsed() { + this.runner.withUserConfiguration(CustomConfigConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(InfluxMeterRegistry.class) + .hasSingleBean(InfluxConfig.class).hasBean("customConfig")); + } + + @Test + public void allowsCustomRegistryToBeUsed() { + this.runner.withUserConfiguration(CustomRegistryConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(InfluxMeterRegistry.class) + .hasBean("customRegistry").hasSingleBean(InfluxConfig.class)); + } + + @Configuration + static class BaseConfiguration { + + @Bean + public Clock clock() { + return Clock.SYSTEM; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomConfigConfiguration { + + @Bean + public InfluxConfig customConfig() { + return new InfluxConfig() { + + @Override + public String get(String k) { + return null; + } + + }; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomRegistryConfiguration { + + @Bean + public InfluxMeterRegistry customRegistry(InfluxConfig config, Clock clock) { + return new InfluxMeterRegistry(config, clock); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxMetricsExportAutoConfigurationTests.java new file mode 100644 index 00000000000..960c2603e89 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxMetricsExportAutoConfigurationTests.java @@ -0,0 +1,145 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.metrics.export.jmx; + +import io.micrometer.core.instrument.Clock; +import io.micrometer.core.instrument.Meter.Id; +import io.micrometer.core.instrument.config.NamingConvention; +import io.micrometer.core.instrument.util.HierarchicalNameMapper; +import io.micrometer.jmx.JmxConfig; +import io.micrometer.jmx.JmxMeterRegistry; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JmxMetricsExportAutoConfiguration}. + * + * @author Andy Wilkinson + */ +public class JmxMetricsExportAutoConfigurationTests { + + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(JmxMetricsExportAutoConfiguration.class)); + + @Test + public void backsOffWithoutAClock() { + this.runner.run( + (context) -> assertThat(context).doesNotHaveBean(JmxMeterRegistry.class)); + } + + @Test + public void autoConfiguresItsConfigMeterRegistryAndNameMapper() { + this.runner.withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(JmxMeterRegistry.class) + .hasSingleBean(JmxConfig.class) + .hasSingleBean(HierarchicalNameMapper.class)); + } + + @Test + public void allowsCustomConfigToBeUsed() { + this.runner.withUserConfiguration(CustomConfigConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(JmxMeterRegistry.class) + .hasSingleBean(JmxConfig.class).hasBean("customConfig") + .hasSingleBean(HierarchicalNameMapper.class)); + } + + @Test + public void allowsCustomRegistryToBeUsed() { + this.runner.withUserConfiguration(CustomRegistryConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(JmxMeterRegistry.class).hasBean("customRegistry") + .hasSingleBean(JmxConfig.class) + .hasSingleBean(HierarchicalNameMapper.class)); + } + + @Test + public void allowsCustomHierarchicalNameMapperToBeUsed() { + this.runner.withUserConfiguration(CustomNameMapperConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(JmxMeterRegistry.class) + .hasSingleBean(JmxConfig.class).hasBean("customNameMapper") + .hasSingleBean(HierarchicalNameMapper.class)); + } + + @Configuration + static class BaseConfiguration { + + @Bean + public Clock clock() { + return Clock.SYSTEM; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomConfigConfiguration { + + @Bean + public JmxConfig customConfig() { + return new JmxConfig() { + + @Override + public String get(String k) { + return null; + } + + }; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomRegistryConfiguration { + + @Bean + public JmxMeterRegistry customRegistry(JmxConfig config, Clock clock) { + return new JmxMeterRegistry(config, clock); + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomNameMapperConfiguration { + + @Bean + public HierarchicalNameMapper customNameMapper() { + return new HierarchicalNameMapper() { + + @Override + public String toHierarchicalName(Id id, NamingConvention convention) { + return "test"; + } + + }; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java new file mode 100644 index 00000000000..2ed12f47ecb --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfigurationTests.java @@ -0,0 +1,183 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus; + +import io.micrometer.core.instrument.Clock; +import io.micrometer.prometheus.PrometheusConfig; +import io.micrometer.prometheus.PrometheusMeterRegistry; +import io.prometheus.client.CollectorRegistry; +import org.junit.Test; + +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusScrapeEndpoint; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link PrometheusMetricsExportAutoConfiguration}. + * + * @author Andy Wilkinson + */ +public class PrometheusMetricsExportAutoConfigurationTests { + + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations + .of(PrometheusMetricsExportAutoConfiguration.class)); + + @Test + public void backsOffWithoutAClock() { + this.runner.run((context) -> assertThat(context) + .doesNotHaveBean(PrometheusMeterRegistry.class)); + } + + @Test + public void autoConfiguresItsConfigCollectorRegistryAndMeterRegistry() { + this.runner.withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(PrometheusMeterRegistry.class) + .hasSingleBean(CollectorRegistry.class) + .hasSingleBean(PrometheusConfig.class)); + } + + @Test + public void allowsCustomConfigToBeUsed() { + this.runner.withUserConfiguration(CustomConfigConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(PrometheusMeterRegistry.class) + .hasSingleBean(CollectorRegistry.class) + .hasSingleBean(PrometheusConfig.class).hasBean("customConfig")); + } + + @Test + public void allowsCustomRegistryToBeUsed() { + this.runner.withUserConfiguration(CustomRegistryConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(PrometheusMeterRegistry.class) + .hasBean("customRegistry").hasSingleBean(CollectorRegistry.class) + .hasSingleBean(PrometheusConfig.class)); + } + + @Test + public void allowsCustomCollectorRegistryToBeUsed() { + this.runner.withUserConfiguration(CustomCollectorRegistryConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(PrometheusMeterRegistry.class) + .hasBean("customCollectorRegistry") + .hasSingleBean(CollectorRegistry.class) + .hasSingleBean(PrometheusConfig.class)); + } + + @Test + public void addsScrapeEndpointToManagementContext() { + this.runner + .withConfiguration( + AutoConfigurations.of(ManagementContextAutoConfiguration.class)) + .withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(PrometheusScrapeEndpoint.class)); + } + + @Test + public void scrapeEndpointCanBeDisabled() { + this.runner + .withConfiguration( + AutoConfigurations.of(ManagementContextAutoConfiguration.class)) + .withPropertyValues("management.endpoint.prometheus.enabled=false") + .withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context) + .doesNotHaveBean(PrometheusScrapeEndpoint.class)); + } + + @Test + public void allowsCustomScrapeEndpointToBeUsed() { + this.runner + .withConfiguration( + AutoConfigurations.of(ManagementContextAutoConfiguration.class)) + .withUserConfiguration(CustomEndpointConfiguration.class) + .run((context) -> assertThat(context).hasBean("customEndpoint") + .hasSingleBean(PrometheusScrapeEndpoint.class)); + } + + @Configuration + static class BaseConfiguration { + + @Bean + public Clock clock() { + return Clock.SYSTEM; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomConfigConfiguration { + + @Bean + public PrometheusConfig customConfig() { + return new PrometheusConfig() { + + @Override + public String get(String k) { + return null; + } + + }; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomRegistryConfiguration { + + @Bean + public PrometheusMeterRegistry customRegistry(PrometheusConfig config, + CollectorRegistry collectorRegistry, Clock clock) { + return new PrometheusMeterRegistry(config, collectorRegistry, clock); + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomCollectorRegistryConfiguration { + + @Bean + public CollectorRegistry customCollectorRegistry() { + return new CollectorRegistry(); + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomEndpointConfiguration { + + @Bean + public PrometheusScrapeEndpoint customEndpoint( + CollectorRegistry collectorRegistry) { + return new PrometheusScrapeEndpoint(collectorRegistry); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplMetricsExportAutoConfigurationTests.java new file mode 100644 index 00000000000..04746174722 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimplMetricsExportAutoConfigurationTests.java @@ -0,0 +1,107 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.metrics.export.simple; + +import io.micrometer.core.instrument.Clock; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.simple.SimpleConfig; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * + * Tests for {@link SimpleMetricsExportAutoConfiguration}. + * + * @author Andy Wilkinson + */ +public class SimplMetricsExportAutoConfigurationTests { + + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(SimpleMetricsExportAutoConfiguration.class)); + + @Test + public void autoConfiguresConfigAndMeterRegistry() { + this.runner.withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(SimpleMeterRegistry.class) + .hasSingleBean(Clock.class).hasSingleBean(SimpleConfig.class)); + } + + @Test + public void allowsConfigToBeCustomized() { + this.runner.withUserConfiguration(CustomConfigConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(SimpleConfig.class) + .hasBean("customConfig")); + } + + @Test + public void backsOffEntirelyWithCustomMeterRegistry() { + this.runner.withUserConfiguration(CustomRegistryConfiguration.class) + .run((context) -> assertThat(context).hasSingleBean(MeterRegistry.class) + .hasBean("customRegistry").doesNotHaveBean(SimpleConfig.class)); + } + + @Configuration + static class BaseConfiguration { + + @Bean + public Clock clock() { + return Clock.SYSTEM; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomConfigConfiguration { + + @Bean + public SimpleConfig customConfig() { + return new SimpleConfig() { + + @Override + public String get(String k) { + return null; + } + + }; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomRegistryConfiguration { + + @Bean + public MeterRegistry customRegistry() { + return mock(MeterRegistry.class); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfigurationTests.java new file mode 100644 index 00000000000..1c8360e8605 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdMetricsExportAutoConfigurationTests.java @@ -0,0 +1,145 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd; + +import io.micrometer.core.instrument.Clock; +import io.micrometer.core.instrument.Meter.Id; +import io.micrometer.core.instrument.config.NamingConvention; +import io.micrometer.core.instrument.util.HierarchicalNameMapper; +import io.micrometer.statsd.StatsdConfig; +import io.micrometer.statsd.StatsdMeterRegistry; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link StatsdMetricsExportAutoConfiguration}. + * + * @author Andy Wilkinson + */ +public class StatsdMetricsExportAutoConfigurationTests { + + private final ApplicationContextRunner runner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(StatsdMetricsExportAutoConfiguration.class)); + + @Test + public void backsOffWithoutAClock() { + this.runner.run((context) -> assertThat(context) + .doesNotHaveBean(StatsdMeterRegistry.class)); + } + + @Test + public void autoConfiguresItsConfigMeterRegistryAndNameMapper() { + this.runner.withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(StatsdMeterRegistry.class) + .hasSingleBean(StatsdConfig.class) + .hasSingleBean(HierarchicalNameMapper.class)); + } + + @Test + public void allowsCustomConfigToBeUsed() { + this.runner.withUserConfiguration(CustomConfigConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(StatsdMeterRegistry.class) + .hasSingleBean(StatsdConfig.class).hasBean("customConfig") + .hasSingleBean(HierarchicalNameMapper.class)); + } + + @Test + public void allowsCustomRegistryToBeUsed() { + this.runner.withUserConfiguration(CustomRegistryConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(StatsdMeterRegistry.class) + .hasBean("customRegistry").hasSingleBean(StatsdConfig.class) + .hasSingleBean(HierarchicalNameMapper.class)); + } + + @Test + public void allowsCustomHierarchicalNameMapperToBeUsed() { + this.runner.withUserConfiguration(CustomNameMapperConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(StatsdMeterRegistry.class) + .hasSingleBean(StatsdConfig.class).hasBean("customNameMapper") + .hasSingleBean(HierarchicalNameMapper.class)); + } + + @Configuration + static class BaseConfiguration { + + @Bean + public Clock clock() { + return Clock.SYSTEM; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomConfigConfiguration { + + @Bean + public StatsdConfig customConfig() { + return new StatsdConfig() { + + @Override + public String get(String k) { + return null; + } + + }; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomRegistryConfiguration { + + @Bean + public StatsdMeterRegistry customRegistry(StatsdConfig config, Clock clock) { + return new StatsdMeterRegistry(config, clock); + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomNameMapperConfiguration { + + @Bean + public HierarchicalNameMapper customNameMapper() { + return new HierarchicalNameMapper() { + + @Override + public String toHierarchicalName(Id id, NamingConvention convention) { + return "test"; + } + + }; + } + + } + +} 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 new file mode 100644 index 00000000000..de70fd09fb4 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/jdbc/DataSourcePoolMetricsAutoConfigurationTests.java @@ -0,0 +1,141 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.metrics.jdbc; + +import java.util.UUID; + +import javax.sql.DataSource; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DataSourcePoolMetricsAutoConfiguration}. + * + * @author Stephane Nicoll + * @author Andy Wilkinson + */ +public class DataSourcePoolMetricsAutoConfigurationTests { + + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(DataSourcePoolMetricsAutoConfiguration.class)) + .withUserConfiguration(BaseConfiguration.class); + + @Test + public void autoConfiguredDataSourceIsInstrumented() { + this.contextRunner + .withConfiguration( + AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .withPropertyValues("spring.datasource.generate-unique-name=true") + .run((context) -> { + context.getBean(DataSource.class).getConnection().getMetaData(); + MeterRegistry registry = context.getBean(MeterRegistry.class); + registry.get("data.source.max.connections").tags("name", "dataSource") + .meter(); + }); + } + + @Test + public void autoConfiguredDataSourceWithCustomMetricName() { + this.contextRunner + .withConfiguration( + AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .withPropertyValues("spring.datasource.generate-unique-name=true", + "management.metrics.jdbc.metric-name=custom.name") + .run((context) -> { + context.getBean(DataSource.class).getConnection().getMetaData(); + MeterRegistry registry = context.getBean(MeterRegistry.class); + registry.get("custom.name.max.connections").tags("name", "dataSource") + .meter(); + }); + } + + @Test + public void dataSourceInstrumentationCanBeDisabled() { + this.contextRunner + .withConfiguration( + AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .withPropertyValues("spring.datasource.generate-unique-name=true", + "management.metrics.jdbc.instrument=false") + .run((context) -> { + context.getBean(DataSource.class).getConnection().getMetaData(); + MeterRegistry registry = context.getBean(MeterRegistry.class); + assertThat(registry.find("data.source.max.connections") + .tags("name", "dataSource").meter()).isNull(); + }); + } + + @Test + public void allDataSourcesCanBeInstrumented() { + this.contextRunner.withUserConfiguration(TwoDataSourcesConfiguration.class) + .withConfiguration( + AutoConfigurations.of(DataSourceAutoConfiguration.class)) + .run((context) -> { + context.getBean("firstDataSource", DataSource.class).getConnection() + .getMetaData(); + context.getBean("secondOne", DataSource.class).getConnection() + .getMetaData(); + MeterRegistry registry = context.getBean(MeterRegistry.class); + registry.get("data.source.max.connections").tags("name", "first") + .meter(); + registry.get("data.source.max.connections").tags("name", "secondOne") + .meter(); + }); + } + + @Configuration + static class BaseConfiguration { + + @Bean + public SimpleMeterRegistry simpleMeterRegistry() { + return new SimpleMeterRegistry(); + } + + } + + @Configuration + static class TwoDataSourcesConfiguration { + + @Bean + public DataSource firstDataSource() { + return createDataSource(); + } + + @Bean + public DataSource secondOne() { + return createDataSource(); + } + + private DataSource createDataSource() { + String url = "jdbc:hsqldb:mem:test-" + UUID.randomUUID(); + return DataSourceBuilder.create().url(url).build(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsRun.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsRun.java index 78ed4b10309..05f911dddd8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsRun.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/test/MetricsRun.java @@ -30,7 +30,9 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia.Gan import org.springframework.boot.actuate.autoconfigure.metrics.export.graphite.GraphiteMetricsExportAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.influx.InfluxMetricsExportAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxMetricsExportAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic.NewRelicMetricsExportAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx.SignalFxMetricsExportAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetricsExportAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration; @@ -60,8 +62,10 @@ public final class MetricsRun { implementations.add(GraphiteMetricsExportAutoConfiguration.class); implementations.add(InfluxMetricsExportAutoConfiguration.class); implementations.add(JmxMetricsExportAutoConfiguration.class); + implementations.add(NewRelicMetricsExportAutoConfiguration.class); implementations.add(PrometheusMetricsExportAutoConfiguration.class); implementations.add(SimpleMetricsExportAutoConfiguration.class); + implementations.add(SignalFxMetricsExportAutoConfiguration.class); implementations.add(StatsdMetricsExportAutoConfiguration.class); EXPORT_AUTO_CONFIGURATIONS = Collections.unmodifiableSet(implementations); } diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index a0d0cbc1294..27208dd3cd8 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -1242,7 +1242,7 @@ content into your application. Rather, pick only the properties that you need. # PROMETHEUS ENDPOINT ({sc-spring-boot-actuator}/metrics/export/prometheus/PrometheusScrapeEndpoint.{sc-ext}[PrometheusScrapeEndpoint]) management.endpoint.prometheus.cache.time-to-live=0ms # Maximum time that a response can be cached. - management.endpoint.prometheus.enabled= # Whether to enable the metrics endpoint. + management.endpoint.prometheus.enabled= # Whether to enable the Prometheus endpoint. # SCHEDULED TASKS ENDPOINT ({sc-spring-boot-actuator}/scheduling/ScheduledTasksEndpoint.{sc-ext}[ScheduledTasksEndpoint]) management.endpoint.scheduledtasks.cache.time-to-live=0ms # Maximum time that a response can be cached. @@ -1295,6 +1295,7 @@ content into your application. Rather, pick only the properties that you need. management.info.git.mode=simple # Mode to use to expose git information. # METRICS + management.metrics.binders.integration.enabled=true # Whether to enable Spring Integration metrics. management.metrics.binders.jvm.enabled=true # Whether to enable JVM metrics. management.metrics.binders.logback.enabled=true # Whether to enable Logback metrics. management.metrics.binders.processor.enabled=true # Whether to enable processor metrics.