Skip to content

Commit d102e8b

Browse files
Disable HTTP Observations for Actuator
Closes gh-34801
1 parent d1449fb commit d102e8b

File tree

5 files changed

+440
-3
lines changed

5 files changed

+440
-3
lines changed

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

+37
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.observation.web.reactive;
1818

19+
import java.nio.file.Path;
20+
1921
import io.micrometer.core.instrument.MeterRegistry;
2022
import io.micrometer.core.instrument.config.MeterFilter;
2123
import io.micrometer.observation.Observation;
24+
import io.micrometer.observation.ObservationPredicate;
2225
import io.micrometer.observation.ObservationRegistry;
2326

2427
import org.springframework.beans.factory.ObjectProvider;
@@ -29,18 +32,22 @@
2932
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
3033
import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
3134
import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
35+
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
3236
import org.springframework.boot.autoconfigure.AutoConfiguration;
3337
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
3438
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
3539
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3640
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
41+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3742
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
43+
import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties;
3844
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3945
import org.springframework.context.annotation.Bean;
4046
import org.springframework.context.annotation.Configuration;
4147
import org.springframework.core.Ordered;
4248
import org.springframework.core.annotation.Order;
4349
import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention;
50+
import org.springframework.http.server.reactive.observation.ServerRequestObservationContext;
4451
import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention;
4552
import org.springframework.web.filter.reactive.ServerHttpObservationFilter;
4653

@@ -51,6 +58,7 @@
5158
* @author Brian Clozel
5259
* @author Jon Schneider
5360
* @author Dmytro Nosan
61+
* @author Jonatan Ivanov
5462
* @since 3.0.0
5563
*/
5664
@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class,
@@ -97,4 +105,33 @@ MeterFilter metricsHttpServerUriTagFilter(MetricsProperties metricsProperties,
97105

98106
}
99107

108+
@Configuration(proxyBeanMethods = false)
109+
@ConditionalOnProperty(value = "management.observations.http.server.actuator.enabled", havingValue = "false")
110+
static class ActuatorWebEndpointObservationConfiguration {
111+
112+
@Bean
113+
ObservationPredicate actuatorWebEndpointObservationPredicate(WebFluxProperties webFluxProperties,
114+
PathMappedEndpoints pathMappedEndpoints) {
115+
return (name, context) -> {
116+
if (context instanceof ServerRequestObservationContext serverContext) {
117+
String endpointPath = getEndpointPath(webFluxProperties, pathMappedEndpoints);
118+
return !serverContext.getCarrier().getURI().getPath().startsWith(endpointPath);
119+
}
120+
return true;
121+
};
122+
123+
}
124+
125+
private static String getEndpointPath(WebFluxProperties webFluxProperties,
126+
PathMappedEndpoints pathMappedEndpoints) {
127+
String webFluxBasePath = getWebFluxBasePath(webFluxProperties);
128+
return Path.of(webFluxBasePath, pathMappedEndpoints.getBasePath()).toString();
129+
}
130+
131+
private static String getWebFluxBasePath(WebFluxProperties webFluxProperties) {
132+
return (webFluxProperties.getBasePath() != null) ? webFluxProperties.getBasePath() : "";
133+
}
134+
135+
}
136+
100137
}

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

+47-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.observation.web.servlet;
1818

19+
import java.nio.file.Path;
20+
1921
import io.micrometer.core.instrument.MeterRegistry;
2022
import io.micrometer.core.instrument.config.MeterFilter;
2123
import io.micrometer.observation.Observation;
24+
import io.micrometer.observation.ObservationPredicate;
2225
import io.micrometer.observation.ObservationRegistry;
2326
import jakarta.servlet.DispatcherType;
2427

@@ -30,19 +33,25 @@
3033
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
3134
import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
3235
import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
36+
import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints;
3337
import org.springframework.boot.autoconfigure.AutoConfiguration;
3438
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
3539
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
3640
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
41+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3742
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
43+
import org.springframework.boot.autoconfigure.web.ServerProperties;
44+
import org.springframework.boot.autoconfigure.web.ServerProperties.Servlet;
3845
import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean;
46+
import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties;
3947
import org.springframework.boot.context.properties.EnableConfigurationProperties;
4048
import org.springframework.boot.web.servlet.FilterRegistrationBean;
4149
import org.springframework.context.annotation.Bean;
4250
import org.springframework.context.annotation.Configuration;
4351
import org.springframework.core.Ordered;
4452
import org.springframework.core.annotation.Order;
4553
import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
54+
import org.springframework.http.server.observation.ServerRequestObservationContext;
4655
import org.springframework.http.server.observation.ServerRequestObservationConvention;
4756
import org.springframework.web.filter.ServerHttpObservationFilter;
4857
import org.springframework.web.servlet.DispatcherServlet;
@@ -54,14 +63,16 @@
5463
* @author Brian Clozel
5564
* @author Jon Schneider
5665
* @author Dmytro Nosan
66+
* @author Jonatan Ivanov
5767
* @since 3.0.0
5868
*/
5969
@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class,
6070
SimpleMetricsExportAutoConfiguration.class, ObservationAutoConfiguration.class })
6171
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
6272
@ConditionalOnClass({ DispatcherServlet.class, Observation.class })
6373
@ConditionalOnBean(ObservationRegistry.class)
64-
@EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class })
74+
@EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class, ServerProperties.class,
75+
WebMvcProperties.class })
6576
public class WebMvcObservationAutoConfiguration {
6677

6778
@Bean
@@ -97,4 +108,39 @@ MeterFilter metricsHttpServerUriTagFilter(ObservationProperties observationPrope
97108

98109
}
99110

111+
@Configuration(proxyBeanMethods = false)
112+
@ConditionalOnProperty(value = "management.observations.http.server.actuator.enabled", havingValue = "false")
113+
static class ActuatorWebEndpointObservationConfiguration {
114+
115+
@Bean
116+
ObservationPredicate actuatorWebEndpointObservationPredicate(ServerProperties serverProperties,
117+
WebMvcProperties webMvcProperties, PathMappedEndpoints pathMappedEndpoints) {
118+
return (name, context) -> {
119+
if (context instanceof ServerRequestObservationContext serverContext) {
120+
String endpointPath = getEndpointPath(serverProperties, webMvcProperties, pathMappedEndpoints);
121+
return !serverContext.getCarrier().getRequestURI().startsWith(endpointPath);
122+
}
123+
return true;
124+
};
125+
}
126+
127+
private static String getEndpointPath(ServerProperties serverProperties, WebMvcProperties webMvcProperties,
128+
PathMappedEndpoints pathMappedEndpoints) {
129+
String contextPath = getContextPath(serverProperties);
130+
String servletPath = getServletPath(webMvcProperties);
131+
return Path.of(contextPath, servletPath, pathMappedEndpoints.getBasePath()).toString();
132+
}
133+
134+
private static String getContextPath(ServerProperties serverProperties) {
135+
Servlet servlet = serverProperties.getServlet();
136+
return (servlet.getContextPath() != null) ? servlet.getContextPath() : "";
137+
}
138+
139+
private static String getServletPath(WebMvcProperties webMvcProperties) {
140+
WebMvcProperties.Servlet servletProperties = webMvcProperties.getServlet();
141+
return (servletProperties.getPath() != null) ? servletProperties.getPath() : "";
142+
}
143+
144+
}
145+
100146
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json

+6
Original file line numberDiff line numberDiff line change
@@ -2054,6 +2054,12 @@
20542054
"level": "error"
20552055
}
20562056
},
2057+
{
2058+
"name": "management.observations.http.server.actuator.enabled",
2059+
"type": "java.lang.Boolean",
2060+
"description": "Whether to enable HTTP observations for actuator endpoints.",
2061+
"defaultValue": false
2062+
},
20572063
{
20582064
"name": "management.otlp.tracing.compression",
20592065
"defaultValue": "none"

0 commit comments

Comments
 (0)