Skip to content

Commit e2453a1

Browse files
jkschneiderwilkinsona
authored andcommitted
Add auto-configuration for exporting metrics to StatsD
Closes gh-10522
1 parent ff636b5 commit e2453a1

File tree

8 files changed

+336
-2
lines changed

8 files changed

+336
-2
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@
122122
<artifactId>micrometer-registry-prometheus</artifactId>
123123
<optional>true</optional>
124124
</dependency>
125+
<dependency>
126+
<groupId>io.micrometer</groupId>
127+
<artifactId>micrometer-registry-statsd</artifactId>
128+
<optional>true</optional>
129+
</dependency>
125130
<dependency>
126131
<groupId>io.searchbox</groupId>
127132
<artifactId>jest</artifactId>

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfiguration.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.springframework.boot.actuate.autoconfigure.metrics.export.jmx.JmxExportConfiguration;
3737
import org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusExportConfiguration;
3838
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleExportConfiguration;
39+
import org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdExportConfiguration;
3940
import org.springframework.boot.actuate.autoconfigure.metrics.reactive.server.WebFluxMetricsConfiguration;
4041
import org.springframework.boot.actuate.autoconfigure.metrics.web.client.RestTemplateMetricsConfiguration;
4142
import org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsConfiguration;
@@ -67,7 +68,8 @@
6768
AtlasExportConfiguration.class, DatadogExportConfiguration.class,
6869
GangliaExportConfiguration.class, GraphiteExportConfiguration.class,
6970
InfluxExportConfiguration.class, JmxExportConfiguration.class,
70-
PrometheusExportConfiguration.class, SimpleExportConfiguration.class })
71+
PrometheusExportConfiguration.class, SimpleExportConfiguration.class,
72+
StatsdExportConfiguration.class })
7173
public class MetricsAutoConfiguration {
7274

7375
@Bean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd;
18+
19+
import io.micrometer.core.instrument.Clock;
20+
import io.micrometer.statsd.StatsdConfig;
21+
import io.micrometer.statsd.StatsdMeterRegistry;
22+
23+
import org.springframework.boot.actuate.autoconfigure.metrics.export.MetricsExporter;
24+
import org.springframework.boot.actuate.autoconfigure.metrics.export.StringToDurationConverter;
25+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
26+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
27+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
28+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
29+
import org.springframework.context.annotation.Bean;
30+
import org.springframework.context.annotation.Configuration;
31+
import org.springframework.context.annotation.Import;
32+
33+
/**
34+
* Configuration for exporting metrics to StatsD.
35+
*
36+
* @author Jon Schneider
37+
* @since 2.0.0
38+
*/
39+
@Configuration
40+
@ConditionalOnClass(StatsdMeterRegistry.class)
41+
@Import(StringToDurationConverter.class)
42+
@EnableConfigurationProperties(StatsdProperties.class)
43+
public class StatsdExportConfiguration {
44+
45+
@Bean
46+
@ConditionalOnMissingBean(StatsdConfig.class)
47+
public StatsdConfig statsdConfig(StatsdProperties statsdProperties) {
48+
return new StatsdPropertiesConfigAdapter(statsdProperties);
49+
}
50+
51+
@Bean
52+
@ConditionalOnProperty(value = "spring.metrics.statsd.enabled", matchIfMissing = true)
53+
public MetricsExporter statsdExporter(StatsdConfig statsdConfig, Clock clock) {
54+
return () -> new StatsdMeterRegistry(statsdConfig, clock);
55+
}
56+
57+
@Bean
58+
@ConditionalOnMissingBean
59+
public Clock micrometerClock() {
60+
return Clock.SYSTEM;
61+
}
62+
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd;
18+
19+
import java.time.Duration;
20+
21+
import io.micrometer.statsd.StatsdFlavor;
22+
23+
import org.springframework.boot.context.properties.ConfigurationProperties;
24+
25+
/**
26+
* {@link ConfigurationProperties} for configuring StatsD metrics export.
27+
*
28+
* @author Jon Schneider
29+
* @since 2.0.0
30+
*/
31+
@ConfigurationProperties(prefix = "spring.metrics.statsd")
32+
public class StatsdProperties {
33+
34+
/**
35+
* Enable publishing to the backend.
36+
*/
37+
private Boolean enabled = true;
38+
39+
/**
40+
* Variant of the StatsD line protocol to use.
41+
*/
42+
private StatsdFlavor flavor = StatsdFlavor.Datadog;
43+
44+
/**
45+
* Host name of the StatsD agent.
46+
*/
47+
private String host = "localhost";
48+
49+
/**
50+
* UDP port of the StatsD agent.
51+
*/
52+
private Integer port = 8125;
53+
54+
/**
55+
* Total length of a single payload should be kept within your network's MTU.
56+
*/
57+
private Integer maxPacketLength = 1400;
58+
59+
/**
60+
* Determines how often gauges will be polled. When a gauge is polled, its value is
61+
* recalculated. If the value has changed, it is sent to the StatsD server.
62+
*/
63+
private Duration pollingFrequency = Duration.ofSeconds(10);
64+
65+
/**
66+
* Governs the maximum size of the queue of items waiting to be sent to a StatsD agent
67+
* over UDP.
68+
*/
69+
private Integer queueSize = Integer.MAX_VALUE;
70+
71+
/**
72+
* Used to create a bucket filter clamping the bucket domain of timer percentiles
73+
* histograms to some max value. This is used to limit the number of buckets shipped
74+
* to StatsD to save on storage.
75+
*/
76+
private Duration timerPercentilesMax = Duration.ofMinutes(2);
77+
78+
/**
79+
* Used to create a bucket filter clamping the bucket domain of timer percentiles
80+
* histograms to some min value. This is used to limit the number of buckets shipped
81+
* to StatsD to save on storage.
82+
*/
83+
private Duration timerPercentilesMin = Duration.ofMillis(10);
84+
85+
public Duration getTimerPercentilesMax() {
86+
return this.timerPercentilesMax;
87+
}
88+
89+
public void setTimerPercentilesMax(Duration timerPercentilesMax) {
90+
this.timerPercentilesMax = timerPercentilesMax;
91+
}
92+
93+
public Duration getTimerPercentilesMin() {
94+
return this.timerPercentilesMin;
95+
}
96+
97+
public void setTimerPercentilesMin(Duration timerPercentilesMin) {
98+
this.timerPercentilesMin = timerPercentilesMin;
99+
}
100+
101+
public Boolean getEnabled() {
102+
return this.enabled;
103+
}
104+
105+
public void setEnabled(Boolean enabled) {
106+
this.enabled = enabled;
107+
}
108+
109+
public StatsdFlavor getFlavor() {
110+
return this.flavor;
111+
}
112+
113+
public void setFlavor(StatsdFlavor flavor) {
114+
this.flavor = flavor;
115+
}
116+
117+
public String getHost() {
118+
return this.host;
119+
}
120+
121+
public void setHost(String host) {
122+
this.host = host;
123+
}
124+
125+
public Integer getPort() {
126+
return this.port;
127+
}
128+
129+
public void setPort(Integer port) {
130+
this.port = port;
131+
}
132+
133+
public Integer getMaxPacketLength() {
134+
return this.maxPacketLength;
135+
}
136+
137+
public void setMaxPacketLength(Integer maxPacketLength) {
138+
this.maxPacketLength = maxPacketLength;
139+
}
140+
141+
public Duration getPollingFrequency() {
142+
return this.pollingFrequency;
143+
}
144+
145+
public void setPollingFrequency(Duration pollingFrequency) {
146+
this.pollingFrequency = pollingFrequency;
147+
}
148+
149+
public Integer getQueueSize() {
150+
return this.queueSize;
151+
}
152+
153+
public void setQueueSize(Integer queueSize) {
154+
this.queueSize = queueSize;
155+
}
156+
157+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd;
18+
19+
import java.time.Duration;
20+
21+
import io.micrometer.statsd.StatsdConfig;
22+
import io.micrometer.statsd.StatsdFlavor;
23+
24+
import org.springframework.boot.actuate.autoconfigure.metrics.export.PropertiesConfigAdapter;
25+
26+
/**
27+
* Adapter to convert {@link StatsdProperties} to a {@link StatsdConfig}.
28+
*
29+
* @author Jon Schneider
30+
* @since 2.0.0
31+
*/
32+
public class StatsdPropertiesConfigAdapter extends
33+
PropertiesConfigAdapter<StatsdProperties, StatsdConfig> implements StatsdConfig {
34+
35+
private static final StatsdConfig DEFAULTS = (key) -> null;
36+
37+
public StatsdPropertiesConfigAdapter(StatsdProperties properties) {
38+
super(properties, DEFAULTS);
39+
}
40+
41+
@Override
42+
public String get(String s) {
43+
return null;
44+
}
45+
46+
@Override
47+
public StatsdFlavor flavor() {
48+
return get(StatsdProperties::getFlavor, StatsdConfig::flavor);
49+
}
50+
51+
@Override
52+
public boolean enabled() {
53+
return get(StatsdProperties::getEnabled, StatsdConfig::enabled);
54+
}
55+
56+
@Override
57+
public String host() {
58+
return get(StatsdProperties::getHost, StatsdConfig::host);
59+
}
60+
61+
@Override
62+
public int port() {
63+
return get(StatsdProperties::getPort, StatsdConfig::port);
64+
}
65+
66+
@Override
67+
public int maxPacketLength() {
68+
return get(StatsdProperties::getMaxPacketLength, StatsdConfig::maxPacketLength);
69+
}
70+
71+
@Override
72+
public Duration pollingFrequency() {
73+
return get(StatsdProperties::getPollingFrequency, StatsdConfig::pollingFrequency);
74+
}
75+
76+
@Override
77+
public int queueSize() {
78+
return get(StatsdProperties::getQueueSize, StatsdConfig::queueSize);
79+
}
80+
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Support for exporting actuator metrics to StatsD.
19+
*/
20+
package org.springframework.boot.actuate.autoconfigure.metrics.export.statsd;

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleExportConfigurationTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ public void simpleMeterRegistryIsInTheCompositeWhenNoOtherRegistryIs() {
4545
"spring.metrics.graphite.enabled=false",
4646
"spring.metrics.influx.enabled=false",
4747
"spring.metrics.jmx.enabled=false",
48-
"spring.metrics.prometheus.enabled=false")
48+
"spring.metrics.prometheus.enabled=false",
49+
"spring.metrics.statsd.enabled=false")
4950
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class))
5051
.run((context) -> {
5152
CompositeMeterRegistry meterRegistry = context

spring-boot-project/spring-boot-dependencies/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,11 @@
942942
<artifactId>micrometer-registry-prometheus</artifactId>
943943
<version>${micrometer.version}</version>
944944
</dependency>
945+
<dependency>
946+
<groupId>io.micrometer</groupId>
947+
<artifactId>micrometer-registry-statsd</artifactId>
948+
<version>${micrometer.version}</version>
949+
</dependency>
945950
<dependency>
946951
<groupId>io.netty</groupId>
947952
<artifactId>netty-bom</artifactId>

0 commit comments

Comments
 (0)