Merge pull request #210 from spring-cloud/issues_#209_configurable_scheduled

[#209] Skip pattern for Scheduled
This commit is contained in:
Marcin Grzejszczak
2016-03-10 12:09:06 +01:00
6 changed files with 73 additions and 12 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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));
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -7,4 +7,6 @@ exceptionService.ribbon:
MaxAutoRetries: 3
OkToRetryOnAllOperations: true
ConnectTimeout: 1
ReadTimeout: 1
ReadTimeout: 1
spring.sleuth.scheduled.skipPattern: "^org.*TestBeanWithScheduledMethodToBeIgnored$"