Skip to content

Commit 0367236

Browse files
committed
Add properties for default config of auto-timed metrics
When `management.metrics.web.server.auto-time-requests` is enabled (default=true), spring-boot collects metrics on controller methods even when they are not annotated with `@Timed`. When this happens, created metrics are based on the default configuration values of `@Timed`. Currently, there is no way to specify the default configuration to those auto-timed controller metrics. This commit adds default configurations to auto-time requests on both client and server sides. These properties are introduced: - "management.metrics.web.[server|client].request.auto-time.enabled" - "management.metrics.web.[server|client].request.auto-time.default-percentiles" - "management.metrics.web.[server|client].request.auto-time.default-histogram" Also, "requests-metric-name" property is updated: old: "management.metrics.web.[server|client].requests-metric-name" new: "management.metrics.web.[server|client].request.metric-name" This property is removed: - `management.metrics.web.server.auto-time-requests`
1 parent 054c8ee commit 0367236

File tree

20 files changed

+389
-76
lines changed

20 files changed

+389
-76
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java

Lines changed: 117 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.metrics;
1818

19+
import java.util.ArrayList;
1920
import java.util.LinkedHashMap;
21+
import java.util.List;
2022
import java.util.Map;
2123

2224
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -26,6 +28,7 @@
2628
*
2729
* @author Jon Schneider
2830
* @author Alexander Abramov
31+
* @author Tadaya Tsuyukubo
2932
* @since 2.0.0
3033
*/
3134
@ConfigurationProperties("management.metrics")
@@ -93,10 +96,7 @@ public Server getServer() {
9396

9497
public static class Client {
9598

96-
/**
97-
* Name of the metric for sent requests.
98-
*/
99-
private String requestsMetricName = "http.client.requests";
99+
private final Request request = new Request("http.client.requests");
100100

101101
/**
102102
* Maximum number of unique URI tag values allowed. After the max number of
@@ -105,12 +105,26 @@ public static class Client {
105105
*/
106106
private int maxUriTags = 100;
107107

108+
/**
109+
* Get name of the metric for received requests.
110+
* @return request metric name
111+
* @deprecated since 2.2.0 in favor of {@link Request#getMetricName()}
112+
*/
108113
public String getRequestsMetricName() {
109-
return this.requestsMetricName;
114+
return this.request.getMetricName();
110115
}
111116

117+
/**
118+
* Set name of the metric for received requests.
119+
* @param requestsMetricName request metric name
120+
* @deprecated since 2.2.0 in favor of {@link Request#setMetricName(String)}
121+
*/
112122
public void setRequestsMetricName(String requestsMetricName) {
113-
this.requestsMetricName = requestsMetricName;
123+
this.request.setMetricName(requestsMetricName);
124+
}
125+
126+
public Request getRequest() {
127+
return this.request;
114128
}
115129

116130
public int getMaxUriTags() {
@@ -125,18 +139,7 @@ public void setMaxUriTags(int maxUriTags) {
125139

126140
public static class Server {
127141

128-
/**
129-
* Whether requests handled by Spring MVC, WebFlux or Jersey should be
130-
* automatically timed. If the number of time series emitted grows too large
131-
* on account of request mapping timings, disable this and use 'Timed' on a
132-
* per request mapping basis as needed.
133-
*/
134-
private boolean autoTimeRequests = true;
135-
136-
/**
137-
* Name of the metric for received requests.
138-
*/
139-
private String requestsMetricName = "http.server.requests";
142+
private final Request request = new Request("http.server.requests");
140143

141144
/**
142145
* Maximum number of unique URI tag values allowed. After the max number of
@@ -145,20 +148,26 @@ public static class Server {
145148
*/
146149
private int maxUriTags = 100;
147150

148-
public boolean isAutoTimeRequests() {
149-
return this.autoTimeRequests;
150-
}
151-
152-
public void setAutoTimeRequests(boolean autoTimeRequests) {
153-
this.autoTimeRequests = autoTimeRequests;
154-
}
155-
151+
/**
152+
* Get name of the metric for received requests.
153+
* @return request metric name
154+
* @deprecated since 2.2.0 in favor of {@link Request#getMetricName()}
155+
*/
156156
public String getRequestsMetricName() {
157-
return this.requestsMetricName;
157+
return this.request.getMetricName();
158158
}
159159

160+
/**
161+
* Set name of the metric for received requests.
162+
* @param requestsMetricName request metric name
163+
* @deprecated since 2.2.0 in favor of {@link Request#setMetricName(String)}
164+
*/
160165
public void setRequestsMetricName(String requestsMetricName) {
161-
this.requestsMetricName = requestsMetricName;
166+
this.request.setMetricName(requestsMetricName);
167+
}
168+
169+
public Request getRequest() {
170+
return this.request;
162171
}
163172

164173
public int getMaxUriTags() {
@@ -171,6 +180,86 @@ public void setMaxUriTags(int maxUriTags) {
171180

172181
}
173182

183+
public static class Request {
184+
185+
public Request(String metricName) {
186+
this.metricName = metricName;
187+
}
188+
189+
/**
190+
* Automatically time requests.
191+
*/
192+
private final AutoTime autoTime = new AutoTime();
193+
194+
/**
195+
* Name of the metric for received requests.
196+
*/
197+
private String metricName;
198+
199+
public AutoTime getAutoTime() {
200+
return this.autoTime;
201+
}
202+
203+
public String getMetricName() {
204+
return this.metricName;
205+
}
206+
207+
public void setMetricName(String metricName) {
208+
this.metricName = metricName;
209+
}
210+
211+
public static class AutoTime {
212+
213+
/**
214+
* Whether requests handled by Spring MVC, WebFlux or Jersey should be
215+
* automatically timed. If the number of time series emitted grows too
216+
* large on account of request mapping timings, disable this and use
217+
* 'Timed' on a per request mapping basis as needed.
218+
*/
219+
private boolean enabled = true;
220+
221+
/**
222+
* Default percentiles when @Timed annotation is not presented on the
223+
* corresponding request handler. Any @Timed annotation presented will
224+
* have precedence.
225+
*/
226+
private List<Double> defaultPercentiles = new ArrayList<>();
227+
228+
/**
229+
* Default histogram when @Timed annotation is not presented on the
230+
* corresponding request handler. Any @Timed annotation presented will
231+
* have precedence.
232+
*/
233+
private boolean defaultHistogram;
234+
235+
public boolean isEnabled() {
236+
return this.enabled;
237+
}
238+
239+
public void setEnabled(boolean enabled) {
240+
this.enabled = enabled;
241+
}
242+
243+
public List<Double> getDefaultPercentiles() {
244+
return this.defaultPercentiles;
245+
}
246+
247+
public void setDefaultPercentiles(List<Double> defaultPercentiles) {
248+
this.defaultPercentiles = defaultPercentiles;
249+
}
250+
251+
public boolean isDefaultHistogram() {
252+
return this.defaultHistogram;
253+
}
254+
255+
public void setDefaultHistogram(boolean defaultHistogram) {
256+
this.defaultHistogram = defaultHistogram;
257+
}
258+
259+
}
260+
261+
}
262+
174263
}
175264

176265
public static class Distribution {

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/jersey/JerseyServerMetricsAutoConfiguration.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,16 @@ public ResourceConfigCustomizer jerseyServerMetricsResourceConfigCustomizer(
7979
MeterRegistry meterRegistry, JerseyTagsProvider tagsProvider) {
8080
Server server = this.properties.getWeb().getServer();
8181
return (config) -> config.register(new MetricsApplicationEventListener(
82-
meterRegistry, tagsProvider, server.getRequestsMetricName(),
83-
server.isAutoTimeRequests(), new AnnotationUtilsAnnotationFinder()));
82+
meterRegistry, tagsProvider, server.getRequest().getMetricName(),
83+
server.getRequest().getAutoTime().isEnabled(),
84+
new AnnotationUtilsAnnotationFinder()));
8485
}
8586

8687
@Bean
8788
@Order(0)
8889
public MeterFilter jerseyMetricsUriTagFilter() {
89-
String metricName = this.properties.getWeb().getServer().getRequestsMetricName();
90+
String metricName = this.properties.getWeb().getServer().getRequest()
91+
.getMetricName();
9092
MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter(() -> String
9193
.format("Reached the maximum number of URI tags for '%s'.", metricName));
9294
return MeterFilter.maximumAllowableTags(metricName, "uri",

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/HttpClientMetricsAutoConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public class HttpClientMetricsAutoConfiguration {
5353
@Bean
5454
@Order(0)
5555
public MeterFilter metricsHttpClientUriTagFilter(MetricsProperties properties) {
56-
String metricName = properties.getWeb().getClient().getRequestsMetricName();
56+
String metricName = properties.getWeb().getClient().getRequest().getMetricName();
5757
MeterFilter denyFilter = new OnlyOnceLoggingDenyMeterFilter(() -> String
5858
.format("Reached the maximum number of URI tags for '%s'. Are you using "
5959
+ "'uriVariables'?", metricName));

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfiguration.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import io.micrometer.core.instrument.MeterRegistry;
2020

2121
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
22+
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Client;
23+
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Request.AutoTime;
2224
import org.springframework.boot.actuate.metrics.web.client.DefaultRestTemplateExchangeTagsProvider;
2325
import org.springframework.boot.actuate.metrics.web.client.MetricsRestTemplateCustomizer;
2426
import org.springframework.boot.actuate.metrics.web.client.RestTemplateExchangeTagsProvider;
@@ -53,9 +55,13 @@ public MetricsRestTemplateCustomizer metricsRestTemplateCustomizer(
5355
MeterRegistry meterRegistry,
5456
RestTemplateExchangeTagsProvider restTemplateExchangeTagsProvider,
5557
MetricsProperties properties) {
58+
59+
Client client = properties.getWeb().getClient();
60+
AutoTime autoTime = client.getRequest().getAutoTime();
5661
return new MetricsRestTemplateCustomizer(meterRegistry,
57-
restTemplateExchangeTagsProvider,
58-
properties.getWeb().getClient().getRequestsMetricName());
62+
restTemplateExchangeTagsProvider, client.getRequest().getMetricName(),
63+
autoTime.isEnabled(), autoTime.getDefaultPercentiles(),
64+
autoTime.isDefaultHistogram());
5965
}
6066

6167
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/client/WebClientMetricsConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public MetricsWebClientCustomizer metricsWebClientCustomizer(
4949
MeterRegistry meterRegistry, WebClientExchangeTagsProvider tagsProvider,
5050
MetricsProperties properties) {
5151
return new MetricsWebClientCustomizer(meterRegistry, tagsProvider,
52-
properties.getWeb().getClient().getRequestsMetricName());
52+
properties.getWeb().getClient().getRequest().getMetricName());
5353
}
5454

5555
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/reactive/WebFluxMetricsAutoConfiguration.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
2323
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
24+
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Request.AutoTime;
25+
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Server;
2426
import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter;
2527
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
2628
import org.springframework.boot.actuate.metrics.web.reactive.server.DefaultWebFluxTagsProvider;
@@ -65,15 +67,18 @@ public DefaultWebFluxTagsProvider webfluxTagConfigurer() {
6567
@Bean
6668
public MetricsWebFilter webfluxMetrics(MeterRegistry registry,
6769
WebFluxTagsProvider tagConfigurer) {
70+
Server serverProperties = this.properties.getWeb().getServer();
71+
AutoTime autotime = serverProperties.getRequest().getAutoTime();
6872
return new MetricsWebFilter(registry, tagConfigurer,
69-
this.properties.getWeb().getServer().getRequestsMetricName(),
70-
this.properties.getWeb().getServer().isAutoTimeRequests());
73+
serverProperties.getRequest().getMetricName(), autotime.isEnabled(),
74+
autotime.getDefaultPercentiles(), autotime.isDefaultHistogram());
7175
}
7276

7377
@Bean
7478
@Order(0)
7579
public MeterFilter metricsHttpServerUriTagFilter() {
76-
String metricName = this.properties.getWeb().getServer().getRequestsMetricName();
80+
String metricName = this.properties.getWeb().getServer().getRequest()
81+
.getMetricName();
7782
MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter(() -> String
7883
.format("Reached the maximum number of URI tags for '%s'.", metricName));
7984
return MeterFilter.maximumAllowableTags(metricName, "uri",

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/web/servlet/WebMvcMetricsAutoConfiguration.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
2525
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
26+
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Request.AutoTime;
2627
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties.Web.Server;
2728
import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter;
2829
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
@@ -79,9 +80,10 @@ public DefaultWebMvcTagsProvider webMvcTagsProvider() {
7980
public FilterRegistrationBean<WebMvcMetricsFilter> webMvcMetricsFilter(
8081
MeterRegistry registry, WebMvcTagsProvider tagsProvider) {
8182
Server serverProperties = this.properties.getWeb().getServer();
83+
AutoTime autotime = serverProperties.getRequest().getAutoTime();
8284
WebMvcMetricsFilter filter = new WebMvcMetricsFilter(registry, tagsProvider,
83-
serverProperties.getRequestsMetricName(),
84-
serverProperties.isAutoTimeRequests());
85+
serverProperties.getRequest().getMetricName(), autotime.isEnabled(),
86+
autotime.getDefaultPercentiles(), autotime.isDefaultHistogram());
8587
FilterRegistrationBean<WebMvcMetricsFilter> registration = new FilterRegistrationBean<>(
8688
filter);
8789
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
@@ -92,7 +94,8 @@ public FilterRegistrationBean<WebMvcMetricsFilter> webMvcMetricsFilter(
9294
@Bean
9395
@Order(0)
9496
public MeterFilter metricsHttpServerUriTagFilter() {
95-
String metricName = this.properties.getWeb().getServer().getRequestsMetricName();
97+
String metricName = this.properties.getWeb().getServer().getRequest()
98+
.getMetricName();
9699
MeterFilter filter = new OnlyOnceLoggingDenyMeterFilter(() -> String
97100
.format("Reached the maximum number of URI tags for '%s'.", metricName));
98101
return MeterFilter.maximumAllowableTags(metricName, "uri",

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/reactive/WebFluxMetricsAutoConfigurationTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public void metricsAreNotRecordedIfAutoTimeRequestsIsDisabled() {
102102
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class))
103103
.withUserConfiguration(TestController.class)
104104
.withPropertyValues(
105-
"management.metrics.web.server.auto-time-requests=false")
105+
"management.metrics.web.server.request.auto-time.enabled=false")
106106
.run((context) -> {
107107
MeterRegistry registry = getInitializedMeterRegistry(context);
108108
assertThat(registry.find("http.server.requests").meter()).isNull();

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/web/servlet/WebMvcMetricsAutoConfigurationTests.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
import io.micrometer.core.instrument.MeterRegistry;
2828
import io.micrometer.core.instrument.Tag;
29+
import io.micrometer.core.instrument.Timer;
30+
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
2931
import org.junit.Rule;
3032
import org.junit.Test;
3133

@@ -137,6 +139,27 @@ public void shouldNotDenyNorLogIfMaxUrisIsNotReached() {
137139
});
138140
}
139141

142+
@Test
143+
public void autoTimeRequestsDefaultValues() {
144+
this.contextRunner.withUserConfiguration(TestController.class)
145+
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class,
146+
WebMvcAutoConfiguration.class))
147+
.withPropertyValues(
148+
"management.metrics.web.server.request.auto-time.enabled=true",
149+
"management.metrics.web.server.request.auto-time.default-percentiles=0.5,0.7",
150+
"management.metrics.web.server.request.auto-time.default-histogram=true")
151+
.run((context) -> {
152+
MeterRegistry registry = getInitializedMeterRegistry(context);
153+
Timer timer = registry.get("http.server.requests").timer();
154+
HistogramSnapshot snapshot = timer.takeSnapshot();
155+
assertThat(snapshot.percentileValues()).hasSize(2);
156+
assertThat(snapshot.percentileValues()[0].percentile())
157+
.isEqualTo(0.5);
158+
assertThat(snapshot.percentileValues()[1].percentile())
159+
.isEqualTo(0.7);
160+
});
161+
}
162+
140163
@Test
141164
@SuppressWarnings("rawtypes")
142165
public void longTaskTimingInterceptorIsRegistered() {

0 commit comments

Comments
 (0)