Commit 8045bf1f authored by Stephane Nicoll's avatar Stephane Nicoll

Polish "Allow configuration of auto-timed metrics"

Closes gh-15988
parent 4df6f5de
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
package org.springframework.boot.actuate.autoconfigure.metrics; package org.springframework.boot.actuate.autoconfigure.metrics;
import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
/** /**
* {@link ConfigurationProperties @ConfigurationProperties} for configuring * {@link ConfigurationProperties @ConfigurationProperties} for configuring
...@@ -107,8 +107,12 @@ public class MetricsProperties { ...@@ -107,8 +107,12 @@ public class MetricsProperties {
*/ */
private int maxUriTags = 100; private int maxUriTags = 100;
public ClientRequest getRequest() {
return this.request;
}
/** /**
* Get name of the metric for received requests. * Return the name of the metric for client requests.
* @return request metric name * @return request metric name
* @deprecated since 2.2.0 in favor of {@link ClientRequest#getMetricName()} * @deprecated since 2.2.0 in favor of {@link ClientRequest#getMetricName()}
*/ */
...@@ -119,7 +123,7 @@ public class MetricsProperties { ...@@ -119,7 +123,7 @@ public class MetricsProperties {
} }
/** /**
* Set name of the metric for received requests. * Set the name of the metric for client requests.
* @param requestsMetricName request metric name * @param requestsMetricName request metric name
* @deprecated since 2.2.0 in favor of * @deprecated since 2.2.0 in favor of
* {@link ClientRequest#setMetricName(String)} * {@link ClientRequest#setMetricName(String)}
...@@ -128,10 +132,6 @@ public class MetricsProperties { ...@@ -128,10 +132,6 @@ public class MetricsProperties {
this.request.setMetricName(requestsMetricName); this.request.setMetricName(requestsMetricName);
} }
public ClientRequest getRequest() {
return this.request;
}
public int getMaxUriTags() { public int getMaxUriTags() {
return this.maxUriTags; return this.maxUriTags;
} }
...@@ -148,11 +148,12 @@ public class MetricsProperties { ...@@ -148,11 +148,12 @@ public class MetricsProperties {
private String metricName = "http.client.requests"; private String metricName = "http.client.requests";
/** /**
* Automatically time requests. * Auto-timed request settings.
*/ */
private final AutoTime autoTime = new AutoTime(); @NestedConfigurationProperty
private final Autotime autoTime = new Autotime();
public AutoTime getAutoTime() { public Autotime getAutotime() {
return this.autoTime; return this.autoTime;
} }
...@@ -179,8 +180,12 @@ public class MetricsProperties { ...@@ -179,8 +180,12 @@ public class MetricsProperties {
*/ */
private int maxUriTags = 100; private int maxUriTags = 100;
public ServerRequest getRequest() {
return this.request;
}
/** /**
* Get name of the metric for received requests. * Return name of the metric for server requests.
* @return request metric name * @return request metric name
* @deprecated since 2.2.0 in favor of {@link ServerRequest#getMetricName()} * @deprecated since 2.2.0 in favor of {@link ServerRequest#getMetricName()}
*/ */
...@@ -191,7 +196,7 @@ public class MetricsProperties { ...@@ -191,7 +196,7 @@ public class MetricsProperties {
} }
/** /**
* Set name of the metric for received requests. * Set the name of the metric for server requests.
* @param requestsMetricName request metric name * @param requestsMetricName request metric name
* @deprecated since 2.2.0 in favor of * @deprecated since 2.2.0 in favor of
* {@link ServerRequest#setMetricName(String)} * {@link ServerRequest#setMetricName(String)}
...@@ -200,10 +205,6 @@ public class MetricsProperties { ...@@ -200,10 +205,6 @@ public class MetricsProperties {
this.request.setMetricName(requestsMetricName); this.request.setMetricName(requestsMetricName);
} }
public ServerRequest getRequest() {
return this.request;
}
public int getMaxUriTags() { public int getMaxUriTags() {
return this.maxUriTags; return this.maxUriTags;
} }
...@@ -220,12 +221,13 @@ public class MetricsProperties { ...@@ -220,12 +221,13 @@ public class MetricsProperties {
private String metricName = "http.server.requests"; private String metricName = "http.server.requests";
/** /**
* Automatically time requests. * Auto-timed request settings.
*/ */
private final AutoTime autoTime = new AutoTime(); @NestedConfigurationProperty
private final Autotime autotime = new Autotime();
public AutoTime getAutoTime() { public Autotime getAutotime() {
return this.autoTime; return this.autotime;
} }
public String getMetricName() { public String getMetricName() {
...@@ -240,56 +242,6 @@ public class MetricsProperties { ...@@ -240,56 +242,6 @@ public class MetricsProperties {
} }
public static class AutoTime {
/**
* Whether requests handled by Spring MVC, WebFlux or Jersey should be
* automatically timed. If the number of time series emitted grows too large
* on account of request mapping timings, disable this and use 'Timed' on a
* per request mapping basis as needed.
*/
private boolean enabled = true;
/**
* Default percentiles when @Timed annotation is not presented on the
* corresponding request handler. Any @Timed annotation presented will have
* precedence.
*/
private List<Double> defaultPercentiles = new ArrayList<>();
/**
* Default histogram when @Timed annotation is not presented on the
* corresponding request handler. Any @Timed annotation presented will have
* precedence.
*/
private boolean defaultHistogram;
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public List<Double> getDefaultPercentiles() {
return this.defaultPercentiles;
}
public void setDefaultPercentiles(List<Double> defaultPercentiles) {
this.defaultPercentiles = defaultPercentiles;
}
public boolean isDefaultHistogram() {
return this.defaultHistogram;
}
public void setDefaultHistogram(boolean defaultHistogram) {
this.defaultHistogram = defaultHistogram;
}
}
} }
public static class Distribution { public static class Distribution {
......
...@@ -80,7 +80,7 @@ public class JerseyServerMetricsAutoConfiguration { ...@@ -80,7 +80,7 @@ public class JerseyServerMetricsAutoConfiguration {
Server server = this.properties.getWeb().getServer(); Server server = this.properties.getWeb().getServer();
return (config) -> config.register(new MetricsApplicationEventListener( return (config) -> config.register(new MetricsApplicationEventListener(
meterRegistry, tagsProvider, server.getRequest().getMetricName(), meterRegistry, tagsProvider, server.getRequest().getMetricName(),
server.getRequest().getAutoTime().isEnabled(), server.getRequest().getAutotime().isEnabled(),
new AnnotationUtilsAnnotationFinder())); new AnnotationUtilsAnnotationFinder()));
} }
......
...@@ -19,8 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.client; ...@@ -19,8 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.client;
import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.AutoTime; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Client.ClientRequest;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Client;
import org.springframework.boot.actuate.metrics.web.client.DefaultRestTemplateExchangeTagsProvider; 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.MetricsRestTemplateCustomizer;
import org.springframework.boot.actuate.metrics.web.client.RestTemplateExchangeTagsProvider; import org.springframework.boot.actuate.metrics.web.client.RestTemplateExchangeTagsProvider;
...@@ -55,13 +54,10 @@ class RestTemplateMetricsConfiguration { ...@@ -55,13 +54,10 @@ class RestTemplateMetricsConfiguration {
MeterRegistry meterRegistry, MeterRegistry meterRegistry,
RestTemplateExchangeTagsProvider restTemplateExchangeTagsProvider, RestTemplateExchangeTagsProvider restTemplateExchangeTagsProvider,
MetricsProperties properties) { MetricsProperties properties) {
ClientRequest request = properties.getWeb().getClient().getRequest();
Client client = properties.getWeb().getClient();
AutoTime autoTime = client.getRequest().getAutoTime();
return new MetricsRestTemplateCustomizer(meterRegistry, return new MetricsRestTemplateCustomizer(meterRegistry,
restTemplateExchangeTagsProvider, client.getRequest().getMetricName(), restTemplateExchangeTagsProvider, request.getMetricName(),
autoTime.isEnabled(), autoTime.getDefaultPercentiles(), request.getAutotime());
autoTime.isDefaultHistogram());
} }
} }
...@@ -19,6 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.client; ...@@ -19,6 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.client;
import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Client.ClientRequest;
import org.springframework.boot.actuate.metrics.web.reactive.client.DefaultWebClientExchangeTagsProvider; 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.MetricsWebClientCustomizer;
import org.springframework.boot.actuate.metrics.web.reactive.client.WebClientExchangeTagsProvider; import org.springframework.boot.actuate.metrics.web.reactive.client.WebClientExchangeTagsProvider;
...@@ -48,8 +49,9 @@ class WebClientMetricsConfiguration { ...@@ -48,8 +49,9 @@ class WebClientMetricsConfiguration {
public MetricsWebClientCustomizer metricsWebClientCustomizer( public MetricsWebClientCustomizer metricsWebClientCustomizer(
MeterRegistry meterRegistry, WebClientExchangeTagsProvider tagsProvider, MeterRegistry meterRegistry, WebClientExchangeTagsProvider tagsProvider,
MetricsProperties properties) { MetricsProperties properties) {
ClientRequest request = properties.getWeb().getClient().getRequest();
return new MetricsWebClientCustomizer(meterRegistry, tagsProvider, return new MetricsWebClientCustomizer(meterRegistry, tagsProvider,
properties.getWeb().getClient().getRequest().getMetricName()); request.getMetricName(), request.getAutotime());
} }
} }
...@@ -21,8 +21,7 @@ import io.micrometer.core.instrument.config.MeterFilter; ...@@ -21,8 +21,7 @@ import io.micrometer.core.instrument.config.MeterFilter;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.AutoTime; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Server.ServerRequest;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Server;
import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter; import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.metrics.web.reactive.server.DefaultWebFluxTagsProvider; import org.springframework.boot.actuate.metrics.web.reactive.server.DefaultWebFluxTagsProvider;
...@@ -67,11 +66,9 @@ public class WebFluxMetricsAutoConfiguration { ...@@ -67,11 +66,9 @@ public class WebFluxMetricsAutoConfiguration {
@Bean @Bean
public MetricsWebFilter webfluxMetrics(MeterRegistry registry, public MetricsWebFilter webfluxMetrics(MeterRegistry registry,
WebFluxTagsProvider tagConfigurer) { WebFluxTagsProvider tagConfigurer) {
Server serverProperties = this.properties.getWeb().getServer(); ServerRequest request = this.properties.getWeb().getServer().getRequest();
AutoTime autotime = serverProperties.getRequest().getAutoTime(); return new MetricsWebFilter(registry, tagConfigurer, request.getMetricName(),
return new MetricsWebFilter(registry, tagConfigurer, request.getAutotime());
serverProperties.getRequest().getMetricName(), autotime.isEnabled(),
autotime.getDefaultPercentiles(), autotime.isDefaultHistogram());
} }
@Bean @Bean
......
...@@ -23,8 +23,7 @@ import io.micrometer.core.instrument.config.MeterFilter; ...@@ -23,8 +23,7 @@ import io.micrometer.core.instrument.config.MeterFilter;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.AutoTime; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Server.ServerRequest;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Server;
import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter; import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.metrics.web.servlet.DefaultWebMvcTagsProvider; import org.springframework.boot.actuate.metrics.web.servlet.DefaultWebMvcTagsProvider;
...@@ -79,11 +78,9 @@ public class WebMvcMetricsAutoConfiguration { ...@@ -79,11 +78,9 @@ public class WebMvcMetricsAutoConfiguration {
@Bean @Bean
public FilterRegistrationBean<WebMvcMetricsFilter> webMvcMetricsFilter( public FilterRegistrationBean<WebMvcMetricsFilter> webMvcMetricsFilter(
MeterRegistry registry, WebMvcTagsProvider tagsProvider) { MeterRegistry registry, WebMvcTagsProvider tagsProvider) {
Server serverProperties = this.properties.getWeb().getServer(); ServerRequest request = this.properties.getWeb().getServer().getRequest();
AutoTime autotime = serverProperties.getRequest().getAutoTime();
WebMvcMetricsFilter filter = new WebMvcMetricsFilter(registry, tagsProvider, WebMvcMetricsFilter filter = new WebMvcMetricsFilter(registry, tagsProvider,
serverProperties.getRequest().getMetricName(), autotime.isEnabled(), request.getMetricName(), request.getAutotime());
autotime.getDefaultPercentiles(), autotime.isDefaultHistogram());
FilterRegistrationBean<WebMvcMetricsFilter> registration = new FilterRegistrationBean<>( FilterRegistrationBean<WebMvcMetricsFilter> registration = new FilterRegistrationBean<>(
filter); filter);
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1); registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
......
...@@ -253,6 +253,34 @@ ...@@ -253,6 +253,34 @@
"level": "error" "level": "error"
} }
}, },
{
"name": "management.metrics.web.client.request.autotime.enabled",
"description": "Whether to automatically time web client requests.",
"defaultValue": true
},
{
"name": "management.metrics.web.client.request.autotime.percentiles",
"description": "Computed non-aggregable percentiles to publish."
},
{
"name": "management.metrics.web.client.request.autotime.percentiles-histogram",
"description": "Whether percentile histograms should be published.",
"defaultValue": false
},
{
"name": "management.metrics.web.server.request.autotime.enabled",
"description": "Whether to automatically time web server requests.",
"defaultValue": true
},
{
"name": "management.metrics.web.server.request.autotime.percentiles",
"description": "Computed non-aggregable percentiles to publish."
},
{
"name": "management.metrics.web.server.request.autotime.percentiles-histogram",
"description": "Whether percentile histograms should be published.",
"defaultValue": false
},
{ {
"name": "management.server.ssl.ciphers", "name": "management.server.ssl.ciphers",
"description": "Supported SSL ciphers." "description": "Supported SSL ciphers."
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
package org.springframework.boot.actuate.autoconfigure.metrics.web.client; package org.springframework.boot.actuate.autoconfigure.metrics.web.client;
import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
...@@ -100,6 +102,24 @@ public class RestTemplateMetricsConfigurationTests { ...@@ -100,6 +102,24 @@ public class RestTemplateMetricsConfigurationTests {
}); });
} }
@Test
public void autoTimeRequestsCanBeConfigured() {
this.contextRunner.withPropertyValues(
"management.metrics.web.client.request.autotime.enabled=true",
"management.metrics.web.client.request.autotime.percentiles=0.5,0.7",
"management.metrics.web.client.request.autotime.percentiles-histogram=true")
.run((context) -> {
MeterRegistry registry = getInitializedMeterRegistry(context);
Timer timer = registry.get("http.client.requests").timer();
HistogramSnapshot snapshot = timer.takeSnapshot();
assertThat(snapshot.percentileValues()).hasSize(2);
assertThat(snapshot.percentileValues()[0].percentile())
.isEqualTo(0.5);
assertThat(snapshot.percentileValues()[1].percentile())
.isEqualTo(0.7);
});
}
@Test @Test
public void backsOffWhenRestTemplateBuilderIsMissing() { public void backsOffWhenRestTemplateBuilderIsMissing() {
new ApplicationContextRunner().with(MetricsRun.simple()) new ApplicationContextRunner().with(MetricsRun.simple())
......
...@@ -19,6 +19,8 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.client; ...@@ -19,6 +19,8 @@ package org.springframework.boot.actuate.autoconfigure.metrics.web.client;
import java.time.Duration; import java.time.Duration;
import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
...@@ -101,6 +103,24 @@ public class WebClientMetricsConfigurationTests { ...@@ -101,6 +103,24 @@ public class WebClientMetricsConfigurationTests {
}); });
} }
@Test
public void autoTimeRequestsCanBeConfigured() {
this.contextRunner.withPropertyValues(
"management.metrics.web.client.request.autotime.enabled=true",
"management.metrics.web.client.request.autotime.percentiles=0.5,0.7",
"management.metrics.web.client.request.autotime.percentiles-histogram=true")
.run((context) -> {
MeterRegistry registry = getInitializedMeterRegistry(context);
Timer timer = registry.get("http.client.requests").timer();
HistogramSnapshot snapshot = timer.takeSnapshot();
assertThat(snapshot.percentileValues()).hasSize(2);
assertThat(snapshot.percentileValues()[0].percentile())
.isEqualTo(0.5);
assertThat(snapshot.percentileValues()[1].percentile())
.isEqualTo(0.7);
});
}
private MeterRegistry getInitializedMeterRegistry( private MeterRegistry getInitializedMeterRegistry(
AssertableApplicationContext context) { AssertableApplicationContext context) {
WebClient webClient = mockWebClient(context.getBean(WebClient.Builder.class)); WebClient webClient = mockWebClient(context.getBean(WebClient.Builder.class));
......
...@@ -102,7 +102,7 @@ public class WebFluxMetricsAutoConfigurationTests { ...@@ -102,7 +102,7 @@ public class WebFluxMetricsAutoConfigurationTests {
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class)) .withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class))
.withUserConfiguration(TestController.class) .withUserConfiguration(TestController.class)
.withPropertyValues( .withPropertyValues(
"management.metrics.web.server.request.auto-time.enabled=false") "management.metrics.web.server.request.autotime.enabled=false")
.run((context) -> { .run((context) -> {
MeterRegistry registry = getInitializedMeterRegistry(context); MeterRegistry registry = getInitializedMeterRegistry(context);
assertThat(registry.find("http.server.requests").meter()).isNull(); assertThat(registry.find("http.server.requests").meter()).isNull();
......
...@@ -141,14 +141,14 @@ public class WebMvcMetricsAutoConfigurationTests { ...@@ -141,14 +141,14 @@ public class WebMvcMetricsAutoConfigurationTests {
} }
@Test @Test
public void autoTimeRequestsDefaultValues() { public void autoTimeRequestsCanBeConfigured() {
this.contextRunner.withUserConfiguration(TestController.class) this.contextRunner.withUserConfiguration(TestController.class)
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class, .withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class,
WebMvcAutoConfiguration.class)) WebMvcAutoConfiguration.class))
.withPropertyValues( .withPropertyValues(
"management.metrics.web.server.request.auto-time.enabled=true", "management.metrics.web.server.request.autotime.enabled=true",
"management.metrics.web.server.request.auto-time.default-percentiles=0.5,0.7", "management.metrics.web.server.request.autotime.percentiles=0.5,0.7",
"management.metrics.web.server.request.auto-time.default-histogram=true") "management.metrics.web.server.request.autotime.percentiles-histogram=true")
.run((context) -> { .run((context) -> {
MeterRegistry registry = getInitializedMeterRegistry(context); MeterRegistry registry = getInitializedMeterRegistry(context);
Timer timer = registry.get("http.server.requests").timer(); Timer timer = registry.get("http.server.requests").timer();
......
/*
* Copyright 2012-2019 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
*
* https://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.metrics;
import java.util.List;
/**
* Settings for requests that are automatically timed.
*
* @author Tadaya Tsuyukubo
* @author Stephane Nicoll
* @since 2.2.0
*/
public final class Autotime {
private boolean enabled = true;
private boolean percentilesHistogram;
private double[] percentiles;
/**
* Create an instance that automatically time requests with no percentiles.
*/
public Autotime() {
}
/**
* Create an instance with the specified settings.
* @param enabled whether requests should be automatically timed
* @param percentilesHistogram whether percentile histograms should be published
* @param percentiles computed non-aggregable percentiles to publish (can be
* {@code null})
*/
public Autotime(boolean enabled, boolean percentilesHistogram,
List<Double> percentiles) {
this.enabled = enabled;
this.percentilesHistogram = percentilesHistogram;
this.percentiles = (percentiles != null)
? percentiles.stream().mapToDouble(Double::doubleValue).toArray() : null;
}
/**
* Create an instance that disable auto-timed requests.
* @return an instance that disable auto-timed requests
*/
public static Autotime disabled() {
return new Autotime(false, false, null);
}
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isPercentilesHistogram() {
return this.percentilesHistogram;
}
public void setPercentilesHistogram(boolean percentilesHistogram) {
this.percentilesHistogram = percentilesHistogram;
}
public double[] getPercentiles() {
return this.percentiles;
}
public void setPercentiles(double[] percentiles) {
this.percentiles = percentiles;
}
}
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -18,13 +18,13 @@ package org.springframework.boot.actuate.metrics.web.client; ...@@ -18,13 +18,13 @@ package org.springframework.boot.actuate.metrics.web.client;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer; import io.micrometer.core.instrument.Timer;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.core.NamedThreadLocal; import org.springframework.core.NamedThreadLocal;
import org.springframework.http.HttpRequest; import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestExecution;
...@@ -51,11 +51,7 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto ...@@ -51,11 +51,7 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto
private final String metricName; private final String metricName;
private final boolean autoTimeRequests; private final Autotime autotime;
private final double[] percentiles;
private final boolean histogram;
/** /**
* Create a new {@code MetricsClientHttpRequestInterceptor}. * Create a new {@code MetricsClientHttpRequestInterceptor}.
...@@ -63,11 +59,11 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto ...@@ -63,11 +59,11 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto
* @param tagProvider provider for metrics tags * @param tagProvider provider for metrics tags
* @param metricName name of the metric to record * @param metricName name of the metric to record
* @deprecated since 2.2.0 in favor of * @deprecated since 2.2.0 in favor of
* {@link #MetricsClientHttpRequestInterceptor(MeterRegistry, RestTemplateExchangeTagsProvider, String, boolean, List, boolean)} * {@link #MetricsClientHttpRequestInterceptor(MeterRegistry, RestTemplateExchangeTagsProvider, String, Autotime)}
*/ */
MetricsClientHttpRequestInterceptor(MeterRegistry meterRegistry, MetricsClientHttpRequestInterceptor(MeterRegistry meterRegistry,
RestTemplateExchangeTagsProvider tagProvider, String metricName) { RestTemplateExchangeTagsProvider tagProvider, String metricName) {
this(meterRegistry, tagProvider, metricName, true, null, false); this(meterRegistry, tagProvider, metricName, new Autotime());
} }
/** /**
...@@ -75,25 +71,16 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto ...@@ -75,25 +71,16 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto
* @param meterRegistry the registry to which metrics are recorded * @param meterRegistry the registry to which metrics are recorded
* @param tagProvider provider for metrics tags * @param tagProvider provider for metrics tags
* @param metricName name of the metric to record * @param metricName name of the metric to record
* @param autoTimeRequests if requests should be automatically timed * @param autotime auto timed request settings
* @param percentileList percentiles for auto time requests
* @param histogram histogram or not for auto time requests
* @since 2.2.0 * @since 2.2.0
*/ */
MetricsClientHttpRequestInterceptor(MeterRegistry meterRegistry, MetricsClientHttpRequestInterceptor(MeterRegistry meterRegistry,
RestTemplateExchangeTagsProvider tagProvider, String metricName, RestTemplateExchangeTagsProvider tagProvider, String metricName,
boolean autoTimeRequests, List<Double> percentileList, boolean histogram) { Autotime autotime) {
double[] percentiles = (percentileList != null)
? percentileList.stream().mapToDouble(Double::doubleValue).toArray()
: null;
this.tagProvider = tagProvider; this.tagProvider = tagProvider;
this.meterRegistry = meterRegistry; this.meterRegistry = meterRegistry;
this.metricName = metricName; this.metricName = metricName;
this.autoTimeRequests = autoTimeRequests; this.autotime = (autotime != null) ? autotime : Autotime.disabled();
this.percentiles = percentiles;
this.histogram = histogram;
} }
@Override @Override
...@@ -106,7 +93,7 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto ...@@ -106,7 +93,7 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto
return response; return response;
} }
finally { finally {
if (this.autoTimeRequests) { if (this.autotime.isEnabled()) {
getTimeBuilder(request, response).register(this.meterRegistry) getTimeBuilder(request, response).register(this.meterRegistry)
.record(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); .record(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
} }
...@@ -134,8 +121,9 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto ...@@ -134,8 +121,9 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto
private Timer.Builder getTimeBuilder(HttpRequest request, private Timer.Builder getTimeBuilder(HttpRequest request,
ClientHttpResponse response) { ClientHttpResponse response) {
return Timer.builder(this.metricName).publishPercentiles(this.percentiles) return Timer.builder(this.metricName)
.publishPercentileHistogram(this.histogram) .publishPercentiles(this.autotime.getPercentiles())
.publishPercentileHistogram(this.autotime.isPercentilesHistogram())
.tags(this.tagProvider.getTags(urlTemplate.get(), request, response)) .tags(this.tagProvider.getTags(urlTemplate.get(), request, response))
.description("Timer of RestTemplate operation"); .description("Timer of RestTemplate operation");
} }
......
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -21,6 +21,7 @@ import java.util.List; ...@@ -21,6 +21,7 @@ import java.util.List;
import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.boot.web.client.RestTemplateCustomizer; import org.springframework.boot.web.client.RestTemplateCustomizer;
import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
...@@ -46,32 +47,29 @@ public class MetricsRestTemplateCustomizer implements RestTemplateCustomizer { ...@@ -46,32 +47,29 @@ public class MetricsRestTemplateCustomizer implements RestTemplateCustomizer {
* @param tagProvider the tag provider * @param tagProvider the tag provider
* @param metricName the name of the recorded metric * @param metricName the name of the recorded metric
* @deprecated since 2.2.0 in favor of * @deprecated since 2.2.0 in favor of
* {@link #MetricsRestTemplateCustomizer(MeterRegistry, RestTemplateExchangeTagsProvider, String, boolean, List, boolean)} * {@link #MetricsRestTemplateCustomizer(MeterRegistry, RestTemplateExchangeTagsProvider, String, Autotime)}
*/ */
public MetricsRestTemplateCustomizer(MeterRegistry meterRegistry, public MetricsRestTemplateCustomizer(MeterRegistry meterRegistry,
RestTemplateExchangeTagsProvider tagProvider, String metricName) { RestTemplateExchangeTagsProvider tagProvider, String metricName) {
this.interceptor = new MetricsClientHttpRequestInterceptor(meterRegistry, this(meterRegistry, tagProvider, metricName, new Autotime());
tagProvider, metricName);
} }
/** /**
* Creates a new {@code MetricsRestTemplateInterceptor}. When {@code autoTimeRequests} * Creates a new {@code MetricsRestTemplateInterceptor}. When {@code autoTimeRequests}
* is set to {@code true}, the interceptor records metrics using the given * is set to {@code true}, the interceptor records metrics using the given
* {@code meterRegistry} with tags provided by the given {@code tagProvider} and with * {@code meterRegistry} with tags provided by the given {@code tagProvider} and with
* {@code percentileList} and {@code histogram} configurations. * {@link Autotime auto-timed request configuration}.
* @param meterRegistry the meter registry * @param meterRegistry the meter registry
* @param tagProvider the tag provider * @param tagProvider the tag provider
* @param metricName the name of the recorded metric * @param metricName the name of the recorded metric
* @param autoTimeRequests if requests should be automatically timed * @param autotime auto-timed request settings
* @param percentileList percentiles for auto time requests
* @param histogram histogram or not for auto time requests
* @since 2.2.0 * @since 2.2.0
*/ */
public MetricsRestTemplateCustomizer(MeterRegistry meterRegistry, public MetricsRestTemplateCustomizer(MeterRegistry meterRegistry,
RestTemplateExchangeTagsProvider tagProvider, String metricName, RestTemplateExchangeTagsProvider tagProvider, String metricName,
boolean autoTimeRequests, List<Double> percentileList, boolean histogram) { Autotime autotime) {
this.interceptor = new MetricsClientHttpRequestInterceptor(meterRegistry, this.interceptor = new MetricsClientHttpRequestInterceptor(meterRegistry,
tagProvider, metricName, autoTimeRequests, percentileList, histogram); tagProvider, metricName, autotime);
} }
@Override @Override
......
...@@ -18,6 +18,7 @@ package org.springframework.boot.actuate.metrics.web.reactive.client; ...@@ -18,6 +18,7 @@ package org.springframework.boot.actuate.metrics.web.reactive.client;
import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; import org.springframework.boot.web.reactive.function.client.WebClientCustomizer;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
...@@ -39,11 +40,30 @@ public class MetricsWebClientCustomizer implements WebClientCustomizer { ...@@ -39,11 +40,30 @@ public class MetricsWebClientCustomizer implements WebClientCustomizer {
* @param meterRegistry the meter registry * @param meterRegistry the meter registry
* @param tagProvider the tag provider * @param tagProvider the tag provider
* @param metricName the name of the recorded metric * @param metricName the name of the recorded metric
* @deprecated since 2.2.0 in favor of
* {@link #MetricsWebClientCustomizer(MeterRegistry, WebClientExchangeTagsProvider, String, Autotime)}
*/ */
@Deprecated
public MetricsWebClientCustomizer(MeterRegistry meterRegistry, public MetricsWebClientCustomizer(MeterRegistry meterRegistry,
WebClientExchangeTagsProvider tagProvider, String metricName) { WebClientExchangeTagsProvider tagProvider, String metricName) {
this(meterRegistry, tagProvider, metricName, new Autotime());
}
/**
* Create a new {@code MetricsWebClientFilterFunction} that will record metrics using
* the given {@code meterRegistry} with tags provided by the given
* {@code tagProvider}.
* @param meterRegistry the meter registry
* @param tagProvider the tag provider
* @param metricName the name of the recorded metric
* @param autotime auto-timed request settings
* @since 2.2.0
*/
public MetricsWebClientCustomizer(MeterRegistry meterRegistry,
WebClientExchangeTagsProvider tagProvider, String metricName,
Autotime autotime) {
this.filterFunction = new MetricsWebClientFilterFunction(meterRegistry, this.filterFunction = new MetricsWebClientFilterFunction(meterRegistry,
tagProvider, metricName); tagProvider, metricName, autotime);
} }
@Override @Override
......
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
package org.springframework.boot.actuate.metrics.web.reactive.client; package org.springframework.boot.actuate.metrics.web.reactive.client;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MeterRegistry;
...@@ -24,6 +23,7 @@ import io.micrometer.core.instrument.Tag; ...@@ -24,6 +23,7 @@ import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Timer; import io.micrometer.core.instrument.Timer;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction; import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
...@@ -48,11 +48,7 @@ public class MetricsWebClientFilterFunction implements ExchangeFilterFunction { ...@@ -48,11 +48,7 @@ public class MetricsWebClientFilterFunction implements ExchangeFilterFunction {
private final String metricName; private final String metricName;
private final boolean autoTimeRequests; private final Autotime autotime;
private final double[] percentiles;
private final boolean histogram;
/** /**
* Create a new {@code MetricsWebClientFilterFunction}. * Create a new {@code MetricsWebClientFilterFunction}.
...@@ -60,11 +56,12 @@ public class MetricsWebClientFilterFunction implements ExchangeFilterFunction { ...@@ -60,11 +56,12 @@ public class MetricsWebClientFilterFunction implements ExchangeFilterFunction {
* @param tagProvider provider for metrics tags * @param tagProvider provider for metrics tags
* @param metricName name of the metric to record * @param metricName name of the metric to record
* @deprecated since 2.2.0 in favor of * @deprecated since 2.2.0 in favor of
* {@link #MetricsWebClientFilterFunction(MeterRegistry, WebClientExchangeTagsProvider, String, boolean, List, boolean)} * {@link #MetricsWebClientFilterFunction(MeterRegistry, WebClientExchangeTagsProvider, String, Autotime)}
*/ */
@Deprecated
public MetricsWebClientFilterFunction(MeterRegistry meterRegistry, public MetricsWebClientFilterFunction(MeterRegistry meterRegistry,
WebClientExchangeTagsProvider tagProvider, String metricName) { WebClientExchangeTagsProvider tagProvider, String metricName) {
this(meterRegistry, tagProvider, metricName, true, null, false); this(meterRegistry, tagProvider, metricName, new Autotime());
} }
/** /**
...@@ -72,40 +69,33 @@ public class MetricsWebClientFilterFunction implements ExchangeFilterFunction { ...@@ -72,40 +69,33 @@ public class MetricsWebClientFilterFunction implements ExchangeFilterFunction {
* @param meterRegistry the registry to which metrics are recorded * @param meterRegistry the registry to which metrics are recorded
* @param tagProvider provider for metrics tags * @param tagProvider provider for metrics tags
* @param metricName name of the metric to record * @param metricName name of the metric to record
* @param autoTimeRequests if requests should be automatically timed * @param autotime auto-timed request settings
* @param percentileList percentiles for auto time requests
* @param histogram histogram or not for auto time requests
* @since 2.2.0 * @since 2.2.0
*/ */
public MetricsWebClientFilterFunction(MeterRegistry meterRegistry, public MetricsWebClientFilterFunction(MeterRegistry meterRegistry,
WebClientExchangeTagsProvider tagProvider, String metricName, WebClientExchangeTagsProvider tagProvider, String metricName,
boolean autoTimeRequests, List<Double> percentileList, boolean histogram) { Autotime autotime) {
double[] percentiles = (percentileList != null)
? percentileList.stream().mapToDouble(Double::doubleValue).toArray()
: null;
this.meterRegistry = meterRegistry; this.meterRegistry = meterRegistry;
this.tagProvider = tagProvider; this.tagProvider = tagProvider;
this.metricName = metricName; this.metricName = metricName;
this.autoTimeRequests = autoTimeRequests; this.autotime = (autotime != null) ? autotime : Autotime.disabled();
this.percentiles = percentiles;
this.histogram = histogram;
} }
@Override @Override
public Mono<ClientResponse> filter(ClientRequest clientRequest, public Mono<ClientResponse> filter(ClientRequest clientRequest,
ExchangeFunction exchangeFunction) { ExchangeFunction exchangeFunction) {
return exchangeFunction.exchange(clientRequest).doOnEach((signal) -> { return exchangeFunction.exchange(clientRequest).doOnEach((signal) -> {
if (!signal.isOnComplete() && this.autoTimeRequests) { if (!signal.isOnComplete() && this.autotime.isEnabled()) {
Long startTime = signal.getContext().get(METRICS_WEBCLIENT_START_TIME); Long startTime = signal.getContext().get(METRICS_WEBCLIENT_START_TIME);
ClientResponse clientResponse = signal.get(); ClientResponse clientResponse = signal.get();
Throwable throwable = signal.getThrowable(); Throwable throwable = signal.getThrowable();
Iterable<Tag> tags = this.tagProvider.tags(clientRequest, clientResponse, Iterable<Tag> tags = this.tagProvider.tags(clientRequest, clientResponse,
throwable); throwable);
Timer.builder(this.metricName).publishPercentiles(this.percentiles) Timer.builder(this.metricName)
.publishPercentileHistogram(this.histogram).tags(tags) .publishPercentiles(this.autotime.getPercentiles())
.description("Timer of WebClient operation") .publishPercentileHistogram(
this.autotime.isPercentilesHistogram())
.tags(tags).description("Timer of WebClient operation")
.register(this.meterRegistry) .register(this.meterRegistry)
.record(System.nanoTime() - startTime, TimeUnit.NANOSECONDS); .record(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
} }
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
package org.springframework.boot.actuate.metrics.web.reactive.server; package org.springframework.boot.actuate.metrics.web.reactive.server;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MeterRegistry;
...@@ -25,6 +24,7 @@ import io.micrometer.core.instrument.Timer; ...@@ -25,6 +24,7 @@ import io.micrometer.core.instrument.Timer;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponse;
...@@ -48,11 +48,7 @@ public class MetricsWebFilter implements WebFilter { ...@@ -48,11 +48,7 @@ public class MetricsWebFilter implements WebFilter {
private final String metricName; private final String metricName;
private final boolean autoTimeRequests; private final Autotime autotime;
private final double[] percentiles;
private final boolean histogram;
/** /**
* Create a new {@code MetricsWebFilter}. * Create a new {@code MetricsWebFilter}.
...@@ -61,12 +57,13 @@ public class MetricsWebFilter implements WebFilter { ...@@ -61,12 +57,13 @@ public class MetricsWebFilter implements WebFilter {
* @param metricName name of the metric to record * @param metricName name of the metric to record
* @param autoTimeRequests if requests should be automatically timed * @param autoTimeRequests if requests should be automatically timed
* @deprecated since 2.2.0 in favor of * @deprecated since 2.2.0 in favor of
* {@link #MetricsWebFilter(MeterRegistry, WebFluxTagsProvider, String, boolean, List, boolean)} * {@link #MetricsWebFilter(MeterRegistry, WebFluxTagsProvider, String, Autotime)}
*/ */
@Deprecated @Deprecated
public MetricsWebFilter(MeterRegistry registry, WebFluxTagsProvider tagsProvider, public MetricsWebFilter(MeterRegistry registry, WebFluxTagsProvider tagsProvider,
String metricName, boolean autoTimeRequests) { String metricName, boolean autoTimeRequests) {
this(registry, tagsProvider, metricName, autoTimeRequests, null, false); this(registry, tagsProvider, metricName,
new Autotime(autoTimeRequests, false, null));
} }
/** /**
...@@ -74,30 +71,20 @@ public class MetricsWebFilter implements WebFilter { ...@@ -74,30 +71,20 @@ public class MetricsWebFilter implements WebFilter {
* @param registry the registry to which metrics are recorded * @param registry the registry to which metrics are recorded
* @param tagsProvider provider for metrics tags * @param tagsProvider provider for metrics tags
* @param metricName name of the metric to record * @param metricName name of the metric to record
* @param autoTimeRequests if requests should be automatically timed * @param autotime auto timed request settings
* @param percentileList percentiles for auto time requests
* @param histogram histogram or not for auto time requests
* @since 2.2.0 * @since 2.2.0
*/ */
public MetricsWebFilter(MeterRegistry registry, WebFluxTagsProvider tagsProvider, public MetricsWebFilter(MeterRegistry registry, WebFluxTagsProvider tagsProvider,
String metricName, boolean autoTimeRequests, List<Double> percentileList, String metricName, Autotime autotime) {
boolean histogram) {
double[] percentiles = (percentileList != null)
? percentileList.stream().mapToDouble(Double::doubleValue).toArray()
: null;
this.registry = registry; this.registry = registry;
this.tagsProvider = tagsProvider; this.tagsProvider = tagsProvider;
this.metricName = metricName; this.metricName = metricName;
this.autoTimeRequests = autoTimeRequests; this.autotime = (autotime != null) ? autotime : Autotime.disabled();
this.percentiles = percentiles;
this.histogram = histogram;
} }
@Override @Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
if (this.autoTimeRequests) { if (this.autotime.isEnabled()) {
return chain.filter(exchange).compose((call) -> filter(exchange, call)); return chain.filter(exchange).compose((call) -> filter(exchange, call));
} }
return chain.filter(exchange); return chain.filter(exchange);
...@@ -122,8 +109,10 @@ public class MetricsWebFilter implements WebFilter { ...@@ -122,8 +109,10 @@ public class MetricsWebFilter implements WebFilter {
private void record(ServerWebExchange exchange, long start, Throwable cause) { private void record(ServerWebExchange exchange, long start, Throwable cause) {
Iterable<Tag> tags = this.tagsProvider.httpRequestTags(exchange, cause); Iterable<Tag> tags = this.tagsProvider.httpRequestTags(exchange, cause);
Timer.builder(this.metricName).tags(tags).publishPercentiles(this.percentiles) Timer.builder(this.metricName).tags(tags)
.publishPercentileHistogram(this.histogram).register(this.registry) .publishPercentiles(this.autotime.getPercentiles())
.publishPercentileHistogram(this.autotime.isPercentilesHistogram())
.register(this.registry)
.record(System.nanoTime() - start, TimeUnit.NANOSECONDS); .record(System.nanoTime() - start, TimeUnit.NANOSECONDS);
} }
......
...@@ -19,7 +19,6 @@ package org.springframework.boot.actuate.metrics.web.servlet; ...@@ -19,7 +19,6 @@ package org.springframework.boot.actuate.metrics.web.servlet;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.AnnotatedElement; import java.lang.reflect.AnnotatedElement;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.Supplier; import java.util.function.Supplier;
...@@ -35,6 +34,7 @@ import io.micrometer.core.instrument.Timer; ...@@ -35,6 +34,7 @@ import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.Timer.Builder; import io.micrometer.core.instrument.Timer.Builder;
import io.micrometer.core.instrument.Timer.Sample; import io.micrometer.core.instrument.Timer.Sample;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.core.annotation.MergedAnnotationCollectors; import org.springframework.core.annotation.MergedAnnotationCollectors;
import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
...@@ -60,11 +60,7 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter { ...@@ -60,11 +60,7 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter {
private final String metricName; private final String metricName;
private final boolean autoTimeRequests; private final Autotime autotime;
private final double[] autoTimeRequestsPercentiles;
private final boolean autoTimeRequestsHistogram;
/** /**
* Create a new {@link WebMvcMetricsFilter} instance. * Create a new {@link WebMvcMetricsFilter} instance.
...@@ -73,13 +69,14 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter { ...@@ -73,13 +69,14 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter {
* @param metricName the metric name * @param metricName the metric name
* @param autoTimeRequests if requests should be automatically timed * @param autoTimeRequests if requests should be automatically timed
* @since 2.0.7 * @since 2.0.7
* @deprecated since 2.1.4 in favor of * @deprecated since 2.2.0 in favor of
* {@link #WebMvcMetricsFilter(MeterRegistry, WebMvcTagsProvider, String, boolean, List, boolean)} * {@link #WebMvcMetricsFilter(MeterRegistry, WebMvcTagsProvider, String, Autotime)}
*/ */
@Deprecated @Deprecated
public WebMvcMetricsFilter(MeterRegistry registry, WebMvcTagsProvider tagsProvider, public WebMvcMetricsFilter(MeterRegistry registry, WebMvcTagsProvider tagsProvider,
String metricName, boolean autoTimeRequests) { String metricName, boolean autoTimeRequests) {
this(registry, tagsProvider, metricName, autoTimeRequests, null, false); this(registry, tagsProvider, metricName,
new Autotime(autoTimeRequests, false, null));
} }
/** /**
...@@ -87,26 +84,15 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter { ...@@ -87,26 +84,15 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter {
* @param registry the meter registry * @param registry the meter registry
* @param tagsProvider the tags provider * @param tagsProvider the tags provider
* @param metricName the metric name * @param metricName the metric name
* @param autoTimeRequests if requests should be automatically timed * @param autotime auto timed request settings
* @param autoTimeRequestsPercentiles default percentiles if requests are auto timed
* @param autoTimeRequestsHistogram default histogram flag if requests are auto timed
* @since 2.2.0 * @since 2.2.0
*/ */
public WebMvcMetricsFilter(MeterRegistry registry, WebMvcTagsProvider tagsProvider, public WebMvcMetricsFilter(MeterRegistry registry, WebMvcTagsProvider tagsProvider,
String metricName, boolean autoTimeRequests, String metricName, Autotime autotime) {
List<Double> autoTimeRequestsPercentiles, boolean autoTimeRequestsHistogram) {
double[] percentiles = (autoTimeRequestsPercentiles != null)
? autoTimeRequestsPercentiles.stream().mapToDouble(Double::doubleValue)
.toArray()
: null;
this.registry = registry; this.registry = registry;
this.tagsProvider = tagsProvider; this.tagsProvider = tagsProvider;
this.metricName = metricName; this.metricName = metricName;
this.autoTimeRequests = autoTimeRequests; this.autotime = autotime;
this.autoTimeRequestsPercentiles = percentiles;
this.autoTimeRequestsHistogram = autoTimeRequestsHistogram;
} }
@Override @Override
...@@ -187,10 +173,12 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter { ...@@ -187,10 +173,12 @@ public class WebMvcMetricsFilter extends OncePerRequestFilter {
Supplier<Iterable<Tag>> tags = () -> this.tagsProvider.getTags(request, response, Supplier<Iterable<Tag>> tags = () -> this.tagsProvider.getTags(request, response,
handlerObject, exception); handlerObject, exception);
if (annotations.isEmpty()) { if (annotations.isEmpty()) {
if (this.autoTimeRequests) { if (this.autotime.isEnabled()) {
stop(timerSample, tags, Timer.builder(this.metricName) stop(timerSample, tags,
.publishPercentiles(this.autoTimeRequestsPercentiles) Timer.builder(this.metricName)
.publishPercentileHistogram(this.autoTimeRequestsHistogram)); .publishPercentiles(this.autotime.getPercentiles())
.publishPercentileHistogram(
this.autotime.isPercentilesHistogram()));
} }
} }
else { else {
......
...@@ -27,6 +27,7 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry; ...@@ -27,6 +27,7 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.test.web.client.MockRestServiceServer;
...@@ -59,7 +60,7 @@ public class MetricsRestTemplateCustomizerTests { ...@@ -59,7 +60,7 @@ public class MetricsRestTemplateCustomizerTests {
this.mockServer = MockRestServiceServer.createServer(this.restTemplate); this.mockServer = MockRestServiceServer.createServer(this.restTemplate);
this.customizer = new MetricsRestTemplateCustomizer(this.registry, this.customizer = new MetricsRestTemplateCustomizer(this.registry,
new DefaultRestTemplateExchangeTagsProvider(), "http.client.requests", new DefaultRestTemplateExchangeTagsProvider(), "http.client.requests",
true, null, false); new Autotime());
this.customizer.customize(this.restTemplate); this.customizer.customize(this.restTemplate);
} }
......
...@@ -40,7 +40,7 @@ public class MetricsWebClientCustomizerTests { ...@@ -40,7 +40,7 @@ public class MetricsWebClientCustomizerTests {
@Before @Before
public void setup() { public void setup() {
this.customizer = new MetricsWebClientCustomizer(mock(MeterRegistry.class), this.customizer = new MetricsWebClientCustomizer(mock(MeterRegistry.class),
mock(WebClientExchangeTagsProvider.class), "test"); mock(WebClientExchangeTagsProvider.class), "test", null);
this.clientBuilder = WebClient.builder(); this.clientBuilder = WebClient.builder();
} }
......
...@@ -30,6 +30,7 @@ import org.junit.Before; ...@@ -30,6 +30,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientRequest;
...@@ -63,7 +64,8 @@ public class MetricsWebClientFilterFunctionTests { ...@@ -63,7 +64,8 @@ public class MetricsWebClientFilterFunctionTests {
public void setup() { public void setup() {
this.registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock()); this.registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock());
this.filterFunction = new MetricsWebClientFilterFunction(this.registry, this.filterFunction = new MetricsWebClientFilterFunction(this.registry,
new DefaultWebClientExchangeTagsProvider(), "http.client.requests"); new DefaultWebClientExchangeTagsProvider(), "http.client.requests",
new Autotime());
this.response = mock(ClientResponse.class); this.response = mock(ClientResponse.class);
this.exchange = (r) -> Mono.just(this.response); this.exchange = (r) -> Mono.just(this.response);
} }
......
/* /*
* Copyright 2012-2018 the original author or authors. * Copyright 2012-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -25,6 +25,7 @@ import org.junit.Before; ...@@ -25,6 +25,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest; import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange; import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.HandlerMapping;
...@@ -50,8 +51,7 @@ public class MetricsWebFilterTests { ...@@ -50,8 +51,7 @@ public class MetricsWebFilterTests {
MockClock clock = new MockClock(); MockClock clock = new MockClock();
this.registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, clock); this.registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, clock);
this.webFilter = new MetricsWebFilter(this.registry, this.webFilter = new MetricsWebFilter(this.registry,
new DefaultWebFluxTagsProvider(), REQUEST_METRICS_NAME, true, null, new DefaultWebFluxTagsProvider(), REQUEST_METRICS_NAME, new Autotime());
false);
} }
@Test @Test
......
...@@ -30,6 +30,7 @@ import org.junit.Test; ...@@ -30,6 +30,7 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
...@@ -106,7 +107,8 @@ public class WebMvcMetricsFilterAutoTimedTests { ...@@ -106,7 +107,8 @@ public class WebMvcMetricsFilterAutoTimedTests {
public WebMvcMetricsFilter webMetricsFilter(WebApplicationContext context, public WebMvcMetricsFilter webMetricsFilter(WebApplicationContext context,
MeterRegistry registry) { MeterRegistry registry) {
return new WebMvcMetricsFilter(registry, new DefaultWebMvcTagsProvider(), return new WebMvcMetricsFilter(registry, new DefaultWebMvcTagsProvider(),
"http.server.requests", true, Arrays.asList(0.5, 0.95), true); "http.server.requests",
new Autotime(true, true, Arrays.asList(0.5, 0.95)));
} }
} }
......
...@@ -56,6 +56,7 @@ import org.junit.runner.RunWith; ...@@ -56,6 +56,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
...@@ -372,7 +373,7 @@ public class WebMvcMetricsFilterTests { ...@@ -372,7 +373,7 @@ public class WebMvcMetricsFilterTests {
WebMvcMetricsFilter webMetricsFilter(MeterRegistry registry, WebMvcMetricsFilter webMetricsFilter(MeterRegistry registry,
WebApplicationContext ctx) { WebApplicationContext ctx) {
return new WebMvcMetricsFilter(registry, new DefaultWebMvcTagsProvider(), return new WebMvcMetricsFilter(registry, new DefaultWebMvcTagsProvider(),
"http.server.requests", true, null, false); "http.server.requests", new Autotime());
} }
} }
......
...@@ -27,6 +27,7 @@ import org.junit.Test; ...@@ -27,6 +27,7 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.metrics.Autotime;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
...@@ -111,7 +112,7 @@ public class WebMvcMetricsIntegrationTests { ...@@ -111,7 +112,7 @@ public class WebMvcMetricsIntegrationTests {
public WebMvcMetricsFilter webMetricsFilter(MeterRegistry registry, public WebMvcMetricsFilter webMetricsFilter(MeterRegistry registry,
WebApplicationContext ctx) { WebApplicationContext ctx) {
return new WebMvcMetricsFilter(registry, new DefaultWebMvcTagsProvider(), return new WebMvcMetricsFilter(registry, new DefaultWebMvcTagsProvider(),
"http.server.requests", true, null, false); "http.server.requests", new Autotime());
} }
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
......
...@@ -1801,9 +1801,9 @@ application's absolute start time ...@@ -1801,9 +1801,9 @@ application's absolute start time
[[production-ready-metrics-spring-mvc]] [[production-ready-metrics-spring-mvc]]
==== Spring MVC Metrics ==== Spring MVC Metrics
Auto-configuration enables the instrumentation of requests handled by Spring MVC. When Auto-configuration enables the instrumentation of requests handled by Spring MVC. When
`management.metrics.web.server.request.auto-time.enabled` is `true`, this instrumentation occurs `management.metrics.web.server.request.autotime.enabled` is `true`, this instrumentation
for all requests. Alternatively, when set to `false`, you can enable instrumentation by occurs for all requests. Alternatively, when set to `false`, you can enable
adding `@Timed` to a request-handling method: instrumentation by adding `@Timed` to a request-handling method:
[source,java,indent=0] [source,java,indent=0]
---- ----
...@@ -1896,8 +1896,8 @@ To customize the tags, provide a `@Bean` that implements `WebFluxTagsProvider`. ...@@ -1896,8 +1896,8 @@ To customize the tags, provide a `@Bean` that implements `WebFluxTagsProvider`.
[[production-ready-metrics-jersey-server]] [[production-ready-metrics-jersey-server]]
==== Jersey Server Metrics ==== Jersey Server Metrics
Auto-configuration enables the instrumentation of requests handled by the Jersey JAX-RS Auto-configuration enables the instrumentation of requests handled by the Jersey JAX-RS
implementation. When `management.metrics.web.server.request.auto-time.enabled` is `true`, this implementation. When `management.metrics.web.server.request.autotime.enabled` is `true`,
instrumentation occurs for all requests. Alternatively, when set to `false`, you can this instrumentation occurs for all requests. Alternatively, when set to `false`, you can
enable instrumentation by adding `@Timed` to a request-handling method: enable instrumentation by adding `@Timed` to a request-handling method:
[source,java,indent=0] [source,java,indent=0]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment