From 0c42fcb809782a4b644ba9bc9d16d36b8d8c96a9 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 22 Feb 2018 14:42:58 +0100 Subject: [PATCH] Add an option to provide additional sleuth skip patterns through configuration without this change you always have to set the skip pattern. You can't append anything to the default pattern with this change via the property you can provide some additional skip patterns fixes gh-865 --- .../main/asciidoc/spring-cloud-sleuth.adoc | 12 +++-- .../instrument/web/SleuthWebProperties.java | 14 ++++++ .../web/TraceWebAutoConfiguration.java | 33 +++++++++---- .../web/SkipPatternProviderConfigTest.java | 48 +++++++++++++++++++ 4 files changed, 94 insertions(+), 13 deletions(-) diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc index c8424392a..8af6ec017 100644 --- a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc +++ b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc @@ -1012,7 +1012,9 @@ Features from this section can be disabled by providing the `spring.sleuth.web.e Via the `TraceFilter` all sampled incoming requests result in creation of a Span. That Span's name is `http:` + the path to which the request was sent. E.g. if the request was sent to `/foo/bar` then the name will be `http:/foo/bar`. You can configure which URIs you would like to skip via the `spring.sleuth.web.skipPattern` property. If you have `ManagementServerProperties` on classpath then - its value of `contextPath` gets appended to the provided skip pattern. + its value of `contextPath` gets appended to the provided skip pattern. If you want to reuse the + Sleuth's default skip patterns and just append your own, pass those patterns via + the `spring.sleuth.web.additionalSkipPattern`. ==== HandlerInterceptor @@ -1032,7 +1034,9 @@ If your controller returns a `Callable` or a `WebAsyncTask` Spring Cloud Sleuth Via the `TraceWebFilter` all sampled incoming requests result in creation of a Span. That Span's name is `http:` + the path to which the request was sent. E.g. if the request was sent to `/foo/bar` then the name will be `http:/foo/bar`. You can configure which URIs you would like to skip via the `spring.sleuth.web.skipPattern` property. If you have `ManagementServerProperties` on classpath then - its value of `contextPath` gets appended to the provided skip pattern. + its value of `contextPath` gets appended to the provided skip pattern. If you want to reuse the + Sleuth's default skip patterns and just append your own, pass those patterns via + the `spring.sleuth.web.additionalSkipPattern`. === HTTP client integration @@ -1125,7 +1129,9 @@ If you want to skip Span creation for some `@Scheduled` annotated classes you ca `spring.sleuth.scheduled.skipPattern` with a regular expression that will match the fully qualified name of the `@Scheduled` annotated class. -TIP: If you are using `spring-cloud-sleuth-stream` and `spring-cloud-netflix-hystrix-stream` together, Span will be created for each Hystrix metrics and sent to Zipkin. This may be annoying. You can prevent this by setting `spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask` +TIP: If you are using `spring-cloud-sleuth-stream` and `spring-cloud-netflix-hystrix-stream` together, Span will be created for +each Hystrix metrics and sent to Zipkin. This may be annoying. You can prevent this by setting +`spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask` ==== Executor, ExecutorService and ScheduledExecutorService diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthWebProperties.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthWebProperties.java index 9020ab332..96cd13900 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthWebProperties.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/SleuthWebProperties.java @@ -41,6 +41,12 @@ public class SleuthWebProperties { */ private String skipPattern = DEFAULT_SKIP_PATTERN; + /** + * Additional pattern for URLs that should be skipped in tracing. + * This will be appended to the {@link SleuthWebProperties#skipPattern} + */ + private String additionalSkipPattern; + private Client client; public boolean isEnabled() { @@ -59,6 +65,14 @@ public class SleuthWebProperties { this.skipPattern = skipPattern; } + public String getAdditionalSkipPattern() { + return this.additionalSkipPattern; + } + + public void setAdditionalSkipPattern(String additionalSkipPattern) { + this.additionalSkipPattern = additionalSkipPattern; + } + public Client getClient() { return this.client; } 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 45c3426ef..4277dfda8 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 @@ -77,21 +77,23 @@ public class TraceWebAutoConfiguration { ManagementServerProperties managementServerProperties, SleuthWebProperties sleuthWebProperties) { String skipPattern = sleuthWebProperties.getSkipPattern(); + String additionalSkipPattern = sleuthWebProperties.getAdditionalSkipPattern(); String contextPath = managementServerProperties.getServlet().getContextPath(); if (StringUtils.hasText(skipPattern) && StringUtils.hasText(contextPath)) { - return Pattern.compile(skipPattern + "|" + contextPath + ".*"); + return Pattern.compile(combinedPattern(skipPattern + "|" + contextPath + ".*", additionalSkipPattern)); } else if (StringUtils.hasText(contextPath)) { - return Pattern.compile(contextPath + ".*"); + return Pattern.compile(combinedPattern(contextPath + ".*", additionalSkipPattern)); } - return defaultSkipPattern(skipPattern); + return defaultSkipPattern(skipPattern, additionalSkipPattern); } @Bean @ConditionalOnMissingBean(ManagementServerProperties.class) public SkipPatternProvider defaultSkipPatternBeanIfManagementServerPropsArePresent(SleuthWebProperties sleuthWebProperties) { - return defaultSkipPatternProvider(sleuthWebProperties.getSkipPattern()); + return defaultSkipPatternProvider(sleuthWebProperties.getSkipPattern(), + sleuthWebProperties.getAdditionalSkipPattern()); } } @@ -100,17 +102,28 @@ public class TraceWebAutoConfiguration { @ConditionalOnMissingBean( SkipPatternProvider.class) public SkipPatternProvider defaultSkipPatternBean(SleuthWebProperties sleuthWebProperties) { - return defaultSkipPatternProvider(sleuthWebProperties.getSkipPattern()); + return defaultSkipPatternProvider(sleuthWebProperties.getSkipPattern(), + sleuthWebProperties.getAdditionalSkipPattern()); } private static SkipPatternProvider defaultSkipPatternProvider( - final String skipPattern) { - return () -> defaultSkipPattern(skipPattern); + final String skipPattern, final String additionalSkipPattern) { + return () -> defaultSkipPattern(skipPattern, additionalSkipPattern); } - private static Pattern defaultSkipPattern(String skipPattern) { - return StringUtils.hasText(skipPattern) ? Pattern.compile(skipPattern) - : Pattern.compile(SleuthWebProperties.DEFAULT_SKIP_PATTERN); + private static Pattern defaultSkipPattern(String skipPattern, String additionalSkipPattern) { + return Pattern.compile(combinedPattern(skipPattern, additionalSkipPattern)); + } + + private static String combinedPattern(String skipPattern, String additionalSkipPattern) { + String pattern = skipPattern; + if (!StringUtils.hasText(skipPattern)) { + pattern = SleuthWebProperties.DEFAULT_SKIP_PATTERN; + } + if (StringUtils.hasText(additionalSkipPattern)) { + return pattern + "|" + additionalSkipPattern; + } + return pattern; } } 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 8df05463d..7df40583b 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 @@ -38,6 +38,17 @@ public class SkipPatternProviderConfigTest { then(pattern.pattern()).isEqualTo("foo.*|bar.*|/management/context.*"); } + @Test + public void should_combine_skip_pattern_management_context_and_additional_pattern_when_all_are_not_empty() throws Exception { + SleuthWebProperties sleuthWebProperties = new SleuthWebProperties(); + sleuthWebProperties.setSkipPattern("foo.*|bar.*"); + sleuthWebProperties.setAdditionalSkipPattern("baz.*|faz.*"); + Pattern pattern = TraceWebAutoConfiguration.SkipPatternProviderConfig.getPatternForManagementServerProperties( + managementServerPropertiesWithContextPath(), sleuthWebProperties); + + then(pattern.pattern()).isEqualTo("foo.*|bar.*|/management/context.*|baz.*|faz.*"); + } + @Test public void should_pick_skip_pattern_when_its_not_empty_and_management_context_is_empty() throws Exception { SleuthWebProperties sleuthWebProperties = new SleuthWebProperties(); @@ -48,6 +59,17 @@ public class SkipPatternProviderConfigTest { then(pattern.pattern()).isEqualTo("foo.*|bar.*"); } + @Test + public void should_pick_skip_pattern_and_additional_pattern_when_its_not_empty_and_management_context_is_empty() throws Exception { + SleuthWebProperties sleuthWebProperties = new SleuthWebProperties(); + sleuthWebProperties.setSkipPattern("foo.*|bar.*"); + sleuthWebProperties.setAdditionalSkipPattern("baz.*|faz.*"); + + Pattern pattern = TraceWebAutoConfiguration.SkipPatternProviderConfig.getPatternForManagementServerProperties(new ManagementServerProperties(), sleuthWebProperties); + + then(pattern.pattern()).isEqualTo("foo.*|bar.*|baz.*|faz.*"); + } + @Test public void should_pick_management_context_when_skip_patterns_is_empty_and_context_path_is_not() throws Exception { SleuthWebProperties sleuthWebProperties = new SleuthWebProperties(); @@ -59,6 +81,18 @@ public class SkipPatternProviderConfigTest { then(pattern.pattern()).isEqualTo("/management/context.*"); } + @Test + public void should_pick_management_context_and_additional_pattern_when_skip_patterns_is_empty_and_context_path_is_not() throws Exception { + SleuthWebProperties sleuthWebProperties = new SleuthWebProperties(); + sleuthWebProperties.setSkipPattern(""); + sleuthWebProperties.setAdditionalSkipPattern("baz.*|faz.*"); + + Pattern pattern = TraceWebAutoConfiguration.SkipPatternProviderConfig.getPatternForManagementServerProperties( + managementServerPropertiesWithContextPath(), sleuthWebProperties); + + then(pattern.pattern()).isEqualTo("/management/context.*|baz.*|faz.*"); + } + @Test public void should_pick_default_pattern_when_both_management_context_and_skip_patterns_are_empty() throws Exception { SleuthWebProperties sleuthWebProperties = new SleuthWebProperties(); @@ -72,6 +106,20 @@ public class SkipPatternProviderConfigTest { then(pattern.pattern()).isEqualTo(SleuthWebProperties.DEFAULT_SKIP_PATTERN); } + @Test + public void should_pick_default_pattern_with_additional_pattern_when_both_management_context_and_skip_patterns_are_empty() throws Exception { + SleuthWebProperties sleuthWebProperties = new SleuthWebProperties(); + sleuthWebProperties.setSkipPattern(""); + sleuthWebProperties.setAdditionalSkipPattern("baz.*|faz.*"); + ManagementServerProperties managementServerProperties = new ManagementServerProperties(); + managementServerProperties.getServlet().setContextPath(""); + + Pattern pattern = TraceWebAutoConfiguration.SkipPatternProviderConfig.getPatternForManagementServerProperties( + managementServerProperties, sleuthWebProperties); + + then(pattern.pattern()).isEqualTo(SleuthWebProperties.DEFAULT_SKIP_PATTERN + "|baz.*|faz.*"); + } + private ManagementServerProperties managementServerPropertiesWithContextPath() { ManagementServerProperties managementServerProperties = new ManagementServerProperties(); managementServerProperties.getServlet().setContextPath("/management/context");