Skip to content

Commit b2fe807

Browse files
committed
Move MVC metrics to Observation auto-configuration
This commit moves the entire Metrics auto-configuration for Spring MVC to the new `Observation` API and the instrumentation contributed in Spring Framework. Closes gh-32538
1 parent e6c6906 commit b2fe807

File tree

29 files changed

+455
-1773
lines changed

29 files changed

+455
-1773
lines changed

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

+4-23
Original file line numberDiff line numberDiff line change
@@ -194,37 +194,18 @@ public static class ServerRequest {
194194
*/
195195
private String metricName = "http.server.requests";
196196

197-
/**
198-
* Whether the trailing slash should be ignored when recording metrics.
199-
*/
200-
private boolean ignoreTrailingSlash = true;
201-
202-
/**
203-
* Auto-timed request settings.
204-
*/
205-
@NestedConfigurationProperty
206-
private final AutoTimeProperties autotime = new AutoTimeProperties();
207-
208-
public AutoTimeProperties getAutotime() {
209-
return this.autotime;
210-
}
211-
197+
@Deprecated(since = "3.0.0", forRemoval = true)
198+
@DeprecatedConfigurationProperty(replacement = "management.observations.http.server.requests.name")
212199
public String getMetricName() {
213200
return this.metricName;
214201
}
215202

203+
@Deprecated(since = "3.0.0", forRemoval = true)
204+
@DeprecatedConfigurationProperty(replacement = "management.observations.http.server.requests.name")
216205
public void setMetricName(String metricName) {
217206
this.metricName = metricName;
218207
}
219208

220-
public boolean isIgnoreTrailingSlash() {
221-
return this.ignoreTrailingSlash;
222-
}
223-
224-
public void setIgnoreTrailingSlash(boolean ignoreTrailingSlash) {
225-
this.ignoreTrailingSlash = ignoreTrailingSlash;
226-
}
227-
228209
}
229210

230211
}

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
@ConditionalOnClass({ ResourceConfig.class, MetricsApplicationEventListener.class })
5858
@ConditionalOnBean({ MeterRegistry.class, ResourceConfig.class })
5959
@EnableConfigurationProperties(MetricsProperties.class)
60+
@SuppressWarnings("removal")
6061
public class JerseyServerMetricsAutoConfiguration {
6162

6263
private final MetricsProperties properties;
@@ -75,9 +76,8 @@ public DefaultJerseyTagsProvider jerseyTagsProvider() {
7576
public ResourceConfigCustomizer jerseyServerMetricsResourceConfigCustomizer(MeterRegistry meterRegistry,
7677
JerseyTagsProvider tagsProvider) {
7778
Server server = this.properties.getWeb().getServer();
78-
return (config) -> config.register(
79-
new MetricsApplicationEventListener(meterRegistry, tagsProvider, server.getRequest().getMetricName(),
80-
server.getRequest().getAutotime().isEnabled(), new AnnotationUtilsAnnotationFinder()));
79+
return (config) -> config.register(new MetricsApplicationEventListener(meterRegistry, tagsProvider,
80+
server.getRequest().getMetricName(), true, new AnnotationUtilsAnnotationFinder()));
8181
}
8282

8383
@Bean

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

+3-4
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
SimpleMetricsExportAutoConfiguration.class })
5252
@ConditionalOnBean(MeterRegistry.class)
5353
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
54+
@SuppressWarnings("removal")
5455
public class WebFluxMetricsAutoConfiguration {
5556

5657
private final MetricsProperties properties;
@@ -62,15 +63,13 @@ public WebFluxMetricsAutoConfiguration(MetricsProperties properties) {
6263
@Bean
6364
@ConditionalOnMissingBean(WebFluxTagsProvider.class)
6465
public DefaultWebFluxTagsProvider webFluxTagsProvider(ObjectProvider<WebFluxTagsContributor> contributors) {
65-
return new DefaultWebFluxTagsProvider(this.properties.getWeb().getServer().getRequest().isIgnoreTrailingSlash(),
66-
contributors.orderedStream().toList());
66+
return new DefaultWebFluxTagsProvider(true, contributors.orderedStream().toList());
6767
}
6868

6969
@Bean
7070
public MetricsWebFilter webfluxMetrics(MeterRegistry registry, WebFluxTagsProvider tagConfigurer) {
7171
ServerRequest request = this.properties.getWeb().getServer().getRequest();
72-
return new MetricsWebFilter(registry, tagConfigurer, request.getMetricName(),
73-
new PropertiesAutoTimer(request.getAutotime()));
72+
return new MetricsWebFilter(registry, tagConfigurer, request.getMetricName(), new PropertiesAutoTimer(null));
7473
}
7574

7675
@Bean

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

-131
This file was deleted.

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java

+34
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,16 @@ public static class Http {
3838

3939
private final Client client = new Client();
4040

41+
private final Server server = new Server();
42+
4143
public Client getClient() {
4244
return this.client;
4345
}
4446

47+
public Server getServer() {
48+
return this.server;
49+
}
50+
4551
public static class Client {
4652

4753
private final ClientRequests requests = new ClientRequests();
@@ -70,6 +76,34 @@ public void setName(String name) {
7076

7177
}
7278

79+
public static class Server {
80+
81+
private final ServerRequests requests = new ServerRequests();
82+
83+
public ServerRequests getRequests() {
84+
return this.requests;
85+
}
86+
87+
public static class ServerRequests {
88+
89+
/**
90+
* Name of the observation for server requests. If empty, will use the
91+
* default "http.server.requests".
92+
*/
93+
private String name;
94+
95+
public String getName() {
96+
return this.name;
97+
}
98+
99+
public void setName(String name) {
100+
this.name = name;
101+
}
102+
103+
}
104+
105+
}
106+
73107
}
74108

75109
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2012-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.autoconfigure.observation.web.servlet;
18+
19+
import java.util.List;
20+
21+
import io.micrometer.common.KeyValues;
22+
import io.micrometer.core.instrument.Tag;
23+
import io.micrometer.observation.Observation;
24+
25+
import org.springframework.boot.actuate.metrics.web.servlet.DefaultWebMvcTagsProvider;
26+
import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsContributor;
27+
import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsProvider;
28+
import org.springframework.http.observation.ServerRequestObservationContext;
29+
import org.springframework.http.observation.ServerRequestObservationConvention;
30+
import org.springframework.util.Assert;
31+
import org.springframework.web.servlet.HandlerMapping;
32+
33+
/**
34+
* Adapter class that applies {@link WebMvcTagsProvider} tags as a
35+
* {@link ServerRequestObservationConvention}.
36+
*
37+
* @author Brian Clozel
38+
*/
39+
@SuppressWarnings({ "deprecation", "removal" })
40+
class ServerRequestObservationConventionAdapter implements ServerRequestObservationConvention {
41+
42+
private final String observationName;
43+
44+
private final WebMvcTagsProvider tagsProvider;
45+
46+
ServerRequestObservationConventionAdapter(String observationName, WebMvcTagsProvider tagsProvider,
47+
List<WebMvcTagsContributor> contributors) {
48+
Assert.state((tagsProvider != null) || (contributors != null),
49+
"adapter should adapt to a WebMvcTagsProvider or a list of contributors");
50+
this.observationName = observationName;
51+
this.tagsProvider = (tagsProvider != null) ? tagsProvider : new DefaultWebMvcTagsProvider(contributors);
52+
}
53+
54+
@Override
55+
public String getName() {
56+
return this.observationName;
57+
}
58+
59+
@Override
60+
public boolean supportsContext(Observation.Context context) {
61+
return context instanceof ServerRequestObservationContext;
62+
}
63+
64+
@Override
65+
public KeyValues getLowCardinalityKeyValues(ServerRequestObservationContext context) {
66+
KeyValues keyValues = KeyValues.empty();
67+
Iterable<Tag> tags = this.tagsProvider.getTags(context.getCarrier(), context.getResponse(), getHandler(context),
68+
context.getError());
69+
for (Tag tag : tags) {
70+
keyValues = keyValues.and(tag.getKey(), tag.getValue());
71+
}
72+
return keyValues;
73+
}
74+
75+
private Object getHandler(ServerRequestObservationContext context) {
76+
return context.getCarrier().getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE);
77+
}
78+
79+
}

0 commit comments

Comments
 (0)