diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java index bc43135d8..dbc2e963b 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java @@ -27,6 +27,8 @@ import brave.Tracing; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; import org.springframework.boot.actuate.endpoint.EndpointsSupplier; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; @@ -101,13 +103,12 @@ public class TraceWebAutoConfiguration { } @Configuration - @ConditionalOnClass({ ServerProperties.class, EndpointsSupplier.class, - ExposableWebEndpoint.class }) + @ConditionalOnClass({ ServerProperties.class, EndpointsSupplier.class, ExposableWebEndpoint.class }) @ConditionalOnBean(ServerProperties.class) @ConditionalOnProperty(value = "spring.sleuth.web.ignoreAutoConfiguredSkipPatterns", havingValue = "false", matchIfMissing = true) protected static class ActuatorSkipPatternProviderConfig { - static Optional getEndpointsPatterns(ServerProperties serverProperties, + static Optional getEndpointsPatterns(String contextPath, WebEndpointProperties webEndpointProperties, EndpointsSupplier endpointsSupplier) { Collection endpoints = endpointsSupplier.getEndpoints(); @@ -116,8 +117,6 @@ public class TraceWebAutoConfiguration { return Optional.empty(); } - String contextPath = serverProperties.getServlet().getContextPath(); - String pattern = endpoints.stream().map(PathMappedEndpoint::getRootPath) .map(path -> path + "|" + path + "/.*").collect( Collectors.joining("|", @@ -142,14 +141,24 @@ public class TraceWebAutoConfiguration { } @Bean - public SingleSkipPattern skipPatternForActuatorEndpoints( + @ConditionalOnManagementPort(ManagementPortType.SAME) + public SingleSkipPattern skipPatternForActuatorEndpointsSamePort( final ServerProperties serverProperties, final WebEndpointProperties webEndpointProperties, final EndpointsSupplier endpointsSupplier) { - return () -> getEndpointsPatterns(serverProperties, webEndpointProperties, - endpointsSupplier); + return () -> getEndpointsPatterns(serverProperties.getServlet().getContextPath(), + webEndpointProperties, endpointsSupplier); + } + + @Bean + @ConditionalOnManagementPort(ManagementPortType.DIFFERENT) + @ConditionalOnProperty(name = "management.server.servlet.context-path", havingValue = "/", matchIfMissing = true) + public SingleSkipPattern skipPatternForActuatorEndpointsDifferentPort( + final ServerProperties serverProperties, + final WebEndpointProperties webEndpointProperties, + final EndpointsSupplier endpointsSupplier) { + return () -> getEndpointsPatterns(null, webEndpointProperties, endpointsSupplier); } - } @Configuration diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProviderConfigTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProviderConfigTest.java index 6dbab83f2..abf8361f2 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProviderConfigTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipPatternProviderConfigTest.java @@ -88,7 +88,7 @@ public class SkipPatternProviderConfigTest { public void should_return_empty_when_no_endpoints() { EndpointsSupplier endpointsSupplier = Collections::emptyList; Optional pattern = new TraceWebAutoConfiguration.ActuatorSkipPatternProviderConfig() - .skipPatternForActuatorEndpoints(new ServerProperties(), + .skipPatternForActuatorEndpointsSamePort(new ServerProperties(), new WebEndpointProperties(), endpointsSupplier) .skipPattern(); @@ -107,8 +107,7 @@ public class SkipPatternProviderConfigTest { }; Optional pattern = new TraceWebAutoConfiguration.ActuatorSkipPatternProviderConfig() - .skipPatternForActuatorEndpoints(properties, webEndpointProperties, - endpointsSupplier) + .skipPatternForActuatorEndpointsSamePort(properties, webEndpointProperties, endpointsSupplier) .skipPattern(); then(pattern).isNotEmpty(); @@ -130,8 +129,7 @@ public class SkipPatternProviderConfigTest { }; Optional pattern = new TraceWebAutoConfiguration.ActuatorSkipPatternProviderConfig() - .skipPatternForActuatorEndpoints(properties, webEndpointProperties, - endpointsSupplier) + .skipPatternForActuatorEndpointsSamePort(properties, webEndpointProperties, endpointsSupplier) .skipPattern(); then(pattern).isNotEmpty(); @@ -153,8 +151,7 @@ public class SkipPatternProviderConfigTest { }; Optional pattern = new TraceWebAutoConfiguration.ActuatorSkipPatternProviderConfig() - .skipPatternForActuatorEndpoints(properties, webEndpointProperties, - endpointsSupplier) + .skipPatternForActuatorEndpointsSamePort(properties, webEndpointProperties, endpointsSupplier) .skipPattern(); then(pattern).isNotEmpty(); @@ -176,14 +173,103 @@ public class SkipPatternProviderConfigTest { }; Optional pattern = new TraceWebAutoConfiguration.ActuatorSkipPatternProviderConfig() - .skipPatternForActuatorEndpoints(properties, webEndpointProperties, - endpointsSupplier) + .skipPatternForActuatorEndpointsSamePort(properties, webEndpointProperties, endpointsSupplier) .skipPattern(); then(pattern).isNotEmpty(); then(pattern.get().pattern()).isEqualTo("foo/(info|info/.*|health|health/.*)"); } + @Test + public void should_return_endpoints_with_actuator_context_path_set_to_root() { + WebEndpointProperties webEndpointProperties = new WebEndpointProperties(); + webEndpointProperties.setBasePath("/"); + ServerProperties properties = new ServerProperties(); + properties.getServlet().setContextPath("foo"); + + EndpointsSupplier endpointsSupplier = () -> { + ExposableWebEndpoint infoEndpoint = createEndpoint("info"); + ExposableWebEndpoint healthEndpoint = createEndpoint("health"); + + return Arrays.asList(infoEndpoint, healthEndpoint); + }; + + Optional patternDifferentPort = new TraceWebAutoConfiguration.ActuatorSkipPatternProviderConfig() + .skipPatternForActuatorEndpointsDifferentPort(properties, webEndpointProperties, endpointsSupplier) + .skipPattern(); + + then(patternDifferentPort).isNotEmpty(); + then(patternDifferentPort.get().pattern()).isEqualTo("/(info|info/.*|health|health/.*)"); + + Optional patternSamePort = new TraceWebAutoConfiguration.ActuatorSkipPatternProviderConfig() + .skipPatternForActuatorEndpointsSamePort(properties, webEndpointProperties, endpointsSupplier) + .skipPattern(); + + then(patternSamePort).isNotEmpty(); + then(patternSamePort.get().pattern()) + .isEqualTo("foo/(info|info/.*|health|health/.*)"); + } + + @Test + public void should_return_endpoints_with_actuator_context_path_only() { + WebEndpointProperties webEndpointProperties = new WebEndpointProperties(); + webEndpointProperties.setBasePath("/mgt"); + ServerProperties properties = new ServerProperties(); + properties.getServlet().setContextPath("foo"); + + EndpointsSupplier endpointsSupplier = () -> { + ExposableWebEndpoint infoEndpoint = createEndpoint("info"); + ExposableWebEndpoint healthEndpoint = createEndpoint("health"); + + return Arrays.asList(infoEndpoint, healthEndpoint); + }; + + Optional patternDifferentPort = new TraceWebAutoConfiguration.ActuatorSkipPatternProviderConfig() + .skipPatternForActuatorEndpointsDifferentPort(properties, webEndpointProperties, endpointsSupplier) + .skipPattern(); + + then(patternDifferentPort).isNotEmpty(); + then(patternDifferentPort.get().pattern()) + .isEqualTo("/mgt/(info|info/.*|health|health/.*)"); + + Optional patternSamePort = new TraceWebAutoConfiguration.ActuatorSkipPatternProviderConfig() + .skipPatternForActuatorEndpointsSamePort(properties, webEndpointProperties, endpointsSupplier) + .skipPattern(); + + then(patternSamePort).isNotEmpty(); + then(patternSamePort.get().pattern()) + .isEqualTo("foo/mgt/(info|info/.*|health|health/.*)"); + } + + @Test + public void should_return_endpoints_with_actuator_default_context_path() { + WebEndpointProperties webEndpointProperties = new WebEndpointProperties(); + ServerProperties properties = new ServerProperties(); + properties.getServlet().setContextPath("/foo"); + properties.setPort(8080); + + EndpointsSupplier endpointsSupplier = () -> { + ExposableWebEndpoint infoEndpoint = createEndpoint("info"); + ExposableWebEndpoint healthEndpoint = createEndpoint("health"); + + return Arrays.asList(infoEndpoint, healthEndpoint); + }; + + Optional patternDifferentPort = new TraceWebAutoConfiguration.ActuatorSkipPatternProviderConfig() + .skipPatternForActuatorEndpointsDifferentPort(properties, webEndpointProperties, endpointsSupplier) + .skipPattern(); + + then(patternDifferentPort).isNotEmpty(); + then(patternDifferentPort.get().pattern()).isEqualTo("/actuator/(info|info/.*|health|health/.*)"); + + Optional patternSamePort = new TraceWebAutoConfiguration.ActuatorSkipPatternProviderConfig() + .skipPatternForActuatorEndpointsSamePort(properties, webEndpointProperties, endpointsSupplier) + .skipPattern(); + + then(patternSamePort).isNotEmpty(); + then(patternSamePort.get().pattern()).isEqualTo("/foo/actuator/(info|info/.*|health|health/.*)"); + } + @Test public void should_combine_skip_patterns_from_list() throws Exception { TraceWebAutoConfiguration configuration = new TraceWebAutoConfiguration();