Commit e49d50fe authored by Andy Wilkinson's avatar Andy Wilkinson

Improve testing of metrics auto-configuration

Closes gh-11970
parent ebbdfe72
...@@ -130,6 +130,7 @@ public class MetricsAutoConfiguration { ...@@ -130,6 +130,7 @@ public class MetricsAutoConfiguration {
*/ */
@Configuration @Configuration
@ConditionalOnClass(EnableIntegrationManagement.class) @ConditionalOnClass(EnableIntegrationManagement.class)
@ConditionalOnProperty(value = "management.metrics.binders.integration.enabled", matchIfMissing = true)
static class MetricsIntegrationConfiguration { static class MetricsIntegrationConfiguration {
@Bean(name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME) @Bean(name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME)
...@@ -142,6 +143,7 @@ public class MetricsAutoConfiguration { ...@@ -142,6 +143,7 @@ public class MetricsAutoConfiguration {
} }
@Bean @Bean
@ConditionalOnMissingBean
public SpringIntegrationMetrics springIntegrationMetrics( public SpringIntegrationMetrics springIntegrationMetrics(
IntegrationManagementConfigurer configurer) { IntegrationManagementConfigurer configurer) {
return new SpringIntegrationMetrics(configurer); return new SpringIntegrationMetrics(configurer);
......
...@@ -21,6 +21,7 @@ import io.micrometer.prometheus.PrometheusConfig; ...@@ -21,6 +21,7 @@ import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry; import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.CollectorRegistry; 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.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
...@@ -73,6 +74,8 @@ public class PrometheusMetricsExportAutoConfiguration { ...@@ -73,6 +74,8 @@ public class PrometheusMetricsExportAutoConfiguration {
public static class PrometheusScrapeEndpointConfiguration { public static class PrometheusScrapeEndpointConfiguration {
@Bean @Bean
@ConditionalOnEnabledEndpoint
@ConditionalOnMissingBean
public PrometheusScrapeEndpoint prometheusEndpoint( public PrometheusScrapeEndpoint prometheusEndpoint(
CollectorRegistry collectorRegistry) { CollectorRegistry collectorRegistry) {
return new PrometheusScrapeEndpoint(collectorRegistry); return new PrometheusScrapeEndpoint(collectorRegistry);
......
...@@ -49,7 +49,6 @@ import org.springframework.context.annotation.Configuration; ...@@ -49,7 +49,6 @@ import org.springframework.context.annotation.Configuration;
public class SimpleMetricsExportAutoConfiguration { public class SimpleMetricsExportAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(MeterRegistry.class)
public SimpleMeterRegistry simpleMeterRegistry(SimpleConfig config, Clock clock) { public SimpleMeterRegistry simpleMeterRegistry(SimpleConfig config, Clock clock) {
return new SimpleMeterRegistry(config, clock); return new SimpleMeterRegistry(config, clock);
} }
......
...@@ -54,6 +54,7 @@ public class StatsdMetricsExportAutoConfiguration { ...@@ -54,6 +54,7 @@ public class StatsdMetricsExportAutoConfiguration {
} }
@Bean @Bean
@ConditionalOnMissingBean
public StatsdMeterRegistry statsdMeterRegistry(StatsdConfig statsdConfig, public StatsdMeterRegistry statsdMeterRegistry(StatsdConfig statsdConfig,
HierarchicalNameMapper hierarchicalNameMapper, Clock clock) { HierarchicalNameMapper hierarchicalNameMapper, Clock clock) {
return new StatsdMeterRegistry(statsdConfig, hierarchicalNameMapper, clock); return new StatsdMeterRegistry(statsdConfig, hierarchicalNameMapper, clock);
......
...@@ -178,6 +178,12 @@ ...@@ -178,6 +178,12 @@
{ {
"name": "management.info.git.mode", "name": "management.info.git.mode",
"defaultValue": "simple" "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", "name": "management.metrics.binders.jvm.enabled",
......
/*
* 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());
}
}
}
...@@ -16,222 +16,309 @@ ...@@ -16,222 +16,309 @@
package org.springframework.boot.actuate.autoconfigure.metrics; package org.springframework.boot.actuate.autoconfigure.metrics;
import java.util.UUID; import java.util.List;
import javax.sql.DataSource;
import io.micrometer.core.instrument.Clock; import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.MeterRegistry; 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.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.core.instrument.simple.SimpleMeterRegistry;
import io.micrometer.graphite.GraphiteMeterRegistry;
import io.micrometer.jmx.JmxMeterRegistry;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.actuate.autoconfigure.metrics.export.graphite.GraphiteMetricsExportAutoConfiguration; import org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetrics;
import org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxMetricsExportAutoConfiguration;
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.jdbc.DataSourceBuilder;
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;
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.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}. * Tests for {@link MetricsAutoConfiguration}.
* *
* @author Stephane Nicoll * @author Andy Wilkinson
*/ */
public class MetricsAutoConfigurationTests { public class MetricsAutoConfigurationTests {
private ApplicationContextRunner contextRunner = new ApplicationContextRunner() private final ApplicationContextRunner runner = new ApplicationContextRunner()
.with(MetricsRun.simple()); .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class));
@Test @Test
public void autoConfiguredDataSourceIsInstrumented() { public void autoConfiguresAClock() {
this.contextRunner this.runner.run((context) -> assertThat(context).hasSingleBean(Clock.class));
.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 @Test
public void autoConfiguredDataSourceWithCustomMetricName() { public void allowsACustomClockToBeUsed() {
this.contextRunner this.runner.withUserConfiguration(CustomClockConfiguration.class)
.withConfiguration( .run((context) -> assertThat(context).hasSingleBean(Clock.class)
AutoConfigurations.of(DataSourceAutoConfiguration.class)) .hasBean("customClock"));
.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 @Test
public void dataSourceInstrumentationCanBeDisabled() { public void autoConfiguresACompositeMeterRegistry() {
this.contextRunner this.runner.run((context) -> {
.withConfiguration( assertThat(context).hasSingleBean(CompositeMeterRegistry.class);
AutoConfigurations.of(DataSourceAutoConfiguration.class)) assertThat(context.getBean(CompositeMeterRegistry.class).getRegistries())
.withPropertyValues("spring.datasource.generate-unique-name=true", .isEmpty();
"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();
}); });
} }
@SuppressWarnings("unchecked")
@Test @Test
public void allDataSourcesCanBeInstrumented() { public void configuresMeterRegistries() {
this.contextRunner.withUserConfiguration(TwoDataSourcesConfiguration.class) this.runner.withUserConfiguration(MeterRegistryConfiguration.class)
.withConfiguration(
AutoConfigurations.of(DataSourceAutoConfiguration.class))
.run((context) -> { .run((context) -> {
context.getBean("firstDataSource", DataSource.class).getConnection() MeterRegistry meterRegistry = context.getBean(MeterRegistry.class);
.getMetaData(); List<MeterFilter> filters = (List<MeterFilter>) ReflectionTestUtils
context.getBean("secondOne", DataSource.class).getConnection() .getField(meterRegistry, "filters");
.getMetaData(); assertThat(filters).isNotEmpty();
MeterRegistry registry = context.getBean(MeterRegistry.class); verify((MeterBinder) context.getBean("meterBinder"))
registry.get("data.source.max.connections").tags("name", "first") .bindTo(meterRegistry);
.meter(); verify(context.getBean(MeterRegistryCustomizer.class))
registry.get("data.source.max.connections").tags("name", "secondOne") .customize(meterRegistry);
.meter();
}); });
} }
@Test @Test
public void propertyBasedMeterFilter() { public void autoConfiguresJvmMetrics() {
this.contextRunner.withPropertyValues("management.metrics.enable.my.org=false") this.runner.run((context) -> assertThat(context).hasSingleBean(JvmGcMetrics.class)
.run((context) -> { .hasSingleBean(JvmMemoryMetrics.class)
MeterRegistry registry = context.getBean(MeterRegistry.class); .hasSingleBean(JvmThreadMetrics.class));
registry.timer("my.org.timer");
assertThat(registry.find("my.org.timer").timer()).isNull();
});
} }
/**
* The simple registry is off by default UNLESS there is no other registry
* implementation on the classpath, in which case it is on.
*/
@Test @Test
public void simpleWithNoCompositeCreated() { public void allowsJvmMetricsToBeDisabled() {
this.contextRunner this.runner.withPropertyValues("management.metrics.binders.jvm.enabled=false")
.run((context) -> assertThat(context.getBean(MeterRegistry.class)) .run((context) -> assertThat(context).doesNotHaveBean(JvmGcMetrics.class)
.isInstanceOf(SimpleMeterRegistry.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 @Test
public void emptyCompositeCreated() { public void allowsCustomJvmGcMetricsToBeUsed() {
new ApplicationContextRunner().with(MetricsRun.limitedTo()).run((context) -> { this.runner.withUserConfiguration(CustomJvmGcMetricsConfiguration.class)
MeterRegistry registry = context.getBean(MeterRegistry.class); .run((context) -> assertThat(context).hasSingleBean(JvmGcMetrics.class)
assertThat(registry).isInstanceOf(CompositeMeterRegistry.class); .hasBean("customJvmGcMetrics")
assertThat(((CompositeMeterRegistry) registry).getRegistries()).isEmpty(); .hasSingleBean(JvmMemoryMetrics.class)
}); .hasSingleBean(JvmThreadMetrics.class));
} }
@Test @Test
public void noCompositeCreatedWhenSingleImplementationIsEnabled() { public void allowsCustomJvmMemoryMetricsToBeUsed() {
new ApplicationContextRunner() this.runner.withUserConfiguration(CustomJvmMemoryMetricsConfiguration.class)
.with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class)) .run((context) -> assertThat(context).hasSingleBean(JvmGcMetrics.class)
.run((context) -> assertThat(context.getBean(MeterRegistry.class)) .hasSingleBean(JvmMemoryMetrics.class)
.isInstanceOf(GraphiteMeterRegistry.class)); .hasBean("customJvmMemoryMetrics")
.hasSingleBean(JvmThreadMetrics.class));
} }
@Test @Test
public void noCompositeCreatedWhenMultipleRegistriesButOneMarkedAsPrimary() { public void allowsCustomJvmThreadMetricsToBeUsed() {
new ApplicationContextRunner() this.runner.withUserConfiguration(CustomJvmThreadMetricsConfiguration.class)
.with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class, .run((context) -> assertThat(context).hasSingleBean(JvmGcMetrics.class)
JmxMetricsExportAutoConfiguration.class)) .hasSingleBean(JvmMemoryMetrics.class)
.withUserConfiguration(PrimarySimpleMeterRegistryConfiguration.class) .hasSingleBean(JvmThreadMetrics.class)
.run((context) -> assertThat(context.getBean(MeterRegistry.class)) .hasBean("customJvmThreadMetrics"));
.isInstanceOf(SimpleMeterRegistry.class));
} }
@Test @Test
public void compositeCreatedWhenMultipleImplementationsAreEnabled() { public void autoConfiguresLogbackMetrics() {
new ApplicationContextRunner() this.runner.run(
.with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class, (context) -> assertThat(context).hasSingleBean(LogbackMetrics.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);
});
} }
@Test @Test
public void autoConfiguresAClock() { public void allowsLogbackMetricsToBeDisabled() {
this.contextRunner.with(MetricsRun.limitedTo()) this.runner.withPropertyValues("management.metrics.binders.logback.enabled=false")
.run((context) -> assertThat(context).hasSingleBean(Clock.class)); .run((context) -> assertThat(context)
.doesNotHaveBean(LogbackMetrics.class));
} }
@Test @Test
public void allowsCustomClockToBeConfigured() { public void allowsCustomLogbackMetricsToBeUsed() {
this.contextRunner.with(MetricsRun.limitedTo()) this.runner.withUserConfiguration(CustomLogbackMetricsConfiguration.class)
.withUserConfiguration(CustomClockConfiguration.class) .run((context) -> assertThat(context).hasSingleBean(LogbackMetrics.class)
.run((context) -> assertThat(context).hasSingleBean(Clock.class) .hasBean("customLogbackMetrics"));
.hasBean("customClock")); }
@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 @Configuration
static class PrimarySimpleMeterRegistryConfiguration { static class CustomClockConfiguration {
@Primary
@Bean @Bean
public MeterRegistry simpleMeterRegistry() { Clock customClock() {
return new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock()); return Clock.SYSTEM;
} }
} }
@Configuration @Configuration
static class TwoDataSourcesConfiguration { static class MeterRegistryConfiguration {
@Bean @Bean
public DataSource firstDataSource() { MeterRegistry meterRegistry() {
return createDataSource(); SimpleMeterRegistry meterRegistry = new SimpleMeterRegistry();
return spy(meterRegistry);
} }
@Bean @Bean
public DataSource secondOne() { @SuppressWarnings("rawtypes")
return createDataSource(); MeterRegistryCustomizer meterRegistryCustomizer() {
return mock(MeterRegistryCustomizer.class);
} }
private DataSource createDataSource() { @Bean
String url = "jdbc:hsqldb:mem:test-" + UUID.randomUUID(); MeterBinder meterBinder() {
return DataSourceBuilder.create().url(url).build(); return mock(MeterBinder.class);
} }
} }
@Configuration @Configuration
static class CustomClockConfiguration { static class CustomJvmGcMetricsConfiguration {
@Bean @Bean
public Clock customClock() { JvmGcMetrics customJvmGcMetrics() {
return Clock.SYSTEM; 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);
} }
} }
......
/*
* 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);
}
}
}
...@@ -30,7 +30,7 @@ import org.springframework.context.annotation.Import; ...@@ -30,7 +30,7 @@ import org.springframework.context.annotation.Import;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
* Tests for {@link DatadogMetricsExportAutoConfiguration} * Tests for {@link DatadogMetricsExportAutoConfiguration}.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
*/ */
...@@ -53,7 +53,7 @@ public class DatadogMetricsExportAutoConfigurationTests { ...@@ -53,7 +53,7 @@ public class DatadogMetricsExportAutoConfigurationTests {
} }
@Test @Test
public void autoConfiguresItsConfigAndMeterRegistry() { public void autoConfiguresConfigAndMeterRegistry() {
this.runner.withUserConfiguration(BaseConfiguration.class) this.runner.withUserConfiguration(BaseConfiguration.class)
.withPropertyValues("management.metrics.export.datadog.api-key=abcde") .withPropertyValues("management.metrics.export.datadog.api-key=abcde")
.run((context) -> assertThat(context) .run((context) -> assertThat(context)
......
/*
* 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);
}
}
}
/*
* 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);
}
}
}
/*
* 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);
}
}
}
/*
* 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";
}
};
}
}
}
/*
* 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);
}
}
}
/*
* 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);
}
}
}
/*
* 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";
}
};
}
}
}
/*
* 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();
}
}
}
...@@ -30,7 +30,9 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia.Gan ...@@ -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.graphite.GraphiteMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.influx.InfluxMetricsExportAutoConfiguration; 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.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.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.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetricsExportAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration;
...@@ -60,8 +62,10 @@ public final class MetricsRun { ...@@ -60,8 +62,10 @@ public final class MetricsRun {
implementations.add(GraphiteMetricsExportAutoConfiguration.class); implementations.add(GraphiteMetricsExportAutoConfiguration.class);
implementations.add(InfluxMetricsExportAutoConfiguration.class); implementations.add(InfluxMetricsExportAutoConfiguration.class);
implementations.add(JmxMetricsExportAutoConfiguration.class); implementations.add(JmxMetricsExportAutoConfiguration.class);
implementations.add(NewRelicMetricsExportAutoConfiguration.class);
implementations.add(PrometheusMetricsExportAutoConfiguration.class); implementations.add(PrometheusMetricsExportAutoConfiguration.class);
implementations.add(SimpleMetricsExportAutoConfiguration.class); implementations.add(SimpleMetricsExportAutoConfiguration.class);
implementations.add(SignalFxMetricsExportAutoConfiguration.class);
implementations.add(StatsdMetricsExportAutoConfiguration.class); implementations.add(StatsdMetricsExportAutoConfiguration.class);
EXPORT_AUTO_CONFIGURATIONS = Collections.unmodifiableSet(implementations); EXPORT_AUTO_CONFIGURATIONS = Collections.unmodifiableSet(implementations);
} }
......
...@@ -1242,7 +1242,7 @@ content into your application. Rather, pick only the properties that you need. ...@@ -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]) # 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.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]) # 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. 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. ...@@ -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. management.info.git.mode=simple # Mode to use to expose git information.
# METRICS # 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.jvm.enabled=true # Whether to enable JVM metrics.
management.metrics.binders.logback.enabled=true # Whether to enable Logback metrics. management.metrics.binders.logback.enabled=true # Whether to enable Logback metrics.
management.metrics.binders.processor.enabled=true # Whether to enable processor metrics. management.metrics.binders.processor.enabled=true # Whether to enable processor metrics.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment