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 41ae385908..486191de2e 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 @@ -52,6 +52,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SearchStrategy; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -64,6 +65,7 @@ import org.springframework.integration.support.management.IntegrationManagementC * * @since 2.0.0 * @author Jon Schneider + * @author Stephane Nicoll */ @Configuration @ConditionalOnClass(Timed.class) @@ -76,7 +78,8 @@ import org.springframework.integration.support.management.IntegrationManagementC InfluxExportConfiguration.class, JmxExportConfiguration.class, PrometheusExportConfiguration.class, SimpleExportConfiguration.class, StatsdExportConfiguration.class }) -@AutoConfigureAfter({ CacheAutoConfiguration.class, DataSourceAutoConfiguration.class }) +@AutoConfigureAfter({ CacheAutoConfiguration.class, DataSourceAutoConfiguration.class, + RestTemplateAutoConfiguration.class }) public class MetricsAutoConfiguration { @Bean @@ -87,21 +90,16 @@ public class MetricsAutoConfiguration { ObjectProvider> configurers) { CompositeMeterRegistry composite = metricsProperties.isUseGlobalRegistry() ? Metrics.globalRegistry : new CompositeMeterRegistry(); - - if (configurers.getIfAvailable() != null) { - configurers.getIfAvailable(Collections::emptyList) - .forEach((configurer) -> configurer.configureRegistry(composite)); - } - - if (exporters.getIfAvailable() != null) { - exporters.getIfAvailable().forEach(exporter -> { - final MeterRegistry childRegistry = exporter.registry(); - if (composite == childRegistry) { - throw new IllegalStateException("cannot add a CompositeMeterRegistry to itself"); - } - composite.add(childRegistry); - }); - } + configurers.getIfAvailable(Collections::emptyList) + .forEach((configurer) -> configurer.configureRegistry(composite)); + exporters.getIfAvailable(Collections::emptyList).forEach(exporter -> { + MeterRegistry childRegistry = exporter.registry(); + if (composite == childRegistry) { + throw new IllegalStateException( + "cannot add a CompositeMeterRegistry to itself"); + } + composite.add(childRegistry); + }); return composite; } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogProperties.java index a258db9799..f8b3c74a98 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogProperties.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogProperties.java @@ -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. @@ -40,8 +40,8 @@ public class DatadogProperties extends StepRegistryProperties { private String applicationKey; /** - * Enable publishing descriptions metadata to Datadog. Turn - * this off to minimize the amount of metadata sent. + * Whether to publish descriptions metadata to Datadog. Turn this off to minimize the + * amount of metadata sent. */ private Boolean descriptions; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapter.java index 4a4655038a..3e5b03c052 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapter.java @@ -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. @@ -58,4 +58,5 @@ class DatadogPropertiesConfigAdapter public boolean descriptions() { return get(DatadogProperties::getDescriptions, DatadogConfig.super::descriptions); } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxExportConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxExportConfiguration.java index a6f54b729d..de71666e55 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxExportConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxExportConfiguration.java @@ -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. diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxProperties.java index ee52ed602e..ae73fb4bc7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxProperties.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxProperties.java @@ -28,6 +28,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; */ @ConfigurationProperties(prefix = "management.metrics.export.jmx") public class JmxProperties { + /** * Step size (i.e. reporting frequency) to use. */ diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesConfigAdapter.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesConfigAdapter.java index 3211c98034..1741a6496f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesConfigAdapter.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/jmx/JmxPropertiesConfigAdapter.java @@ -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. @@ -43,4 +43,5 @@ class JmxPropertiesConfigAdapter extends PropertiesConfigAdapter public Duration step() { return get(JmxProperties::getStep, JmxConfig.super::step); } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfiguration.java index c16632370d..0e54df99c4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfiguration.java @@ -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. diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryConfigurerTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryConfigurerTests.java index f00eb836f4..2b3d4e98c7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryConfigurerTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryConfigurerTests.java @@ -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. @@ -40,7 +40,7 @@ public class MeterRegistryConfigurerTests { .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class)) .withConfiguration( UserConfigurations.of(MeterRegistryConfigurerConfiguration.class)) - .withPropertyValues("metrics.use-global-registry=false") + .withPropertyValues("management.metrics.use-global-registry=false") .run((context) -> assertThat(context.getBean(MeterRegistry.class) .find("jvm.memory.used").tags("region", "us-east-1").gauge()) .isPresent()); @@ -52,7 +52,7 @@ public class MeterRegistryConfigurerTests { .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class)) .withConfiguration( UserConfigurations.of(MeterRegistryConfigurerConfiguration.class)) - .withPropertyValues("metrics.use-global-registry=false") + .withPropertyValues("management.metrics.use-global-registry=false") .run((context) -> assertThat(context.getBean(MeterRegistry.class) .find("my.thing").tags("region", "us-east-1").gauge()) .isPresent()); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationIntegrationTests.java index 5fb91f9d6c..bc57384bad 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationIntegrationTests.java @@ -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. @@ -32,17 +32,17 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.metrics.web.client.DefaultRestTemplateExchangeTagsProvider; -import org.springframework.boot.actuate.metrics.web.client.MetricsRestTemplateCustomizer; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -115,7 +115,8 @@ public class MetricsAutoConfigurationIntegrationTests { @Configuration @ImportAutoConfiguration({ MetricsAutoConfiguration.class, JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + RestTemplateAutoConfiguration.class, WebMvcAutoConfiguration.class, + DispatcherServletAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class }) @Import(PersonController.class) static class MetricsApp { @@ -126,12 +127,8 @@ public class MetricsAutoConfigurationIntegrationTests { } @Bean - public RestTemplate restTemplate(MeterRegistry registry) { - RestTemplate restTemplate = new RestTemplate(); - MetricsRestTemplateCustomizer customizer = new MetricsRestTemplateCustomizer( - registry, new DefaultRestTemplateExchangeTagsProvider(), "http.client.requests", false); - customizer.customize(restTemplate); - return restTemplate; + public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) { + return restTemplateBuilder.build(); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java index 624b58cb65..4478bb7cb0 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationTests.java @@ -41,6 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class MetricsAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("management.metrics.use-global-registry=false") .withUserConfiguration(RegistryConfiguration.class) .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class)); @@ -49,8 +50,7 @@ public class MetricsAutoConfigurationTests { this.contextRunner .withConfiguration( AutoConfigurations.of(DataSourceAutoConfiguration.class)) - .withPropertyValues("spring.datasource.generate-unique-name=true", - "management.metrics.use-global-registry=false") + .withPropertyValues("spring.datasource.generate-unique-name=true") .run((context) -> { context.getBean(DataSource.class).getConnection().getMetaData(); MeterRegistry registry = context.getBean(MeterRegistry.class); @@ -65,8 +65,7 @@ public class MetricsAutoConfigurationTests { .withConfiguration( AutoConfigurations.of(DataSourceAutoConfiguration.class)) .withPropertyValues("spring.datasource.generate-unique-name=true", - "management.metrics.jdbc.datasource-metric-name=custom.name", - "management.metrics.use-global-registry=false") + "management.metrics.jdbc.datasource-metric-name=custom.name") .run((context) -> { context.getBean(DataSource.class).getConnection().getMetaData(); MeterRegistry registry = context.getBean(MeterRegistry.class); @@ -81,8 +80,7 @@ public class MetricsAutoConfigurationTests { .withConfiguration( AutoConfigurations.of(DataSourceAutoConfiguration.class)) .withPropertyValues("spring.datasource.generate-unique-name=true", - "management.metrics.jdbc.instrument-datasource=false", - "management.metrics.use-global-registry=false") + "management.metrics.jdbc.instrument-datasource=false") .run((context) -> { context.getBean(DataSource.class).getConnection().getMetaData(); MeterRegistry registry = context.getBean(MeterRegistry.class); @@ -96,7 +94,6 @@ public class MetricsAutoConfigurationTests { this.contextRunner.withUserConfiguration(TwoDataSourcesConfiguration.class) .withConfiguration( AutoConfigurations.of(DataSourceAutoConfiguration.class)) - .withPropertyValues("metrics.use-global-registry=false") .run((context) -> { context.getBean("firstDataSource", DataSource.class).getConnection() .getMetaData(); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsConfigurationCompositeTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsConfigurationCompositeTests.java index 60c5d2ead8..353d6cd076 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsConfigurationCompositeTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsConfigurationCompositeTests.java @@ -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. @@ -37,7 +37,7 @@ public class MetricsConfigurationCompositeTests { public void compositeContainsImplementationsOnClasspath() { new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class)) - .withPropertyValues("metrics.use-global-registry=false") + .withPropertyValues("management.metrics.use-global-registry=false") .run((context) -> assertThat( context.getBean(CompositeMeterRegistry.class).getRegistries()) .hasAtLeastOneElementOfType(PrometheusMeterRegistry.class) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapterTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapterTests.java index 4b59738437..f822103425 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapterTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/datadog/DatadogPropertiesConfigAdapterTests.java @@ -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. @@ -27,12 +27,6 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class DatadogPropertiesConfigAdapterTests { - @Test(expected = IllegalStateException.class) - public void apiKeyIsRequired() { - DatadogProperties properties = new DatadogProperties(); - new DatadogPropertiesConfigAdapter(properties).apiKey(); - } - @Test public void uriCanBeSet() { DatadogProperties properties = new DatadogProperties(); 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 2b1b3b5154..b9f622bcff 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 @@ -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. diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfigurationTests.java index 9a76e86337..70cf20b930 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfigurationTests.java @@ -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. @@ -19,76 +19,75 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.client; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; -import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration; -import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; -import org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration; -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.data.rest.RepositoryRestMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration; -import org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration; -import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; +import org.springframework.boot.actuate.metrics.web.client.MetricsRestTemplateCustomizer; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestTemplate; import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; -@RunWith(SpringRunner.class) -@SpringBootTest(classes = RestTemplateMetricsConfigurationTests.ClientApp.class, webEnvironment = SpringBootTest.WebEnvironment.NONE) +/** + * Tests for {@link RestTemplateMetricsConfiguration}. + * + * @author Stephane Nicoll + */ public class RestTemplateMetricsConfigurationTests { - @Autowired - private RestTemplate client; - @Autowired - private MeterRegistry registry; + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("management.metrics.use-global-registry=false") + .withConfiguration(AutoConfigurations.of( + RestTemplateAutoConfiguration.class, MetricsAutoConfiguration.class)) + .withUserConfiguration(RegistryConfiguration.class); + @Test - public void restTemplatesCreatedWithBuilderAreInstrumented() { - try { - this.client.getForObject("http://google.com", String.class); - } - catch (Throwable ignored) { - // doesn't matter whether the request succeeded or not - } - assertThat(this.registry.find("http.client.requests").meter()).isPresent(); + public void restTemplateCreatedWithBuilderIsInstrumented() { + this.contextRunner.run((context) -> { + MeterRegistry registry = context.getBean(MeterRegistry.class); + RestTemplate restTemplate = context.getBean(RestTemplateBuilder.class) + .build(); + validateRestTemplate(restTemplate, registry); + }); } - @SpringBootApplication(exclude = { - FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class, - CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class, - Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, - MongoAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class, - HazelcastAutoConfiguration.class, MongoDataAutoConfiguration.class, - ElasticsearchAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class, - JestAutoConfiguration.class, SolrRepositoriesAutoConfiguration.class, - SolrAutoConfiguration.class, RedisAutoConfiguration.class, - RedisRepositoriesAutoConfiguration.class - }) - static class ClientApp { + @Test + public void restTemplateCanBeCustomizedManually() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(MetricsRestTemplateCustomizer.class); + RestTemplate restTemplate = new RestTemplateBuilder().customizers( + context.getBean(MetricsRestTemplateCustomizer.class)).build(); + MeterRegistry registry = context.getBean(MeterRegistry.class); + validateRestTemplate(restTemplate, registry); + }); + } + + private void validateRestTemplate(RestTemplate restTemplate, MeterRegistry registry) { + MockRestServiceServer server = MockRestServiceServer.createServer(restTemplate); + server.expect(requestTo("/test")).andRespond(withStatus(HttpStatus.OK)); + assertThat(registry.find("http.client.requests").meter()).isNotPresent(); + assertThat(restTemplate.getForEntity("/test", Void.class).getStatusCode()) + .isEqualTo(HttpStatus.OK); + assertThat(registry.find("http.client.requests").meter()).isPresent(); + } + + @Configuration + static class RegistryConfiguration { + @Bean public MeterRegistry registry() { return new SimpleMeterRegistry(); } - @Bean - public RestTemplate restTemplate(RestTemplateBuilder builder) { - return builder.build(); - } } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetrics.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetrics.java index 39a1163cdf..11d0ee7cad 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetrics.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetrics.java @@ -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. @@ -94,7 +94,8 @@ public class WebMvcMetrics { void preHandle(HttpServletRequest request, Object handler) { if (request.getAttribute(TIMING_REQUEST_ATTRIBUTE) == null) { - request.setAttribute(TIMING_REQUEST_ATTRIBUTE, this.registry.config().clock().monotonicTime()); + request.setAttribute(TIMING_REQUEST_ATTRIBUTE, + this.registry.config().clock().monotonicTime()); } request.setAttribute(HANDLER_REQUEST_ATTRIBUTE, handler); longTaskTimed(handler).forEach((config) -> { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java index 5faa3f36af..3e79318f16 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/MetricsEndpointWebIntegrationTests.java @@ -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. diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/MetricsRestTemplateCustomizerTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/MetricsRestTemplateCustomizerTests.java index c7f5aab8fa..ef392598de 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/MetricsRestTemplateCustomizerTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/client/MetricsRestTemplateCustomizerTests.java @@ -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. diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterAutoTimedTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterAutoTimedTests.java index e372c73d45..65248ca19c 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterAutoTimedTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterAutoTimedTests.java @@ -75,7 +75,6 @@ public class WebMvcMetricsFilterAutoTimedTests { @Test public void metricsCanBeAutoTimed() throws Exception { this.mvc.perform(get("/api/10")).andExpect(status().isOk()); - assertThat( this.registry.find("http.server.requests").tags("status", "200").timer()) .hasValueSatisfying((t) -> assertThat(t.count()).isEqualTo(1)); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterTests.java index 0613c915c0..9ec0d32285 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsFilterTests.java @@ -85,6 +85,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @RunWith(SpringRunner.class) @WebAppConfiguration public class WebMvcMetricsFilterTests { + @Autowired private SimpleMeterRegistry registry; @@ -167,7 +168,7 @@ public class WebMvcMetricsFilterTests { public void unhandledError() { assertThatCode(() -> this.mvc.perform(get("/api/c1/unhandledError/10")) .andExpect(status().isOk())) - .hasRootCauseInstanceOf(RuntimeException.class); + .hasRootCauseInstanceOf(RuntimeException.class); assertThat(this.registry.find("http.server.requests") .tags("exception", "RuntimeException").value(Statistic.Count, 1.0) .timer()).isPresent(); @@ -230,6 +231,7 @@ public class WebMvcMetricsFilterTests { @EnableWebMvc @Import({ Controller1.class, Controller2.class }) static class MetricsFilterApp { + @Primary @Bean MeterRegistry meterRegistry(Collection registries) { @@ -250,7 +252,9 @@ public class WebMvcMetricsFilterTests { @Override public MeterFilterReply accept(Meter.Id id) { for (Tag tag : id.getTags()) { - if (tag.getKey().equals("uri") && (tag.getValue().contains("histogram") || tag.getValue().contains("percentiles"))) { + if (tag.getKey().equals("uri") + && (tag.getValue().contains("histogram") + || tag.getValue().contains("percentiles"))) { return MeterFilterReply.ACCEPT; } } @@ -368,6 +372,7 @@ public class WebMvcMetricsFilterTests { public String successful(@PathVariable Long id) { return id.toString(); } + } static class RedirectAndNotFoundFilter extends OncePerRequestFilter { @@ -377,7 +382,7 @@ public class WebMvcMetricsFilterTests { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { + throws ServletException, IOException { String misbehave = request.getHeader(TEST_MISBEHAVE_HEADER); if (misbehave != null) { response.setStatus(Integer.parseInt(misbehave)); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsIntegrationTests.java index 47a7c5d0f4..712091ab85 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/servlet/WebMvcMetricsIntegrationTests.java @@ -83,8 +83,8 @@ public class WebMvcMetricsIntegrationTests { public void handledExceptionIsRecordedInMetricTag() throws Exception { this.mvc.perform(get("/api/handledError")).andExpect(status().is5xxServerError()); assertThat(this.registry.find("http.server.requests") - .tags("exception", "Exception1", "status", "500").value(Statistic.Count, 1.0).timer()) - .isPresent(); + .tags("exception", "Exception1", "status", "500") + .value(Statistic.Count, 1.0).timer()).isPresent(); } @Test @@ -92,8 +92,8 @@ public class WebMvcMetricsIntegrationTests { assertThatCode(() -> this.mvc.perform(get("/api/rethrownError")) .andExpect(status().is5xxServerError())); assertThat(this.registry.find("http.server.requests") - .tags("exception", "Exception2", "status", "500").value(Statistic.Count, 1.0).timer()) - .isPresent(); + .tags("exception", "Exception2", "status", "500") + .value(Statistic.Count, 1.0).timer()).isPresent(); } @Configuration 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 9b087f6712..df3bd14415 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 @@ -1290,8 +1290,10 @@ content into your application. Rather, pick only the properties that you need. management.metrics.export.atlas.step=1m # Step size (i.e. reporting frequency) to use. management.metrics.export.atlas.uri= # URI of the Atlas server. management.metrics.export.datadog.api-key= # Datadog API key. + management.metrics.export.datadog.application-key= # Datadog application key. management.metrics.export.datadog.batch-size= # Number of measurements per request to use for the backend. If more measurements are found, then multiple requests will be made. management.metrics.export.datadog.connect-timeout= # Connection timeout for requests to the backend. + management.metrics.export.datadog.descriptions= # Whether to publish descriptions metadata to Datadog. Turn this off to minimize the amount of metadata sent. management.metrics.export.datadog.enabled=true # Whether exporting of metrics to this backend is enabled. management.metrics.export.datadog.host-tag= # Tag that will be mapped to "host" when shipping metrics to Datadog. Can be omitted if host should be omitted on publishing. management.metrics.export.datadog.num-threads= # Number of threads to use with the metrics publishing scheduler. @@ -1328,6 +1330,7 @@ content into your application. Rather, pick only the properties that you need. 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. 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 76ecdab49a..dec92b799a 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 @@ -1010,9 +1010,9 @@ instance. [[production-ready-metrics-rest-template]] === RestTemplate Metrics -Auto-configuration customizes the auto-configured `RestTemplate` to enable the -instrumentation of its requests. `MetricsRestTemplateCustomizer` can be used to customize -your own `RestTemplate` instances. +The instrumentation of any `RestTemplate` created using the auto-configured +`RestTemplateBuilder` is enabled. It is also possible to apply +`MetricsRestTemplateCustomizer` manually. By default, metrics are generated with the name, `http.client.requests`. The name can be customized by setting the `management.metrics.web.client.requests-metric-name` property.