diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml index c202ae0e1a..d5be052b68 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml @@ -137,6 +137,11 @@ micrometer-registry-jmx true + + io.micrometer + micrometer-registry-kairos + true + io.micrometer micrometer-registry-new-relic diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfiguration.java new file mode 100644 index 0000000000..d1a6ba9681 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfiguration.java @@ -0,0 +1,66 @@ +/* + * 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.kairos; + +import io.micrometer.core.instrument.Clock; +import io.micrometer.kairos.KairosConfig; +import io.micrometer.kairos.KairosMeterRegistry; + +import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +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.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to KairosDB. + * + * @author Stephane Nicoll + * @since 2.1.0 + */ +@Configuration +@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, + SimpleMetricsExportAutoConfiguration.class }) +@AutoConfigureAfter(MetricsAutoConfiguration.class) +@ConditionalOnBean(Clock.class) +@ConditionalOnClass(KairosMeterRegistry.class) +@ConditionalOnProperty(prefix = "management.metrics.export.kairos", name = "enabled", havingValue = "true", matchIfMissing = true) +@EnableConfigurationProperties(KairosProperties.class) +public class KairosMetricsExportAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public KairosConfig kairosConfig(KairosProperties kairosProperties) { + return new KairosPropertiesConfigAdapter(kairosProperties); + } + + @Bean + @ConditionalOnMissingBean + public KairosMeterRegistry kairosMeterRegistry(KairosConfig kairosConfig, + Clock clock) { + return new KairosMeterRegistry(kairosConfig, clock); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosProperties.java new file mode 100644 index 0000000000..412f70a6f3 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosProperties.java @@ -0,0 +1,70 @@ +/* + * 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.kairos; + +import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * {@link ConfigurationProperties} for configuring KairosDB metrics export. + * + * @author Stephane Nicoll + * @since 2.1.0 + */ +@ConfigurationProperties(prefix = "management.metrics.export.kairos") +public class KairosProperties extends StepRegistryProperties { + + /** + * URI of the KairosDB server. + */ + private String uri = "http://localhost:8080/api/v1/datapoints"; + + /** + * Login user of the KairosDB server. + */ + private String userName; + + /** + * Login password of the KairosDB server. + */ + private String password; + + public String getUri() { + return this.uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getUserName() { + return this.userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesConfigAdapter.java new file mode 100644 index 0000000000..edb95f8f9a --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesConfigAdapter.java @@ -0,0 +1,50 @@ +/* + * 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.kairos; + +import io.micrometer.kairos.KairosConfig; + +import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesConfigAdapter; + +/** + * Adapter to convert {@link KairosProperties} to an {@link KairosConfig}. + * + * @author Stephane Nicoll + */ +class KairosPropertiesConfigAdapter extends + StepRegistryPropertiesConfigAdapter implements KairosConfig { + + KairosPropertiesConfigAdapter(KairosProperties properties) { + super(properties); + } + + @Override + public String uri() { + return get(KairosProperties::getUri, KairosConfig.super::uri); + } + + @Override + public String userName() { + return get(KairosProperties::getUserName, KairosConfig.super::userName); + } + + @Override + public String password() { + return get(KairosProperties::getPassword, KairosConfig.super::password); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/package-info.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/package-info.java new file mode 100644 index 0000000000..de6efe3184 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Support for exporting actuator metrics to KairosDB. + */ +package org.springframework.boot.actuate.autoconfigure.metrics.export.kairos; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories index da69ef3055..8b5b335e12 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories @@ -54,6 +54,7 @@ org.springframework.boot.actuate.autoconfigure.metrics.export.ganglia.GangliaMet 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.kairos.KairosMetricsExportAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.metrics.export.newrelic.NewRelicMetricsExportAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.metrics.export.signalfx.SignalFxMetricsExportAutoConfiguration,\ diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfigurationTests.java new file mode 100644 index 0000000000..0215a7cb92 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosMetricsExportAutoConfigurationTests.java @@ -0,0 +1,145 @@ +/* + * 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.kairos; + +import java.util.Map; + +import io.micrometer.core.instrument.Clock; +import io.micrometer.kairos.KairosConfig; +import io.micrometer.kairos.KairosMeterRegistry; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +/** + * Tests for {@link KairosMetricsExportAutoConfiguration}. + * + * @author Stephane Nicoll + */ +public class KairosMetricsExportAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(KairosMetricsExportAutoConfiguration.class)); + + @Test + public void backsOffWithoutAClock() { + this.contextRunner.run((context) -> assertThat(context) + .doesNotHaveBean(KairosMeterRegistry.class)); + } + + @Test + public void autoConfiguresItsConfigAndMeterRegistry() { + this.contextRunner.withUserConfiguration(BaseConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(KairosMeterRegistry.class) + .hasSingleBean(KairosConfig.class)); + } + + @Test + public void autoConfigurationCanBeDisabled() { + this.contextRunner.withUserConfiguration(BaseConfiguration.class) + .withPropertyValues("management.metrics.export.kairos.enabled=false") + .run((context) -> assertThat(context) + .doesNotHaveBean(KairosMeterRegistry.class) + .doesNotHaveBean(KairosConfig.class)); + } + + @Test + public void allowsCustomConfigToBeUsed() { + this.contextRunner.withUserConfiguration(CustomConfigConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(KairosMeterRegistry.class) + .hasSingleBean(KairosConfig.class).hasBean("customConfig")); + } + + @Test + public void allowsCustomRegistryToBeUsed() { + this.contextRunner.withUserConfiguration(CustomRegistryConfiguration.class) + .run((context) -> assertThat(context) + .hasSingleBean(KairosMeterRegistry.class) + .hasBean("customRegistry").hasSingleBean(KairosConfig.class)); + } + + @Test + public void stopsMeterRegistryWhenContextIsClosed() { + this.contextRunner.withUserConfiguration(BaseConfiguration.class) + .run((context) -> { + KairosMeterRegistry registry = spyOnDisposableBean( + KairosMeterRegistry.class, context); + context.close(); + verify(registry).stop(); + }); + } + + @SuppressWarnings("unchecked") + private T spyOnDisposableBean(Class type, + AssertableApplicationContext context) { + String[] names = context.getBeanNamesForType(type); + assertThat(names).hasSize(1); + String registryBeanName = names[0]; + Map disposableBeans = (Map) ReflectionTestUtils + .getField(context.getAutowireCapableBeanFactory(), "disposableBeans"); + Object registryAdapter = disposableBeans.get(registryBeanName); + T registry = (T) spy(ReflectionTestUtils.getField(registryAdapter, "bean")); + ReflectionTestUtils.setField(registryAdapter, "bean", registry); + return registry; + } + + @Configuration + static class BaseConfiguration { + + @Bean + public Clock clock() { + return Clock.SYSTEM; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomConfigConfiguration { + + @Bean + public KairosConfig customConfig() { + return (key) -> null; + } + + } + + @Configuration + @Import(BaseConfiguration.class) + static class CustomRegistryConfiguration { + + @Bean + public KairosMeterRegistry customRegistry(KairosConfig config, Clock clock) { + return new KairosMeterRegistry(config, clock); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesTests.java new file mode 100644 index 0000000000..361b6a7505 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/kairos/KairosPropertiesTests.java @@ -0,0 +1,44 @@ +/* + * 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.kairos; + +import io.micrometer.kairos.KairosConfig; + +import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.StepRegistryPropertiesTests; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link KairosProperties}. + * + * @author Stephane Nicoll + */ +public class KairosPropertiesTests extends StepRegistryPropertiesTests { + + @Override + public void defaultValuesAreConsistent() { + KairosProperties properties = new KairosProperties(); + KairosConfig config = KairosConfig.DEFAULT; + assertStepRegistryDefaultValues(properties, config); + assertThat(properties.getUri()).isEqualToIgnoringWhitespace(config.uri()); + assertThat(properties.getUserName()) + .isEqualToIgnoringWhitespace(config.userName()); + assertThat(properties.getPassword()) + .isEqualToIgnoringWhitespace(config.password()); + } + +} diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index 6152cc0672..374d0d5eda 100644 --- a/spring-boot-project/spring-boot-dependencies/pom.xml +++ b/spring-boot-project/spring-boot-dependencies/pom.xml @@ -948,6 +948,11 @@ micrometer-registry-jmx ${micrometer.version} + + io.micrometer + micrometer-registry-kairos + ${micrometer.version} + io.micrometer micrometer-registry-new-relic diff --git a/spring-boot-project/spring-boot-docs/pom.xml b/spring-boot-project/spring-boot-docs/pom.xml index 677e9a743b..5c7c0ccc13 100644 --- a/spring-boot-project/spring-boot-docs/pom.xml +++ b/spring-boot-project/spring-boot-docs/pom.xml @@ -246,6 +246,11 @@ micrometer-registry-jmx true + + io.micrometer + micrometer-registry-kairos + true + io.micrometer micrometer-registry-new-relic diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 14db74f9cb..522d577c1a 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -1468,6 +1468,15 @@ content into your application. Rather, pick only the properties that you need. management.metrics.export.jmx.domain=metrics # Metrics JMX domain name. management.metrics.export.jmx.enabled=true # Whether exporting of metrics to JMX is enabled. management.metrics.export.jmx.step=1m # Step size (i.e. reporting frequency) to use. + management.metrics.export.kairos.batch-size=10000 # Number of measurements per request to use for this backend. If more measurements are found, then multiple requests will be made. + management.metrics.export.kairos.connect-timeout=1s # Connection timeout for requests to this backend. + management.metrics.export.kairos.enabled=true # Whether exporting of metrics to this backend is enabled. + management.metrics.export.kairos.num-threads=2 # Number of threads to use with the metrics publishing scheduler. + management.metrics.export.kairos.password= # Login password of the KairosDB server. + management.metrics.export.kairos.read-timeout=10s # Read timeout for requests to this backend. + management.metrics.export.kairos.step=1m # Step size (i.e. reporting frequency) to use. + management.metrics.export.kairos.uri= http://localhost:8080/api/v1/datapoints # URI of the KairosDB server. + management.metrics.export.kairos.user-name= # Login user of the KairosDB server. management.metrics.export.newrelic.account-id= # New Relic account ID. management.metrics.export.newrelic.api-key= # New Relic API key. management.metrics.export.newrelic.batch-size=10000 # Number of measurements per request to use for this backend. If more measurements are found, then multiple requests will be made. diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc index de14dccbc8..fd6d63a262 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc @@ -1352,6 +1352,7 @@ monitoring systems, including: - <> - <> - <> +- <> - <> - <> - <> @@ -1586,6 +1587,19 @@ public JmxMeterRegistry jmxMeterRegistry(JmxConfig config, Clock clock) { +[[production-ready-metrics-export-kairos]] +==== KairosDB +By default, metrics are exported to {micrometer-registry-documentation}/kairos[KairosDB] +running on your local machine. The location of the https://kairosdb.github.io/[KairosDB +server] to use can be provided using: + +[source,properties,indent=0] +---- + management.metrics.export.kairos.uri=http://kairosdb.example.com:8080/api/v1/datapoints +---- + + + [[production-ready-metrics-export-newrelic]] ==== New Relic New Relic registry pushes metrics to {micrometer-registry-documentation}/new-relic[New