Merge pull request #3719 from sbuettner/master
* pr/3719: Add statsd metric export auto-configuration
This commit is contained in:
commit
bf34dc5013
|
@ -29,6 +29,7 @@ import org.springframework.boot.actuate.metrics.export.MetricExportProperties;
|
||||||
import org.springframework.boot.actuate.metrics.export.MetricExporters;
|
import org.springframework.boot.actuate.metrics.export.MetricExporters;
|
||||||
import org.springframework.boot.actuate.metrics.reader.CompositeMetricReader;
|
import org.springframework.boot.actuate.metrics.reader.CompositeMetricReader;
|
||||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||||
|
import org.springframework.boot.actuate.metrics.statsd.StatsdMetricWriter;
|
||||||
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
|
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
@ -45,6 +46,7 @@ import org.springframework.util.CollectionUtils;
|
||||||
* {@link EnableAutoConfiguration Auto-configuration} for metrics export.
|
* {@link EnableAutoConfiguration Auto-configuration} for metrics export.
|
||||||
*
|
*
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
|
* @author Simon Buettner
|
||||||
* @since 1.3.0
|
* @since 1.3.0
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@ -92,6 +94,16 @@ public class MetricExportAutoConfiguration {
|
||||||
return exporters;
|
return exporters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ExportMetricWriter
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
@ConditionalOnProperty(prefix = "spring.metrics.export.statsd", name = "host")
|
||||||
|
public StatsdMetricWriter statsdMetricWriter() {
|
||||||
|
MetricExportProperties.Statsd statsdProperties = this.properties.getStatsd();
|
||||||
|
return new StatsdMetricWriter(statsdProperties.getPrefix(),
|
||||||
|
statsdProperties.getHost(), statsdProperties.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
protected static class MetricExportPropertiesConfiguration {
|
protected static class MetricExportPropertiesConfiguration {
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.springframework.util.PatternMatchUtils;
|
||||||
* Configuration properties for metrics export.
|
* Configuration properties for metrics export.
|
||||||
*
|
*
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
|
* @author Simon Buettner
|
||||||
* @since 1.3.0
|
* @since 1.3.0
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties("spring.metrics.export")
|
@ConfigurationProperties("spring.metrics.export")
|
||||||
|
@ -43,6 +44,8 @@ public class MetricExportProperties extends TriggerProperties {
|
||||||
|
|
||||||
private Redis redis = new Redis();
|
private Redis redis = new Redis();
|
||||||
|
|
||||||
|
private Statsd statsd = new Statsd();
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void setUpDefaults() {
|
public void setUpDefaults() {
|
||||||
TriggerProperties defaults = this;
|
TriggerProperties defaults = this;
|
||||||
|
@ -79,10 +82,6 @@ public class MetricExportProperties extends TriggerProperties {
|
||||||
return this.triggers;
|
return this.triggers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Redis getRedis() {
|
|
||||||
return this.redis;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Aggregate getAggregate() {
|
public Aggregate getAggregate() {
|
||||||
return this.aggregate;
|
return this.aggregate;
|
||||||
}
|
}
|
||||||
|
@ -91,10 +90,22 @@ public class MetricExportProperties extends TriggerProperties {
|
||||||
this.aggregate = aggregate;
|
this.aggregate = aggregate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Redis getRedis() {
|
||||||
|
return this.redis;
|
||||||
|
}
|
||||||
|
|
||||||
public void setRedis(Redis redis) {
|
public void setRedis(Redis redis) {
|
||||||
this.redis = redis;
|
this.redis = redis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Statsd getStatsd() {
|
||||||
|
return this.statsd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatsd(Statsd statsd) {
|
||||||
|
this.statsd = statsd;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a matching trigger configuration.
|
* Find a matching trigger configuration.
|
||||||
* @param name the bean name to match
|
* @param name the bean name to match
|
||||||
|
@ -205,4 +216,50 @@ public class MetricExportProperties extends TriggerProperties {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statsd properties.
|
||||||
|
*/
|
||||||
|
public static class Statsd {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Host of a statsd server to receive exported metrics.
|
||||||
|
*/
|
||||||
|
private String host;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Port of a statsd server to receive exported metrics.
|
||||||
|
*/
|
||||||
|
private int port = 8125;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix for statsd exported metrics.
|
||||||
|
*/
|
||||||
|
private String prefix;
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return this.host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return this.port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrefix() {
|
||||||
|
return this.prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrefix(String prefix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,16 +17,21 @@
|
||||||
package org.springframework.boot.actuate.autoconfigure;
|
package org.springframework.boot.actuate.autoconfigure;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
import org.mockito.Matchers;
|
import org.mockito.Matchers;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.boot.actuate.endpoint.MetricsEndpointMetricReader;
|
import org.springframework.boot.actuate.endpoint.MetricsEndpointMetricReader;
|
||||||
import org.springframework.boot.actuate.metrics.GaugeService;
|
import org.springframework.boot.actuate.metrics.GaugeService;
|
||||||
import org.springframework.boot.actuate.metrics.Metric;
|
import org.springframework.boot.actuate.metrics.Metric;
|
||||||
import org.springframework.boot.actuate.metrics.export.MetricCopyExporter;
|
import org.springframework.boot.actuate.metrics.export.MetricCopyExporter;
|
||||||
import org.springframework.boot.actuate.metrics.export.MetricExporters;
|
import org.springframework.boot.actuate.metrics.export.MetricExporters;
|
||||||
|
import org.springframework.boot.actuate.metrics.statsd.StatsdMetricWriter;
|
||||||
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
|
import org.springframework.boot.actuate.metrics.writer.MetricWriter;
|
||||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
@ -36,16 +41,22 @@ import org.springframework.messaging.MessageHandler;
|
||||||
import org.springframework.messaging.MessagingException;
|
import org.springframework.messaging.MessagingException;
|
||||||
import org.springframework.messaging.SubscribableChannel;
|
import org.springframework.messaging.SubscribableChannel;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link MetricExportAutoConfiguration}.
|
* Tests for {@link MetricExportAutoConfiguration}.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
|
* @author Simon Buettner
|
||||||
*/
|
*/
|
||||||
public class MetricExportAutoConfigurationTests {
|
public class MetricExportAutoConfigurationTests {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
private AnnotationConfigApplicationContext context;
|
private AnnotationConfigApplicationContext context;
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -100,16 +111,43 @@ public class MetricExportAutoConfigurationTests {
|
||||||
Mockito.verify(reader, Mockito.atLeastOnce()).findAll();
|
Mockito.verify(reader, Mockito.atLeastOnce()).findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void statsdMissingHost() throws Exception {
|
||||||
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
|
this.context.register(WriterConfig.class, MetricEndpointConfiguration.class,
|
||||||
|
MetricExportAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
|
this.context.refresh();
|
||||||
|
this.thrown.expect(NoSuchBeanDefinitionException.class);
|
||||||
|
this.context.getBean(StatsdMetricWriter.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void statsdWithHost() throws Exception {
|
||||||
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
|
EnvironmentTestUtils.addEnvironment(this.context,
|
||||||
|
"spring.metrics.export.statsd.host=localhost");
|
||||||
|
this.context.register(WriterConfig.class, MetricEndpointConfiguration.class,
|
||||||
|
MetricExportAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
|
this.context.refresh();
|
||||||
|
assertThat(this.context.getBean(StatsdMetricWriter.class), notNullValue());
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public static class MessageChannelConfiguration {
|
public static class MessageChannelConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SubscribableChannel metricsChannel() {
|
public SubscribableChannel metricsChannel() {
|
||||||
return new FixedSubscriberChannel(new MessageHandler() {
|
return new FixedSubscriberChannel(new MessageHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message<?> message) throws MessagingException {
|
public void handleMessage(Message<?> message) throws MessagingException {
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|
|
@ -790,6 +790,9 @@ content into your application; rather pick only the properties that you need.
|
||||||
spring.metrics.export.excludes= # list of patterns for metric names to exclude. Applied after the includes
|
spring.metrics.export.excludes= # list of patterns for metric names to exclude. Applied after the includes
|
||||||
spring.metrics.export.redis.prefix=spring.metrics # prefix for redis repository if active
|
spring.metrics.export.redis.prefix=spring.metrics # prefix for redis repository if active
|
||||||
spring.metrics.export.redis.key=keys.spring.metrics # key for redis repository export (if active)
|
spring.metrics.export.redis.key=keys.spring.metrics # key for redis repository export (if active)
|
||||||
|
spring.metrics.export.statsd.host= # host of the statsd server
|
||||||
|
spring.metrics.export.statsd.port=8125 # port of the statsd server
|
||||||
|
spring.metrics.export.statsd.prefix= # prefix for exported metrics
|
||||||
spring.metrics.export.triggers.*= # specific trigger properties per MetricWriter bean name
|
spring.metrics.export.triggers.*= # specific trigger properties per MetricWriter bean name
|
||||||
|
|
||||||
# SENDGRID ({sc-spring-boot-autoconfigure}/sendgrid/SendGridAutoConfiguration.{sc-ext}[SendGridAutoConfiguration])
|
# SENDGRID ({sc-spring-boot-autoconfigure}/sendgrid/SendGridAutoConfiguration.{sc-ext}[SendGridAutoConfiguration])
|
||||||
|
|
|
@ -1142,28 +1142,28 @@ curl localhost:4242/api/query?start=1h-ago&m=max:counter.status.200.root
|
||||||
|
|
||||||
[[production-ready-metric-writers-export-to-statsd]]
|
[[production-ready-metric-writers-export-to-statsd]]
|
||||||
==== Example: Export to Statsd
|
==== Example: Export to Statsd
|
||||||
If you provide a `@Bean` of type `StatsdMetricWriter` and mark it `@ExportMetricWriter` the metrics are exported to a
|
To export metrics to Statsd add a `spring.metrics.export.statsd.host` value to your
|
||||||
statsd server:
|
`application.properties` file. Connections will be opened to port `8125` unless a
|
||||||
|
`spring.metrics.export.statsd.port` override is provided. You can use
|
||||||
|
`spring.metrics.export.statsd.prefix` if you want a custom prefix.
|
||||||
|
|
||||||
|
Alternatively, you can provide a `@Bean` of type `StatsdMetricWriter` and mark it
|
||||||
|
`@ExportMetricWriter`:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
----
|
----
|
||||||
@Value("${spring.application.name:application}.${random.value:0000}")
|
@Value("${spring.application.name:application}.${random.value:0000}")
|
||||||
private String prefix = "metrics";
|
private String prefix = "metrics";
|
||||||
|
|
||||||
@Value("${statsd.host:localhost}")
|
|
||||||
private String host = "localhost";
|
|
||||||
|
|
||||||
@Value("${statsd.port:8125}")
|
|
||||||
private int port;
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ExportMetricWriter
|
@ExportMetricWriter
|
||||||
MetricWriter metricWriter() {
|
MetricWriter metricWriter() {
|
||||||
return new StatsdMetricWriter(prefix, host, port);
|
return new StatsdMetricWriter(prefix, "localhost", "8125");
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[production-ready-metric-writers-export-to-jmx]]
|
[[production-ready-metric-writers-export-to-jmx]]
|
||||||
==== Example: Export to JMX
|
==== Example: Export to JMX
|
||||||
If you provide a `@Bean` of type `JmxMetricWriter` marked `@ExportMetricWriter` the metrics are exported as MBeans to
|
If you provide a `@Bean` of type `JmxMetricWriter` marked `@ExportMetricWriter` the metrics are exported as MBeans to
|
||||||
|
|
Loading…
Reference in New Issue