From c1648124f5065589e3eff2d92ee7b3c6339faa6c Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 10 Mar 2016 10:36:19 +0100 Subject: [PATCH] [#209] Skip pattern for Scheduled fixes #209 --- .../main/asciidoc/spring-cloud-sleuth.adoc | 20 +++++++++-- .../scheduling/TraceSchedulingAspect.java | 9 ++++- .../TraceSchedulingAutoConfiguration.java | 14 +++++--- .../web/TraceWebAutoConfiguration.java | 4 +-- .../scheduling/TracingOnScheduledTests.java | 34 +++++++++++++++++++ .../src/test/resources/application.yml | 4 ++- 6 files changed, 73 insertions(+), 12 deletions(-) diff --git a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc index 5b89d6969..1d473b3ec 100644 --- a/docs/src/main/asciidoc/spring-cloud-sleuth.adoc +++ b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc @@ -361,16 +361,30 @@ however will be still there. === Asynchronous communication +==== @Async annotated methods + In Spring Cloud Sleuth we're instrumenting async related components so that the tracing information is passed between threads. You can disable this behaviour by setting the value of `spring.sleuth.async.enabled` to `false`. -==== @Async / @Scheduled annotated methods - -If you annotate your method with `@Async` / `@Scheduled` then we'll automatically create a new Span with the following characteristics: +If you annotate your method with `@Async` then we'll automatically create a new Span with the following characteristics: - the Span name will be the annotated method name - the Span will be tagged with that method's class name and the method name too +==== @Scheduled annotated methods + +In Spring Cloud Sleuth we're instrumenting scheduled method execution so that the tracing information is passed between threads. You can disable this behaviour +by setting the value of `spring.sleuth.scheduled.enabled` to `false`. + +If you annotate your method with `@Scheduled` then we'll automatically create a new Span with the following characteristics: + + - the Span name will be the annotated method name + - the Span will be tagged with that method's class name and the method name too + +If you want to skip Span creation for some `@Scheduled` annotated classes you can set the +`spring.sleuth.scheduled.skipPattern` with a regular expression that will match the fully qualified name of the +`@Scheduled` annotated class. + ==== Executor, ExecutorService and ScheduledExecutorService We're providing `LazyTraceExecutor`, `TraceableExecutorService` and `TraceableScheduledExecutorService`. Those implementations diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java index 08f5ad422..6ac5c5daf 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAspect.java @@ -16,6 +16,8 @@ package org.springframework.cloud.sleuth.instrument.scheduling; +import java.util.regex.Pattern; + import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @@ -45,14 +47,19 @@ public class TraceSchedulingAspect { private final Tracer tracer; private final TraceKeys traceKeys; + private final Pattern skipPattern; - public TraceSchedulingAspect(Tracer tracer, TraceKeys traceKeys) { + public TraceSchedulingAspect(Tracer tracer, TraceKeys traceKeys, Pattern skipPattern) { this.tracer = tracer; this.traceKeys = traceKeys; + this.skipPattern = skipPattern; } @Around("execution (@org.springframework.scheduling.annotation.Scheduled * *.*(..))") public Object traceBackgroundThread(final ProceedingJoinPoint pjp) throws Throwable { + if (this.skipPattern.matcher(pjp.getTarget().getClass().getName()).matches()) { + return pjp.proceed(); + } String spanName = pjp.getSignature().getName(); Span span = this.tracer.createSpan(spanName); this.tracer.addTag(Span.SPAN_LOCAL_COMPONENT_TAG_NAME, SCHEDULED_COMPONENT); diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfiguration.java index f2c5e7272..396a6795d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/scheduling/TraceSchedulingAutoConfiguration.java @@ -16,11 +16,10 @@ package org.springframework.cloud.sleuth.instrument.scheduling; -/** - * @author Spencer Gibb - */ +import java.util.regex.Pattern; import org.aspectj.lang.ProceedingJoinPoint; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -43,15 +42,20 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy; */ @Configuration @EnableAspectJAutoProxy -@ConditionalOnProperty(value = "spring.sleuth.schedule.enabled", matchIfMissing = true) +@ConditionalOnProperty(value = "spring.sleuth.scheduled.enabled", matchIfMissing = true) @ConditionalOnBean(Tracer.class) @AutoConfigureAfter(TraceAutoConfiguration.class) public class TraceSchedulingAutoConfiguration { + /** + * Pattern for the fully qualified name of a class that should be skipped + */ + private @Value("${spring.sleuth.scheduled.skipPattern:}") String skipPattern; + @ConditionalOnClass(ProceedingJoinPoint.class) @Bean public TraceSchedulingAspect traceSchedulingAspect(Tracer tracer, TraceKeys traceKeys) { - return new TraceSchedulingAspect(tracer, traceKeys); + return new TraceSchedulingAspect(tracer, traceKeys, Pattern.compile(this.skipPattern)); } } 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 2c448fa67..5771182ea 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 @@ -61,7 +61,7 @@ public class TraceWebAutoConfiguration { /** * Pattern for URLs that should be skipped in tracing */ - @Value("${spring.sleuth.instrument.web.skipPattern:}") + @Value("${spring.sleuth.web.skipPattern:}") private String skipPattern; @Autowired @@ -94,7 +94,7 @@ public class TraceWebAutoConfiguration { /** * Pattern for URLs that should be skipped in tracing */ - @Value("${spring.sleuth.instrument.web.skipPattern:}") + @Value("${spring.sleuth.web.skipPattern:}") private String skipPattern; @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java index de7606bad..9ae6ac763 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java @@ -16,6 +16,9 @@ package org.springframework.cloud.sleuth.instrument.scheduling; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -37,6 +40,7 @@ import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; public class TracingOnScheduledTests { @Autowired TestBeanWithScheduledMethod beanWithScheduledMethod; + @Autowired TestBeanWithScheduledMethodToBeIgnored beanWithScheduledMethodToBeIgnored; @Test public void should_have_span_set_after_scheduled_method_has_been_executed() { @@ -49,6 +53,12 @@ public class TracingOnScheduledTests { await().until(differentSpanHasBeenSetThan(firstSpan)); } + @Test + public void should_not_span_in_the_scheduled_class_that_matches_skip_pattern() throws Exception { + await().untilAtomic(this.beanWithScheduledMethodToBeIgnored.isExecuted(), Matchers.is(true)); + then(this.beanWithScheduledMethodToBeIgnored.getSpan()).isNull(); + } + private Runnable spanIsSetOnAScheduledMethod() { return new Runnable() { @Override @@ -81,6 +91,10 @@ class ScheduledTestConfiguration { return new TestBeanWithScheduledMethod(); } + @Bean TestBeanWithScheduledMethodToBeIgnored testBeanWithScheduledMethodToBeIgnored() { + return new TestBeanWithScheduledMethodToBeIgnored(); + } + @Bean AlwaysSampler alwaysSampler() { return new AlwaysSampler(); @@ -101,3 +115,23 @@ class TestBeanWithScheduledMethod { return this.span; } } + +class TestBeanWithScheduledMethodToBeIgnored { + + Span span; + AtomicBoolean executed = new AtomicBoolean(false); + + @Scheduled(fixedDelay = 1L) + public void scheduledMethodToIgnore() { + this.span = TestSpanContextHolder.getCurrentSpan(); + this.executed.set(true); + } + + public Span getSpan() { + return this.span; + } + + public AtomicBoolean isExecuted() { + return this.executed; + } +} diff --git a/spring-cloud-sleuth-core/src/test/resources/application.yml b/spring-cloud-sleuth-core/src/test/resources/application.yml index d1791c3df..571531082 100644 --- a/spring-cloud-sleuth-core/src/test/resources/application.yml +++ b/spring-cloud-sleuth-core/src/test/resources/application.yml @@ -7,4 +7,6 @@ exceptionService.ribbon: MaxAutoRetries: 3 OkToRetryOnAllOperations: true ConnectTimeout: 1 - ReadTimeout: 1 \ No newline at end of file + ReadTimeout: 1 + +spring.sleuth.scheduled.skipPattern: "^org.*TestBeanWithScheduledMethodToBeIgnored$" \ No newline at end of file