Change metrics exporters to auto-configurations

Refactor `*ExportConfiguration` classes to be regular auto-configuration
classes.

Also removed the `@ConditionalOnProperty` guards for `.enabled` properties
since auto-configuration can now be excluded in the usual way. Enabled
properties remain where applicable and are adapted for Micrometer to use
as it sees fit.

Fixes gh-11838
pull/11886/merge
Phillip Webb 7 years ago
parent 7ea6af0e46
commit d8de8752ea

@ -1,44 +0,0 @@
/*
* 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 org.springframework.boot.actuate.autoconfigure.metrics.export.atlas.AtlasExportConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.datadog.DatadogExportConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia.GangliaExportConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.graphite.GraphiteExportConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.influx.InfluxExportConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxExportConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusExportConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleExportConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdExportConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* Imports for registry configurations.
*
* @author Jon Schneider
*/
@Configuration
@Import({ AtlasExportConfiguration.class, DatadogExportConfiguration.class,
GangliaExportConfiguration.class, GraphiteExportConfiguration.class,
InfluxExportConfiguration.class, JmxExportConfiguration.class,
PrometheusExportConfiguration.class, SimpleExportConfiguration.class,
StatsdExportConfiguration.class })
class MeterRegistriesConfiguration {
}

@ -19,27 +19,21 @@ package org.springframework.boot.actuate.autoconfigure.metrics;
import java.util.Collection;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.MeterBinder;
import io.micrometer.core.instrument.config.MeterFilter;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.autoconfigure.metrics.amqp.RabbitMetricsConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.CompositeMeterRegistryConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.reactive.server.WebFluxMetricsConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.client.RestTemplateMetricsConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsConfiguration;
import org.springframework.boot.actuate.metrics.MetricsEndpoint;
import org.springframework.boot.actuate.metrics.integration.SpringIntegrationMetrics;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
@ -66,12 +60,16 @@ import org.springframework.integration.support.management.IntegrationManagementC
@Import({ MeterBindersConfiguration.class, WebMvcMetricsConfiguration.class,
WebFluxMetricsConfiguration.class, RestTemplateMetricsConfiguration.class,
CacheMetricsConfiguration.class, DataSourcePoolMetricsConfiguration.class,
RabbitMetricsConfiguration.class, MeterRegistriesConfiguration.class,
CompositeMeterRegistryConfiguration.class })
RabbitMetricsConfiguration.class })
@AutoConfigureAfter({ CacheAutoConfiguration.class, DataSourceAutoConfiguration.class,
RabbitAutoConfiguration.class, RestTemplateAutoConfiguration.class })
public class MetricsAutoConfiguration {
@Bean
public static CompositeMeterRegistryPostProcessor compositeMeterRegistryPostProcessor() {
return new CompositeMeterRegistryPostProcessor();
}
@Bean
public static MeterRegistryPostProcessor meterRegistryPostProcessor(
ObjectProvider<Collection<MeterBinder>> binders,
@ -83,20 +81,6 @@ public class MetricsAutoConfiguration {
properties.isUseGlobalRegistry());
}
@Bean
@ConditionalOnBean(MeterRegistry.class)
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public MetricsEndpoint metricsEndpoint(MeterRegistry registry) {
return new MetricsEndpoint(registry);
}
@Bean
@ConditionalOnMissingBean
public Clock micrometerClock() {
return Clock.SYSTEM;
}
@Bean
@Order(0)
public PropertiesMeterFilter propertiesMeterFilter(MetricsProperties properties) {

@ -0,0 +1,51 @@
/*
* 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.annotation.Timed;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.metrics.MetricsEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link MetricsEndpoint}.
*
* @author Phillip Webb
* @since 2.0.0
*/
@Configuration
@ConditionalOnClass(Timed.class)
@ConditionalOnBean(MeterRegistry.class)
@AutoConfigureAfter(MetricsAutoConfiguration.class)
public class MetricsEndpointAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public MetricsEndpoint metricsEndpoint(MeterRegistry registry) {
return new MetricsEndpoint(registry);
}
}

@ -1,36 +0,0 @@
/*
* 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;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Conditionally build a composite registry when more than one registry present.
*
* @author Jon Schneider
* @since 2.0.0
*/
@Configuration
public class CompositeMeterRegistryConfiguration {
@Bean
public static CompositeMeterRegistryPostProcessor compositeMeterRegistryPostProcessor() {
return new CompositeMeterRegistryPostProcessor();
}
}

@ -20,24 +20,33 @@ import com.netflix.spectator.atlas.AtlasConfig;
import io.micrometer.atlas.AtlasMeterRegistry;
import io.micrometer.core.instrument.Clock;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration for exporting metrics to Atlas.
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Atlas.
*
* @author Jon Schneider
* @author Andy Wilkinson
* @since 2.0.0
*/
@Configuration
@AutoConfigureBefore(MetricsAutoConfiguration.class)
@ConditionalOnClass(AtlasMeterRegistry.class)
@EnableConfigurationProperties(AtlasProperties.class)
public class AtlasExportConfiguration {
public class AtlasMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Clock micrometerClock() {
return Clock.SYSTEM;
}
@Bean
@ConditionalOnMissingBean(AtlasConfig.class)
@ -46,7 +55,7 @@ public class AtlasExportConfiguration {
}
@Bean
@ConditionalOnProperty(value = "management.metrics.export.atlas.enabled", matchIfMissing = true)
@ConditionalOnMissingBean
public AtlasMeterRegistry atlasMeterRegistry(AtlasConfig atlasConfig, Clock clock) {
return new AtlasMeterRegistry(atlasConfig, clock);
}

@ -18,7 +18,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.atlas;
import java.time.Duration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.StepRegistryProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**

@ -20,7 +20,7 @@ import java.time.Duration;
import com.netflix.spectator.atlas.AtlasConfig;
import org.springframework.boot.actuate.autoconfigure.metrics.export.PropertiesConfigAdapter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter;
/**
* Adapter to convert {@link AtlasProperties} to an {@link AtlasConfig}.

@ -20,6 +20,9 @@ import io.micrometer.core.instrument.Clock;
import io.micrometer.datadog.DatadogConfig;
import io.micrometer.datadog.DatadogMeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@ -28,16 +31,23 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration for exporting metrics to Datadog.
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Datadog.
*
* @author Jon Schneider
* @since 2.0.0
*/
@Configuration
@AutoConfigureBefore(MetricsAutoConfiguration.class)
@ConditionalOnClass(DatadogMeterRegistry.class)
@ConditionalOnProperty("management.metrics.export.datadog.api-key")
@EnableConfigurationProperties(DatadogProperties.class)
public class DatadogExportConfiguration {
public class DatadogMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Clock micrometerClock() {
return Clock.SYSTEM;
}
@Bean
@ConditionalOnMissingBean
@ -46,7 +56,7 @@ public class DatadogExportConfiguration {
}
@Bean
@ConditionalOnProperty(value = "management.metrics.export.datadog.enabled", matchIfMissing = true)
@ConditionalOnMissingBean
public DatadogMeterRegistry datadogMeterRegistry(DatadogConfig datadogConfig,
Clock clock) {
return new DatadogMeterRegistry(datadogConfig, clock);

@ -16,7 +16,7 @@
package org.springframework.boot.actuate.autoconfigure.metrics.export.datadog;
import org.springframework.boot.actuate.autoconfigure.metrics.export.StepRegistryProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**

@ -18,7 +18,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.datadog;
import io.micrometer.datadog.DatadogConfig;
import org.springframework.boot.actuate.autoconfigure.metrics.export.StepRegistryPropertiesConfigAdapter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter;
/**
* Adapter to convert {@link DatadogProperties} to a {@link DatadogConfig}.

@ -21,23 +21,32 @@ import io.micrometer.core.instrument.util.HierarchicalNameMapper;
import io.micrometer.ganglia.GangliaConfig;
import io.micrometer.ganglia.GangliaMeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration for exporting metrics to Ganglia.
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Ganglia.
*
* @author Jon Schneider
* @since 2.0.0
*/
@Configuration
@AutoConfigureBefore(MetricsAutoConfiguration.class)
@ConditionalOnClass(GangliaMeterRegistry.class)
@EnableConfigurationProperties(GangliaProperties.class)
public class GangliaExportConfiguration {
public class GangliaMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Clock micrometerClock() {
return Clock.SYSTEM;
}
@Bean
@ConditionalOnMissingBean
@ -46,7 +55,7 @@ public class GangliaExportConfiguration {
}
@Bean
@ConditionalOnProperty(value = "management.metrics.export.ganglia.enabled", matchIfMissing = true)
@ConditionalOnMissingBean
public GangliaMeterRegistry gangliaMeterRegistry(GangliaConfig gangliaConfig,
HierarchicalNameMapper nameMapper, Clock clock) {
return new GangliaMeterRegistry(gangliaConfig, clock, nameMapper);

@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit;
import info.ganglia.gmetric4j.gmetric.GMetric;
import io.micrometer.ganglia.GangliaConfig;
import org.springframework.boot.actuate.autoconfigure.metrics.export.PropertiesConfigAdapter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter;
/**
* Adapter to convert {@link GangliaProperties} to a {@link GangliaConfig}.

@ -21,23 +21,32 @@ import io.micrometer.core.instrument.util.HierarchicalNameMapper;
import io.micrometer.graphite.GraphiteConfig;
import io.micrometer.graphite.GraphiteMeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration for exporting metrics to Graphite.
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Graphite.
*
* @author Jon Schneider
* @since 2.0.0
*/
@Configuration
@AutoConfigureBefore(MetricsAutoConfiguration.class)
@ConditionalOnClass(GraphiteMeterRegistry.class)
@EnableConfigurationProperties(GraphiteProperties.class)
public class GraphiteExportConfiguration {
public class GraphiteMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Clock micrometerClock() {
return Clock.SYSTEM;
}
@Bean
@ConditionalOnMissingBean
@ -46,7 +55,7 @@ public class GraphiteExportConfiguration {
}
@Bean
@ConditionalOnProperty(value = "management.metrics.export.graphite.enabled", matchIfMissing = true)
@ConditionalOnMissingBean
public GraphiteMeterRegistry graphiteMeterRegistry(GraphiteConfig graphiteConfig,
HierarchicalNameMapper nameMapper, Clock clock) {
return new GraphiteMeterRegistry(graphiteConfig, clock, nameMapper);

@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit;
import io.micrometer.graphite.GraphiteConfig;
import io.micrometer.graphite.GraphiteProtocol;
import org.springframework.boot.actuate.autoconfigure.metrics.export.PropertiesConfigAdapter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter;
/**
* Adapter to convert {@link GraphiteProperties} to a {@link GraphiteConfig}.

@ -20,23 +20,32 @@ import io.micrometer.core.instrument.Clock;
import io.micrometer.influx.InfluxConfig;
import io.micrometer.influx.InfluxMeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration for exporting metrics to Influx.
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Influx.
*
* @author Jon Schneider
* @since 2.0.0
*/
@Configuration
@AutoConfigureBefore(MetricsAutoConfiguration.class)
@ConditionalOnClass(InfluxMeterRegistry.class)
@EnableConfigurationProperties(InfluxProperties.class)
public class InfluxExportConfiguration {
public class InfluxMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Clock micrometerClock() {
return Clock.SYSTEM;
}
@Bean
@ConditionalOnMissingBean(InfluxConfig.class)
@ -45,7 +54,7 @@ public class InfluxExportConfiguration {
}
@Bean
@ConditionalOnProperty(value = "management.metrics.export.influx.enabled", matchIfMissing = true)
@ConditionalOnMissingBean
public InfluxMeterRegistry influxMeterRegistry(InfluxConfig influxConfig,
Clock clock) {
return new InfluxMeterRegistry(influxConfig, clock);

@ -18,7 +18,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.influx;
import io.micrometer.influx.InfluxConsistency;
import org.springframework.boot.actuate.autoconfigure.metrics.export.StepRegistryProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**

@ -19,7 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.influx;
import io.micrometer.influx.InfluxConfig;
import io.micrometer.influx.InfluxConsistency;
import org.springframework.boot.actuate.autoconfigure.metrics.export.StepRegistryPropertiesConfigAdapter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter;
/**
* Adapter to convert {@link InfluxProperties} to an {@link InfluxConfig}.

@ -21,23 +21,32 @@ import io.micrometer.core.instrument.util.HierarchicalNameMapper;
import io.micrometer.jmx.JmxConfig;
import io.micrometer.jmx.JmxMeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration for exporting metrics to JMX.
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to JMX.
*
* @author Jon Schneider
* @since 2.0.0
*/
@Configuration
@AutoConfigureBefore(MetricsAutoConfiguration.class)
@ConditionalOnClass(JmxMeterRegistry.class)
@EnableConfigurationProperties(JmxProperties.class)
public class JmxExportConfiguration {
public class JmxMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Clock micrometerClock() {
return Clock.SYSTEM;
}
@Bean
@ConditionalOnMissingBean
@ -46,7 +55,7 @@ public class JmxExportConfiguration {
}
@Bean
@ConditionalOnProperty(value = "management.metrics.export.jmx.enabled", matchIfMissing = true)
@ConditionalOnMissingBean
public JmxMeterRegistry jmxMeterRegistry(JmxConfig config,
HierarchicalNameMapper nameMapper, Clock clock) {
return new JmxMeterRegistry(config, clock, nameMapper);

@ -20,7 +20,7 @@ import java.time.Duration;
import io.micrometer.jmx.JmxConfig;
import org.springframework.boot.actuate.autoconfigure.metrics.export.PropertiesConfigAdapter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter;
/**
* Adapter to convert {@link JmxProperties} to a {@link JmxConfig}.

@ -21,25 +21,34 @@ import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.CollectorRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusScrapeEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration for exporting metrics to Prometheus.
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Prometheus.
*
* @since 2.0.0
* @author Jon Schneider
*/
@Configuration
@AutoConfigureBefore(MetricsAutoConfiguration.class)
@ConditionalOnClass(PrometheusMeterRegistry.class)
@EnableConfigurationProperties(PrometheusProperties.class)
public class PrometheusExportConfiguration {
public class PrometheusMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Clock micrometerClock() {
return Clock.SYSTEM;
}
@Bean
@ConditionalOnMissingBean
@ -48,7 +57,7 @@ public class PrometheusExportConfiguration {
}
@Bean
@ConditionalOnProperty(value = "management.metrics.export.prometheus.enabled", matchIfMissing = true)
@ConditionalOnMissingBean
public PrometheusMeterRegistry prometheusMeterRegistry(
PrometheusConfig prometheusConfig, CollectorRegistry collectorRegistry,
Clock clock) {

@ -20,7 +20,7 @@ import java.time.Duration;
import io.micrometer.prometheus.PrometheusConfig;
import org.springframework.boot.actuate.autoconfigure.metrics.export.PropertiesConfigAdapter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter;
/**
* Adapter to convert {@link PrometheusProperties} to a {@link PrometheusConfig}.

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.metrics.export;
package org.springframework.boot.actuate.autoconfigure.metrics.export.properties;
import java.util.function.Function;
import java.util.function.Supplier;

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.metrics.export;
package org.springframework.boot.actuate.autoconfigure.metrics.export.properties;
import java.time.Duration;

@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* 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.
@ -15,6 +15,6 @@
*/
/**
* Core classes for exporting actuator metrics.
* Base properties and adapters used when exporting actuator metrics.
*/
package org.springframework.boot.actuate.autoconfigure.metrics.export;
package org.springframework.boot.actuate.autoconfigure.metrics.export.properties;

@ -21,25 +21,37 @@ import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.simple.SimpleConfig;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsEndpointAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration for exporting metrics to a {@link SimpleMeterRegistry}.
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to a
* {@link SimpleMeterRegistry}.
*
* @author Jon Schneider
* @since 2.0.0
*/
@Configuration
@AutoConfigureAfter(MetricsAutoConfiguration.class)
@AutoConfigureBefore(MetricsEndpointAutoConfiguration.class)
@EnableConfigurationProperties(SimpleProperties.class)
public class SimpleExportConfiguration {
@ConditionalOnMissingBean(MeterRegistry.class)
public class SimpleMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Clock micrometerClock() {
return Clock.SYSTEM;
}
@Bean
@ConditionalOnProperty(value = "management.metrics.export.simple.enabled", matchIfMissing = true)
@ConditionalOnMissingBean(MeterRegistry.class)
public SimpleMeterRegistry simpleMeterRegistry(SimpleConfig config, Clock clock) {
return new SimpleMeterRegistry(config, clock);
}

@ -21,7 +21,7 @@ import java.time.Duration;
import io.micrometer.core.instrument.simple.CountingMode;
import io.micrometer.core.instrument.simple.SimpleConfig;
import org.springframework.boot.actuate.autoconfigure.metrics.export.PropertiesConfigAdapter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter;
/**
* Adapter to convert {@link SimpleProperties} to a {@link SimpleConfig}.

@ -21,23 +21,32 @@ import io.micrometer.core.instrument.util.HierarchicalNameMapper;
import io.micrometer.statsd.StatsdConfig;
import io.micrometer.statsd.StatsdMeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configuration for exporting metrics to StatsD.
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to StatsD.
*
* @author Jon Schneider
* @since 2.0.0
*/
@Configuration
@AutoConfigureBefore(MetricsAutoConfiguration.class)
@ConditionalOnClass(StatsdMeterRegistry.class)
@EnableConfigurationProperties(StatsdProperties.class)
public class StatsdExportConfiguration {
public class StatsdMetricsExportAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Clock micrometerClock() {
return Clock.SYSTEM;
}
@Bean
@ConditionalOnMissingBean(StatsdConfig.class)
@ -46,7 +55,6 @@ public class StatsdExportConfiguration {
}
@Bean
@ConditionalOnProperty(value = "management.metrics.export.statsd.enabled", matchIfMissing = true)
public StatsdMeterRegistry statsdMeterRegistry(StatsdConfig statsdConfig,
HierarchicalNameMapper hierarchicalNameMapper, Clock clock) {
return new StatsdMeterRegistry(statsdConfig, hierarchicalNameMapper, clock);

@ -21,7 +21,7 @@ import java.time.Duration;
import io.micrometer.statsd.StatsdConfig;
import io.micrometer.statsd.StatsdFlavor;
import org.springframework.boot.actuate.autoconfigure.metrics.export.PropertiesConfigAdapter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter;
/**
* Adapter to convert {@link StatsdProperties} to a {@link StatsdConfig}.

@ -203,12 +203,6 @@
"description": "Instrument all available caches.",
"defaultValue": true
},
{
"name": "management.metrics.export.jmx.enabled",
"type": "java.lang.Boolean",
"description": "Whether exporting of metrics to JMX is enabled.",
"defaultValue": true
},
{
"name": "management.metrics.jdbc.instrument",
"type": "java.lang.Boolean",

@ -32,6 +32,16 @@ org.springframework.boot.actuate.autoconfigure.mail.MailHealthIndicatorAutoConfi
org.springframework.boot.actuate.autoconfigure.management.HeapDumpWebEndpointAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.management.ThreadDumpEndpointAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.MetricsEndpointAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.export.atlas.AtlasMetricsExportAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.export.datadog.DatadogMetricsExportAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia.GangliaMetricsExportAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.export.graphite.GraphiteMetricsExportAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.export.influx.InfluxMetricsExportAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxMetricsExportAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetricsExportAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.mongo.MongoHealthIndicatorAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.neo4j.Neo4jHealthIndicatorAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.redis.RedisHealthIndicatorAutoConfiguration,\

@ -19,7 +19,7 @@ package org.springframework.boot.actuate.autoconfigure;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxMetricsExportAutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration;
@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfigurat
import org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.util.ApplicationContextTestUtils;
@ -53,14 +54,16 @@ public class SpringApplicationHierarchyTests {
public void testParent() {
SpringApplicationBuilder builder = new SpringApplicationBuilder(Child.class);
builder.parent(Parent.class);
this.context = builder.run("--server.port=0");
this.context = builder.run("--server.port=0",
"--management.metrics.use-global-registry=false");
}
@Test
public void testChild() {
SpringApplicationBuilder builder = new SpringApplicationBuilder(Parent.class);
builder.child(Child.class);
this.context = builder.run("--server.port=0");
this.context = builder.run("--server.port=0",
"--management.metrics.use-global-registry=false");
}
@EnableAutoConfiguration(exclude = { ElasticsearchDataAutoConfiguration.class,
@ -69,7 +72,8 @@ public class SpringApplicationHierarchyTests {
MongoDataAutoConfiguration.class, Neo4jDataAutoConfiguration.class,
Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class,
RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class,
MetricsAutoConfiguration.class }, excludeName = {
JestAutoConfiguration.class,
JmxMetricsExportAutoConfiguration.class }, excludeName = {
"org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration" })
public static class Child {
@ -81,7 +85,8 @@ public class SpringApplicationHierarchyTests {
MongoDataAutoConfiguration.class, Neo4jDataAutoConfiguration.class,
Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class,
RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class,
MetricsAutoConfiguration.class }, excludeName = {
JestAutoConfiguration.class,
JmxMetricsExportAutoConfiguration.class }, excludeName = {
"org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration" })
public static class Parent {

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.metrics.export;
package org.springframework.boot.actuate.autoconfigure.metrics;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.MeterRegistry;

@ -20,6 +20,7 @@ import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.MeterRegistry.Config;
import org.junit.Test;
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;

@ -21,14 +21,24 @@ import java.util.UUID;
import javax.sql.DataSource;
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.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 static org.assertj.core.api.Assertions.assertThat;
@ -114,6 +124,73 @@ public class MetricsAutoConfigurationTests {
});
}
/**
* 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));
}
/**
* 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();
});
}
@Test
public void noCompositeCreatedWhenSingleImplementationIsEnabled() {
new ApplicationContextRunner()
.with(MetricsRun.limitedTo(GraphiteMetricsExportAutoConfiguration.class))
.run((context) -> assertThat(context.getBean(MeterRegistry.class))
.isInstanceOf(GraphiteMeterRegistry.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));
}
@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);
});
}
@Configuration
static class PrimarySimpleMeterRegistryConfiguration {
@Primary
@Bean
public MeterRegistry simpleMeterRegistry() {
return new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock());
}
}
@Configuration
static class TwoDataSourcesConfiguration {

@ -1,87 +0,0 @@
/*
* 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 java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
/**
* Additional metrics configuration and settings that can be applied to a
* {@link ApplicationContextRunner} when running a metrics test.
*
* @author Jon Schneider
* @author Phillip Webb
*/
public final class MetricsRun {
private static final Set<String> IMPLEMENTATIONS = Collections
.unmodifiableSet(new LinkedHashSet<>(Arrays.asList("atlas", "datadog",
"ganglia", "graphite", "influx", "jmx", "prometheus", "statsd",
"newrelic", "signalfx", "wavefront", "simple")));
private MetricsRun() {
}
/**
* Return a function that configures the run to be limited to the {@code simple}
* implementation.
* @return the function to apply
*/
public static Function<ApplicationContextRunner, ApplicationContextRunner> simple() {
return limitedTo("simple");
}
/**
* Return a function that configures the run to be limited to the specified
* implementations.
* @param implementations the implementations to include
* @return the function to apply
*/
public static Function<ApplicationContextRunner, ApplicationContextRunner> limitedTo(
String... implementations) {
return (contextRunner) -> apply(contextRunner, implementations);
}
private static ApplicationContextRunner apply(ApplicationContextRunner contextRunner,
String[] implementations) {
return contextRunner.withPropertyValues(getPropertyValues(implementations))
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class));
}
private static String[] getPropertyValues(String[] implementations) {
List<String> propertyValues = new ArrayList<>();
propertyValues.add("management.metrics.use-global-registry=false");
List<String> keep = Arrays.asList(implementations);
IMPLEMENTATIONS.stream()
.filter((implementation) -> !keep.contains(implementation))
.map(MetricsRun::disableExport).forEach(propertyValues::add);
return propertyValues.toArray(new String[0]);
}
private static String disableExport(String implementation) {
return "management.metrics.export." + implementation + ".enabled=false";
}
}

@ -19,7 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.amqp;
import io.micrometer.core.instrument.MeterRegistry;
import org.junit.Test;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsRun;
import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;

@ -19,7 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.cache;
import io.micrometer.core.instrument.MeterRegistry;
import org.junit.Test;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsRun;
import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;

@ -1,111 +0,0 @@
/*
* 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;
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.junit.runner.RunWith;
import org.springframework.boot.actuate.autoconfigure.metrics.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 org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link CompositeMeterRegistryConfiguration}.
*
* @author Jon Schneider
*/
@RunWith(SpringRunner.class)
public class CompositeMeterRegistryConfigurationTests {
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.with(MetricsRun.simple());
/**
* 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));
}
/**
* 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();
});
}
@Test
public void noCompositeCreatedWhenSingleImplementationIsEnabled() {
new ApplicationContextRunner().with(MetricsRun.limitedTo("graphite"))
.run((context) -> assertThat(context.getBean(MeterRegistry.class))
.isInstanceOf(GraphiteMeterRegistry.class));
}
@Test
public void noCompositeCreatedWhenMultipleRegistriesButOneMarkedAsPrimary() {
new ApplicationContextRunner().with(MetricsRun.limitedTo("graphite", "jmx"))
.withUserConfiguration(PrimarySimpleMeterRegistryConfiguration.class)
.run((context) -> assertThat(context.getBean(MeterRegistry.class))
.isInstanceOf(SimpleMeterRegistry.class));
}
@Test
public void compositeCreatedWhenMultipleImplementationsAreEnabled() {
new ApplicationContextRunner().with(MetricsRun.limitedTo("graphite", "jmx"))
.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 PrimarySimpleMeterRegistryConfiguration {
@Primary
@Bean
public MeterRegistry simpleMeterRegistry() {
return new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock());
}
}
}

@ -0,0 +1,98 @@
/*
* 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.test;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Function;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.atlas.AtlasMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.datadog.DatadogMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia.GangliaMetricsExportAutoConfiguration;
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.prometheus.PrometheusMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetricsExportAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.util.Assert;
/**
* Additional metrics configuration and settings that can be applied to a
* {@link ApplicationContextRunner} when running a metrics test.
*
* @author Jon Schneider
* @author Phillip Webb
*/
public final class MetricsRun {
private static final Set<Class<?>> IMPLEMENTATIONS;
static {
Set<Class<?>> implementations = new LinkedHashSet<>();
implementations.add(AtlasMetricsExportAutoConfiguration.class);
implementations.add(DatadogMetricsExportAutoConfiguration.class);
implementations.add(GangliaMetricsExportAutoConfiguration.class);
implementations.add(GraphiteMetricsExportAutoConfiguration.class);
implementations.add(InfluxMetricsExportAutoConfiguration.class);
implementations.add(JmxMetricsExportAutoConfiguration.class);
implementations.add(PrometheusMetricsExportAutoConfiguration.class);
implementations.add(SimpleMetricsExportAutoConfiguration.class);
implementations.add(StatsdMetricsExportAutoConfiguration.class);
IMPLEMENTATIONS = Collections.unmodifiableSet(implementations);
}
private MetricsRun() {
}
/**
* Return a function that configures the run to be limited to the {@code simple}
* implementation.
* @return the function to apply
*/
public static Function<ApplicationContextRunner, ApplicationContextRunner> simple() {
return limitedTo(SimpleMetricsExportAutoConfiguration.class);
}
/**
* Return a function that configures the run to be limited to the specified
* implementations.
* @param implementations the implementations to include
* @return the function to apply
*/
public static Function<ApplicationContextRunner, ApplicationContextRunner> limitedTo(
Class<?>... implementations) {
return (contextRunner) -> apply(contextRunner, implementations);
}
private static ApplicationContextRunner apply(ApplicationContextRunner contextRunner,
Class<?>[] implementations) {
for (Class<?> implementation : implementations) {
Assert.state(IMPLEMENTATIONS.contains(implementation),
"Unknown implementation " + implementation.getName());
}
return contextRunner
.withPropertyValues("management.metrics.use-global-registry=false")
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(implementations));
}
}

@ -21,7 +21,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsRun;
import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
import org.springframework.boot.actuate.metrics.web.client.MetricsRestTemplateCustomizer;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;

@ -1307,7 +1307,6 @@ content into your application. Rather, pick only the properties that you need.
management.metrics.export.atlas.config-time-to-live= # Time to live for subscriptions from the LWC service.
management.metrics.export.atlas.config-uri= # URI for the Atlas LWC endpoint to retrieve current subscriptions.
management.metrics.export.atlas.connect-timeout= # Connection timeout for requests to the backend.
management.metrics.export.atlas.enabled=true # Whether exporting of metrics to this backend is enabled.
management.metrics.export.atlas.eval-uri= # URI for the Atlas LWC endpoint to evaluate the data for a subscription.
management.metrics.export.atlas.lwc-enabled= # Enable streaming to Atlas LWC.
management.metrics.export.atlas.meter-time-to-live= # Time to live for meters that do not have any activity. After this period the meter will be considered expired and will not get reported.
@ -1328,7 +1327,6 @@ content into your application. Rather, pick only the properties that you need.
management.metrics.export.datadog.uri= # URI to ship metrics to. If you need to publish metrics to an internal proxy en-route to Datadog, you can define the location of the proxy with this.
management.metrics.export.ganglia.addressing-mode= # UDP addressing mode, either unicast or multicast.
management.metrics.export.ganglia.duration-units= # Base time unit used to report durations.
management.metrics.export.ganglia.enabled=true # Whether exporting of metrics to Ganglia is enabled.
management.metrics.export.ganglia.host= # Host of the Ganglia server to receive exported metrics.
management.metrics.export.ganglia.port= # Port of the Ganglia server to receive exported metrics.
management.metrics.export.ganglia.protocol-version= # Ganglia protocol version. Must be either 3.1 or 3.0.
@ -1336,7 +1334,6 @@ content into your application. Rather, pick only the properties that you need.
management.metrics.export.ganglia.step= # Step size (i.e. reporting frequency) to use.
management.metrics.export.ganglia.time-to-live= # Time to live for metrics on Ganglia.
management.metrics.export.graphite.duration-units= # Base time unit used to report durations.
management.metrics.export.graphite.enabled=true # Whether exporting of metrics to Graphite is enabled.
management.metrics.export.graphite.host= # Host of the Graphite server to receive exported metrics.
management.metrics.export.graphite.port= # Port of the Graphite server to receive exported metrics.
management.metrics.export.graphite.protocol= # Protocol to use while shipping data to Graphite.
@ -1348,7 +1345,6 @@ content into your application. Rather, pick only the properties that you need.
management.metrics.export.influx.connect-timeout= # Connection timeout for requests to the backend.
management.metrics.export.influx.consistency= # Write consistency for each point.
management.metrics.export.influx.db= # Tag that will be mapped to "host" when shipping metrics to Influx. Can be omitted if host should be omitted on publishing.
management.metrics.export.influx.enabled=true # Whether exporting of metrics to this backend is enabled.
management.metrics.export.influx.num-threads= # Number of threads to use with the metrics publishing scheduler.
management.metrics.export.influx.password= # Login password of the Influx server.
management.metrics.export.influx.read-timeout= # Read timeout for requests to the backend.
@ -1356,15 +1352,12 @@ content into your application. Rather, pick only the properties that you need.
management.metrics.export.influx.step=1m # Step size (i.e. reporting frequency) to use.
management.metrics.export.influx.uri= # URI of the Influx server.
management.metrics.export.influx.user-name= # Login user of the Influx server.
management.metrics.export.jmx.enabled=true # Whether exporting of metrics to JMX is enabled.
management.metrics.export.jmx.step= # Step size (i.e. reporting frequency) to use.
management.metrics.export.prometheus.descriptions= # Enable publishing descriptions as part of the scrape payload to Prometheus. Turn this off to minimize the amount of data sent on each scrape.
management.metrics.export.prometheus.enabled=true # Whether exporting of metrics to Prometheus is enabled.
management.metrics.export.prometheus.step= # Step size (i.e. reporting frequency) to use.
management.metrics.export.simple.enabled=true # Whether exporting of metrics to a simple in-memory store is enabled.
management.metrics.export.simple.mode=cumulative # Counting mode.
management.metrics.export.simple.step=10s # Step size (i.e. reporting frequency) to use.
management.metrics.export.statsd.enabled=true # Export metrics to StatsD.
management.metrics.export.statsd.flavor=datadog # StatsD line protocol to use.
management.metrics.export.statsd.host=localhost # Host of the StatsD server to receive exported metrics.
management.metrics.export.statsd.max-packet-length=1400 # Total length of a single payload should be kept within your network's MTU.

Loading…
Cancel
Save