|
16 | 16 |
|
17 | 17 | package org.springframework.boot.actuate.autoconfigure.observation.web.servlet;
|
18 | 18 |
|
| 19 | +import java.nio.file.Path; |
| 20 | + |
19 | 21 | import io.micrometer.core.instrument.MeterRegistry;
|
20 | 22 | import io.micrometer.core.instrument.config.MeterFilter;
|
21 | 23 | import io.micrometer.observation.Observation;
|
| 24 | +import io.micrometer.observation.ObservationPredicate; |
22 | 25 | import io.micrometer.observation.ObservationRegistry;
|
23 | 26 | import jakarta.servlet.DispatcherType;
|
24 | 27 |
|
|
30 | 33 | import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
|
31 | 34 | import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
|
32 | 35 | import org.springframework.boot.actuate.autoconfigure.observation.ObservationProperties;
|
| 36 | +import org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints; |
33 | 37 | import org.springframework.boot.autoconfigure.AutoConfiguration;
|
34 | 38 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
35 | 39 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
36 | 40 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
| 41 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
37 | 42 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
| 43 | +import org.springframework.boot.autoconfigure.web.ServerProperties; |
| 44 | +import org.springframework.boot.autoconfigure.web.ServerProperties.Servlet; |
38 | 45 | import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean;
|
| 46 | +import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties; |
39 | 47 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
40 | 48 | import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
41 | 49 | import org.springframework.context.annotation.Bean;
|
42 | 50 | import org.springframework.context.annotation.Configuration;
|
43 | 51 | import org.springframework.core.Ordered;
|
44 | 52 | import org.springframework.core.annotation.Order;
|
45 | 53 | import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
|
| 54 | +import org.springframework.http.server.observation.ServerRequestObservationContext; |
46 | 55 | import org.springframework.http.server.observation.ServerRequestObservationConvention;
|
47 | 56 | import org.springframework.web.filter.ServerHttpObservationFilter;
|
48 | 57 | import org.springframework.web.servlet.DispatcherServlet;
|
|
54 | 63 | * @author Brian Clozel
|
55 | 64 | * @author Jon Schneider
|
56 | 65 | * @author Dmytro Nosan
|
| 66 | + * @author Jonatan Ivanov |
57 | 67 | * @since 3.0.0
|
58 | 68 | */
|
59 | 69 | @AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class,
|
60 | 70 | SimpleMetricsExportAutoConfiguration.class, ObservationAutoConfiguration.class })
|
61 | 71 | @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
62 | 72 | @ConditionalOnClass({ DispatcherServlet.class, Observation.class })
|
63 | 73 | @ConditionalOnBean(ObservationRegistry.class)
|
64 |
| -@EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class }) |
| 74 | +@EnableConfigurationProperties({ MetricsProperties.class, ObservationProperties.class, ServerProperties.class, |
| 75 | + WebMvcProperties.class }) |
65 | 76 | public class WebMvcObservationAutoConfiguration {
|
66 | 77 |
|
67 | 78 | @Bean
|
@@ -97,4 +108,39 @@ MeterFilter metricsHttpServerUriTagFilter(ObservationProperties observationPrope
|
97 | 108 |
|
98 | 109 | }
|
99 | 110 |
|
| 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 | + |
100 | 146 | }
|
0 commit comments