From e2453a17c7b87a827d87ae6ea63da74ed6f0b992 Mon Sep 17 00:00:00 2001 From: Jon Schneider Date: Wed, 4 Oct 2017 22:20:30 -0500 Subject: [PATCH] Add auto-configuration for exporting metrics to StatsD Closes gh-10522 --- .../pom.xml | 5 + .../metrics/MetricsAutoConfiguration.java | 4 +- .../statsd/StatsdExportConfiguration.java | 63 +++++++ .../export/statsd/StatsdProperties.java | 157 ++++++++++++++++++ .../statsd/StatsdPropertiesConfigAdapter.java | 81 +++++++++ .../metrics/export/statsd/package-info.java | 20 +++ .../SimpleExportConfigurationTests.java | 3 +- .../spring-boot-dependencies/pom.xml | 5 + 8 files changed, 336 insertions(+), 2 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdExportConfiguration.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdProperties.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesConfigAdapter.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/package-info.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml index 9c7e2f9550c..4a977c5d439 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml @@ -122,6 +122,11 @@ micrometer-registry-prometheus true + + io.micrometer + micrometer-registry-statsd + true + io.searchbox jest diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java index 14562127991..515a14fe287 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java @@ -36,6 +36,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.influx.Infl 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.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; @@ -67,7 +68,8 @@ import org.springframework.integration.support.management.IntegrationManagementC AtlasExportConfiguration.class, DatadogExportConfiguration.class, GangliaExportConfiguration.class, GraphiteExportConfiguration.class, InfluxExportConfiguration.class, JmxExportConfiguration.class, - PrometheusExportConfiguration.class, SimpleExportConfiguration.class }) + PrometheusExportConfiguration.class, SimpleExportConfiguration.class, + StatsdExportConfiguration.class }) public class MetricsAutoConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdExportConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdExportConfiguration.java new file mode 100644 index 00000000000..1b52307208b --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdExportConfiguration.java @@ -0,0 +1,63 @@ +/* + * Copyright 2012-2017 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.statsd.StatsdConfig; +import io.micrometer.statsd.StatsdMeterRegistry; + +import org.springframework.boot.actuate.autoconfigure.metrics.export.MetricsExporter; +import org.springframework.boot.actuate.autoconfigure.metrics.export.StringToDurationConverter; +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; +import org.springframework.context.annotation.Import; + +/** + * Configuration for exporting metrics to StatsD. + * + * @author Jon Schneider + * @since 2.0.0 + */ +@Configuration +@ConditionalOnClass(StatsdMeterRegistry.class) +@Import(StringToDurationConverter.class) +@EnableConfigurationProperties(StatsdProperties.class) +public class StatsdExportConfiguration { + + @Bean + @ConditionalOnMissingBean(StatsdConfig.class) + public StatsdConfig statsdConfig(StatsdProperties statsdProperties) { + return new StatsdPropertiesConfigAdapter(statsdProperties); + } + + @Bean + @ConditionalOnProperty(value = "spring.metrics.statsd.enabled", matchIfMissing = true) + public MetricsExporter statsdExporter(StatsdConfig statsdConfig, Clock clock) { + return () -> new StatsdMeterRegistry(statsdConfig, clock); + } + + @Bean + @ConditionalOnMissingBean + public Clock micrometerClock() { + return Clock.SYSTEM; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdProperties.java new file mode 100644 index 00000000000..acce7ecdfff --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdProperties.java @@ -0,0 +1,157 @@ +/* + * Copyright 2012-2017 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 java.time.Duration; + +import io.micrometer.statsd.StatsdFlavor; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * {@link ConfigurationProperties} for configuring StatsD metrics export. + * + * @author Jon Schneider + * @since 2.0.0 + */ +@ConfigurationProperties(prefix = "spring.metrics.statsd") +public class StatsdProperties { + + /** + * Enable publishing to the backend. + */ + private Boolean enabled = true; + + /** + * Variant of the StatsD line protocol to use. + */ + private StatsdFlavor flavor = StatsdFlavor.Datadog; + + /** + * Host name of the StatsD agent. + */ + private String host = "localhost"; + + /** + * UDP port of the StatsD agent. + */ + private Integer port = 8125; + + /** + * Total length of a single payload should be kept within your network's MTU. + */ + private Integer maxPacketLength = 1400; + + /** + * Determines how often gauges will be polled. When a gauge is polled, its value is + * recalculated. If the value has changed, it is sent to the StatsD server. + */ + private Duration pollingFrequency = Duration.ofSeconds(10); + + /** + * Governs the maximum size of the queue of items waiting to be sent to a StatsD agent + * over UDP. + */ + private Integer queueSize = Integer.MAX_VALUE; + + /** + * Used to create a bucket filter clamping the bucket domain of timer percentiles + * histograms to some max value. This is used to limit the number of buckets shipped + * to StatsD to save on storage. + */ + private Duration timerPercentilesMax = Duration.ofMinutes(2); + + /** + * Used to create a bucket filter clamping the bucket domain of timer percentiles + * histograms to some min value. This is used to limit the number of buckets shipped + * to StatsD to save on storage. + */ + private Duration timerPercentilesMin = Duration.ofMillis(10); + + public Duration getTimerPercentilesMax() { + return this.timerPercentilesMax; + } + + public void setTimerPercentilesMax(Duration timerPercentilesMax) { + this.timerPercentilesMax = timerPercentilesMax; + } + + public Duration getTimerPercentilesMin() { + return this.timerPercentilesMin; + } + + public void setTimerPercentilesMin(Duration timerPercentilesMin) { + this.timerPercentilesMin = timerPercentilesMin; + } + + public Boolean getEnabled() { + return this.enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public StatsdFlavor getFlavor() { + return this.flavor; + } + + public void setFlavor(StatsdFlavor flavor) { + this.flavor = flavor; + } + + public String getHost() { + return this.host; + } + + public void setHost(String host) { + this.host = host; + } + + public Integer getPort() { + return this.port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public Integer getMaxPacketLength() { + return this.maxPacketLength; + } + + public void setMaxPacketLength(Integer maxPacketLength) { + this.maxPacketLength = maxPacketLength; + } + + public Duration getPollingFrequency() { + return this.pollingFrequency; + } + + public void setPollingFrequency(Duration pollingFrequency) { + this.pollingFrequency = pollingFrequency; + } + + public Integer getQueueSize() { + return this.queueSize; + } + + public void setQueueSize(Integer queueSize) { + this.queueSize = queueSize; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesConfigAdapter.java new file mode 100644 index 00000000000..840be63de53 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/StatsdPropertiesConfigAdapter.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-2017 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 java.time.Duration; + +import io.micrometer.statsd.StatsdConfig; +import io.micrometer.statsd.StatsdFlavor; + +import org.springframework.boot.actuate.autoconfigure.metrics.export.PropertiesConfigAdapter; + +/** + * Adapter to convert {@link StatsdProperties} to a {@link StatsdConfig}. + * + * @author Jon Schneider + * @since 2.0.0 + */ +public class StatsdPropertiesConfigAdapter extends + PropertiesConfigAdapter implements StatsdConfig { + + private static final StatsdConfig DEFAULTS = (key) -> null; + + public StatsdPropertiesConfigAdapter(StatsdProperties properties) { + super(properties, DEFAULTS); + } + + @Override + public String get(String s) { + return null; + } + + @Override + public StatsdFlavor flavor() { + return get(StatsdProperties::getFlavor, StatsdConfig::flavor); + } + + @Override + public boolean enabled() { + return get(StatsdProperties::getEnabled, StatsdConfig::enabled); + } + + @Override + public String host() { + return get(StatsdProperties::getHost, StatsdConfig::host); + } + + @Override + public int port() { + return get(StatsdProperties::getPort, StatsdConfig::port); + } + + @Override + public int maxPacketLength() { + return get(StatsdProperties::getMaxPacketLength, StatsdConfig::maxPacketLength); + } + + @Override + public Duration pollingFrequency() { + return get(StatsdProperties::getPollingFrequency, StatsdConfig::pollingFrequency); + } + + @Override + public int queueSize() { + return get(StatsdProperties::getQueueSize, StatsdConfig::queueSize); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/package-info.java new file mode 100644 index 00000000000..b2eec12eb2e --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/statsd/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-2017 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. + */ + +/** + * Support for exporting actuator metrics to StatsD. + */ +package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleExportConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleExportConfigurationTests.java index 3f6af8de688..4a76b3a69cd 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleExportConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleExportConfigurationTests.java @@ -45,7 +45,8 @@ public class SimpleExportConfigurationTests { "spring.metrics.graphite.enabled=false", "spring.metrics.influx.enabled=false", "spring.metrics.jmx.enabled=false", - "spring.metrics.prometheus.enabled=false") + "spring.metrics.prometheus.enabled=false", + "spring.metrics.statsd.enabled=false") .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class)) .run((context) -> { CompositeMeterRegistry meterRegistry = context diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index 23c8f1d0788..15c2c1aa63e 100644 --- a/spring-boot-project/spring-boot-dependencies/pom.xml +++ b/spring-boot-project/spring-boot-dependencies/pom.xml @@ -942,6 +942,11 @@ micrometer-registry-prometheus ${micrometer.version} + + io.micrometer + micrometer-registry-statsd + ${micrometer.version} + io.netty netty-bom