Harmonize HTTP client metrics

This commit harmonizes the auto-configurations for RestTemplate and
WebClient in a single `HttpClientMetricsAutoConfiguration`. Doing so
allows to give a better scope for the shared `MeterFilter`.

As a result`WebClientMetricsAutoConfiguration` has moved to the `client`
package.

Closes gh-14269
pull/14255/head
Stephane Nicoll 6 years ago
parent 2fc557a5a9
commit 7bee9dfc22

@ -23,62 +23,44 @@ import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfigu
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.metrics.web.client.DefaultRestTemplateExchangeTagsProvider;
import org.springframework.boot.actuate.metrics.web.client.MetricsRestTemplateCustomizer;
import org.springframework.boot.actuate.metrics.web.client.RestTemplateExchangeTagsProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
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.web.client.RestTemplateAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.Order;
import org.springframework.web.client.RestTemplate;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link RestTemplate}-related
* metrics.
* {@link EnableAutoConfiguration Auto-configuration} for HTTP client-related metrics.
*
* @author Jon Schneider
* @author Phillip Webb
* @since 2.0.0
* @author Stephane Nicoll
* @since 2.1.0
*/
@Configuration
@AutoConfigureAfter({ MetricsAutoConfiguration.class, RestTemplateAutoConfiguration.class,
@AutoConfigureAfter({ MetricsAutoConfiguration.class,
SimpleMetricsExportAutoConfiguration.class })
@ConditionalOnClass(RestTemplate.class)
@ConditionalOnClass(MeterRegistry.class)
@ConditionalOnBean(MeterRegistry.class)
public class RestTemplateMetricsAutoConfiguration {
@Import({ RestTemplateMetricsConfiguration.class, WebClientMetricsConfiguration.class })
public class HttpClientMetricsAutoConfiguration {
private final MetricsProperties properties;
public RestTemplateMetricsAutoConfiguration(MetricsProperties properties) {
public HttpClientMetricsAutoConfiguration(MetricsProperties properties) {
this.properties = properties;
}
@Bean
@ConditionalOnMissingBean(RestTemplateExchangeTagsProvider.class)
public DefaultRestTemplateExchangeTagsProvider restTemplateTagConfigurer() {
return new DefaultRestTemplateExchangeTagsProvider();
}
@Bean
public MetricsRestTemplateCustomizer metricsRestTemplateCustomizer(
MeterRegistry meterRegistry,
RestTemplateExchangeTagsProvider restTemplateTagConfigurer) {
return new MetricsRestTemplateCustomizer(meterRegistry, restTemplateTagConfigurer,
this.properties.getWeb().getClient().getRequestsMetricName());
}
@Bean
@Order(0)
public MeterFilter metricsHttpClientUriTagFilter() {
String metricName = this.properties.getWeb().getClient().getRequestsMetricName();
MeterFilter denyFilter = new OnlyOnceLoggingDenyMeterFilter(() -> String
.format("Reached the maximum number of URI tags for '%s'. Are you using "
+ "'uriVariables' on RestTemplate calls?", metricName));
+ "'uriVariables'?", metricName));
return MeterFilter.maximumAllowableTags(metricName, "uri",
this.properties.getWeb().getClient().getMaxUriTags(), denyFilter);
}

@ -0,0 +1,61 @@
/*
* 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.web.client;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.metrics.web.client.DefaultRestTemplateExchangeTagsProvider;
import org.springframework.boot.actuate.metrics.web.client.MetricsRestTemplateCustomizer;
import org.springframework.boot.actuate.metrics.web.client.RestTemplateExchangeTagsProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* Configure the instrumentation of {@link RestTemplate}.
*
* @author Jon Schneider
* @author Phillip Webb
*/
@Configuration
@ConditionalOnClass(RestTemplate.class)
class RestTemplateMetricsConfiguration {
private final MetricsProperties properties;
RestTemplateMetricsConfiguration(MetricsProperties properties) {
this.properties = properties;
}
@Bean
@ConditionalOnMissingBean(RestTemplateExchangeTagsProvider.class)
public DefaultRestTemplateExchangeTagsProvider restTemplateTagConfigurer() {
return new DefaultRestTemplateExchangeTagsProvider();
}
@Bean
public MetricsRestTemplateCustomizer metricsRestTemplateCustomizer(
MeterRegistry meterRegistry,
RestTemplateExchangeTagsProvider restTemplateTagConfigurer) {
return new MetricsRestTemplateCustomizer(meterRegistry, restTemplateTagConfigurer,
this.properties.getWeb().getClient().getRequestsMetricName());
}
}

@ -14,46 +14,29 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.metrics.web.reactive;
package org.springframework.boot.actuate.autoconfigure.metrics.web.client;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.client.RestTemplateMetricsAutoConfiguration;
import org.springframework.boot.actuate.metrics.web.reactive.client.DefaultWebClientExchangeTagsProvider;
import org.springframework.boot.actuate.metrics.web.reactive.client.MetricsWebClientCustomizer;
import org.springframework.boot.actuate.metrics.web.reactive.client.WebClientExchangeTagsProvider;
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.web.reactive.function.client.WebClientAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
/**
* {@link EnableAutoConfiguration Auto-configuration} for instrumentation of
* {@link org.springframework.web.reactive.function.client.WebClient}.
* <p>
* This is reusing the {@link io.micrometer.core.instrument.config.MeterFilter} defined in
* {@link RestTemplateMetricsAutoConfiguration} for limiting the cardinality of "uri"
* tags.
* Configure the instrumentation of {@link WebClient}.
*
* @author Brian Clozel
* @since 2.1.0
* @author Stephane Nicoll
*/
@Configuration
@ConditionalOnClass(WebClient.class)
@AutoConfigureAfter({ MetricsAutoConfiguration.class,
SimpleMetricsExportAutoConfiguration.class })
@AutoConfigureBefore(WebClientAutoConfiguration.class)
@ConditionalOnBean(MeterRegistry.class)
public class WebClientMetricsAutoConfiguration {
class WebClientMetricsConfiguration {
@Bean
@ConditionalOnMissingBean

@ -52,8 +52,7 @@ org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetri
org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront.WavefrontMetricsExportAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa.HibernateMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.client.RestTemplateMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.reactive.WebClientMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.client.HttpClientMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.reactive.WebFluxMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat.TomcatMetricsAutoConfiguration,\

@ -39,7 +39,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.amqp.RabbitMetrics
import org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa.HibernateMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.client.RestTemplateMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.client.HttpClientMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.reactive.WebFluxMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsAutoConfiguration;
import org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter;
@ -143,7 +143,7 @@ public class MetricsIntegrationTests {
RabbitMetricsAutoConfiguration.class, CacheMetricsAutoConfiguration.class,
DataSourcePoolMetricsAutoConfiguration.class,
HibernateMetricsAutoConfiguration.class,
RestTemplateMetricsAutoConfiguration.class,
HttpClientMetricsAutoConfiguration.class,
WebFluxMetricsAutoConfiguration.class, WebMvcMetricsAutoConfiguration.class,
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
RestTemplateAutoConfiguration.class, WebMvcAutoConfiguration.class,

@ -38,8 +38,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.Simp
import org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.orm.jpa.HibernateMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.client.RestTemplateMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.reactive.WebClientMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.client.HttpClientMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.reactive.WebFluxMetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurations;
@ -78,8 +77,7 @@ public final class MetricsRun {
RabbitMetricsAutoConfiguration.class, CacheMetricsAutoConfiguration.class,
DataSourcePoolMetricsAutoConfiguration.class,
HibernateMetricsAutoConfiguration.class,
RestTemplateMetricsAutoConfiguration.class,
WebClientMetricsAutoConfiguration.class,
HttpClientMetricsAutoConfiguration.class,
WebFluxMetricsAutoConfiguration.class, WebMvcMetricsAutoConfiguration.class);
private MetricsRun() {

@ -37,12 +37,12 @@ import static org.springframework.test.web.client.match.MockRestRequestMatchers.
import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
/**
* Tests for {@link RestTemplateMetricsAutoConfiguration}.
* Tests for {@link RestTemplateMetricsConfiguration}.
*
* @author Stephane Nicoll
* @author Jon Schneider
*/
public class RestTemplateMetricsAutoConfigurationTests {
public class RestTemplateMetricsConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.with(MetricsRun.simple()).withConfiguration(
@ -82,8 +82,8 @@ public class RestTemplateMetricsAutoConfigurationTests {
assertThat(registry.get("http.client.requests").meters()).hasSize(2);
assertThat(this.out.toString()).contains(
"Reached the maximum number of URI tags for 'http.client.requests'.");
assertThat(this.out.toString()).contains(
"Are you using 'uriVariables' on RestTemplate calls?");
assertThat(this.out.toString())
.contains("Are you using 'uriVariables'?");
});
}

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.metrics.web.reactive;
package org.springframework.boot.actuate.autoconfigure.metrics.web.client;
import io.micrometer.core.instrument.MeterRegistry;
import org.junit.Before;
@ -42,11 +42,11 @@ import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link WebClientMetricsAutoConfiguration}
* Tests for {@link WebClientMetricsConfiguration}
*
* @author Brian Clozel
*/
public class WebClientMetricsAutoConfigurationTests {
public class WebClientMetricsConfigurationTests {
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.with(MetricsRun.simple())
@ -103,9 +103,10 @@ public class WebClientMetricsAutoConfigurationTests {
}
assertThat(registry.get("http.client.requests").meters())
.hasSize(maxUriTags);
assertThat(this.out.toString()).contains(
"Reached the maximum number of URI tags for 'http.client.requests'.");
assertThat(this.out.toString())
.contains("Reached the maximum number of URI tags "
+ "for 'http.client.requests'");
.contains("Are you using 'uriVariables'?");
});
}
Loading…
Cancel
Save