Make SpanContextHolder package private

That way it can't leak back out into public classes, particularly
in intrumentation. Such use cases should use TraceAccessor or
Tracer exclusively.
This commit is contained in:
Dave Syer
2016-02-05 06:26:41 +00:00
parent ad97be2fa6
commit 9aeb399f7e
27 changed files with 289 additions and 129 deletions

View File

@@ -31,7 +31,7 @@ import org.springframework.cloud.sleuth.metric.CounterServiceBasedSpanReporterSe
import org.springframework.cloud.sleuth.metric.NoOpSpanReporterService;
import org.springframework.cloud.sleuth.metric.SleuthMetricProperties;
import org.springframework.cloud.sleuth.metric.SpanReporterService;
import org.springframework.cloud.sleuth.sampler.IsTracingSampler;
import org.springframework.cloud.sleuth.sampler.NeverSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
@@ -54,7 +54,7 @@ public class TraceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Sampler defaultTraceSampler() {
return new IsTracingSampler();
return NeverSampler.INSTANCE;
}
@Bean

View File

@@ -21,7 +21,7 @@ import java.util.Random;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.instrument.TraceKeys;
import org.springframework.cloud.sleuth.sampler.IsTracingSampler;
import org.springframework.cloud.sleuth.sampler.NeverSampler;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
@@ -54,7 +54,7 @@ public class TraceChannelInterceptor extends AbstractTraceChannelInterceptor {
return getTracer().joinTrace(name, span);
}
if (message.getHeaders().containsKey(Span.NOT_SAMPLED_NAME)) {
return getTracer().startTrace(name, IsTracingSampler.INSTANCE);
return getTracer().startTrace(name, NeverSampler.INSTANCE);
}
return getTracer().startTrace(name);
}

View File

@@ -35,7 +35,7 @@ import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.event.ServerReceivedEvent;
import org.springframework.cloud.sleuth.event.ServerSentEvent;
import org.springframework.cloud.sleuth.instrument.TraceKeys;
import org.springframework.cloud.sleuth.sampler.IsTracingSampler;
import org.springframework.cloud.sleuth.sampler.NeverSampler;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
@@ -156,7 +156,7 @@ public class TraceFilter extends OncePerRequestFilter
else {
if (skip) {
spanFromRequest = this.tracer.startTrace(name,
IsTracingSampler.INSTANCE);
NeverSampler.INSTANCE);
}
else {
spanFromRequest = this.tracer.startTrace(name);

View File

@@ -18,17 +18,22 @@ package org.springframework.cloud.sleuth.sampler;
import org.springframework.cloud.sleuth.Sampler;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.SpanAccessor;
/**
* @author Spencer Gibb
*/
public class IsTracingSampler implements Sampler {
public static IsTracingSampler INSTANCE = new IsTracingSampler();
private SpanAccessor accessor;
public IsTracingSampler(SpanAccessor accessor) {
super();
this.accessor = accessor;
}
@Override
public boolean isSampled(Span span) {
return SpanContextHolder.isTracing();
return this.accessor.isTracing();
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.sleuth.sampler;
import org.springframework.cloud.sleuth.Sampler;
import org.springframework.cloud.sleuth.Span;
/**
* @author Spencer Gibb
*/
public class NeverSampler implements Sampler {
public static NeverSampler INSTANCE = new NeverSampler();
@Override
public boolean isSampled(Span span) {
return false;
}
}

View File

@@ -22,35 +22,47 @@ import org.springframework.core.NamedThreadLocal;
import lombok.extern.apachecommons.CommonsLog;
/**
* Utility for managing the thread local state for the {@link DefaultTracer}.
*
* @author Spencer Gibb
* @author Dave Syer
*/
@CommonsLog
public class SpanContextHolder {
class SpanContextHolder {
private static final ThreadLocal<SpanContext> CURRENT_SPAN = new NamedThreadLocal<>(
"Trace Context");
public static Span getCurrentSpan() {
/**
* Get the current span out of the thread context
*/
static Span getCurrentSpan() {
return isTracing() ? CURRENT_SPAN.get().span : null;
}
public static void setCurrentSpan(Span span) {
// backwards compatibility
if (span == null) {
CURRENT_SPAN.remove();
return;
}
/**
* Set the current span in the thread context
*/
static void setCurrentSpan(Span span) {
if (log.isTraceEnabled()) {
log.trace("Setting current span " + span);
}
push(span, false);
}
public static void removeCurrentSpan() {
/**
* Remove all thread context relating to spans (useful for testing).
*
* @see #close() for a better alternative in instrumetation
*/
static void removeCurrentSpan() {
CURRENT_SPAN.remove();
}
public static boolean isTracing() {
/**
* Check if there is already a span in the current thread
*/
static boolean isTracing() {
return CURRENT_SPAN.get() != null;
}
@@ -71,6 +83,11 @@ public class SpanContextHolder {
}
}
/**
* Push a span into the thread context, with the option to have it auto close if any
* child spans are themselves closed. Use autoClose=true if you start a new span with
* a parent that wasn't already in thread context.
*/
static void push(Span span, boolean autoClose) {
if (isCurrent(span)) {
return;

View File

@@ -9,7 +9,7 @@ import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.ApplicationEventPublisher;
import java.util.Random;
@@ -28,7 +28,7 @@ public class TraceCallableTests {
@After
public void clean() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@Test
@@ -78,7 +78,7 @@ public class TraceCallableTests {
return new Callable<Span>() {
@Override
public Span call() throws Exception {
return SpanContextHolder.getCurrentSpan();
return TestSpanContextHolder.getCurrentSpan();
}
};
}

View File

@@ -9,7 +9,7 @@ import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.ApplicationEventPublisher;
import java.util.Random;
@@ -27,7 +27,7 @@ public class TraceRunnableTests {
@After
public void cleanup() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@Test
@@ -91,7 +91,7 @@ public class TraceRunnableTests {
@Override
public void run() {
this.span = SpanContextHolder.getCurrentSpan();
this.span = TestSpanContextHolder.getCurrentSpan();
}
}

View File

@@ -11,7 +11,7 @@ import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.ApplicationEventPublisher;
import java.util.ArrayList;
@@ -40,7 +40,7 @@ public class TraceableExecutorServiceTests {
public void setup() {
this.tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher);
this.traceManagerableExecutorService = new TraceableExecutorService(this.executorService, this.tracer);
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@After
@@ -48,7 +48,7 @@ public class TraceableExecutorServiceTests {
this.tracer = null;
this.traceManagerableExecutorService.shutdown();
this.executorService.shutdown();
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@Test
@@ -77,7 +77,7 @@ public class TraceableExecutorServiceTests {
@Override
public void run() {
Span span = SpanContextHolder.getCurrentSpan();
Span span = TestSpanContextHolder.getCurrentSpan();
this.traceIds.add(span.getTraceId());
this.spanIds.add(span.getSpanId());
}

View File

@@ -14,7 +14,7 @@ import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
@@ -36,7 +36,7 @@ public class HystrixAnnotationsIntegrationTests {
@After
public void cleanTrace() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@Test
@@ -92,7 +92,7 @@ public class HystrixAnnotationsIntegrationTests {
@HystrixCommand
public void invokeLogicWrappedInHystrixCommand() {
this.spanCaughtFromHystrixThread = new AtomicReference<>(
SpanContextHolder.getCurrentSpan());
TestSpanContextHolder.getCurrentSpan());
}
public Long getTraceId() {

View File

@@ -14,7 +14,7 @@ import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.ApplicationEventPublisher;
import com.netflix.hystrix.HystrixCommandProperties;
@@ -28,12 +28,12 @@ public class TraceCommandTests {
@Before
public void setup() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@After
public void cleanup() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@Test
@@ -74,7 +74,7 @@ public class TraceCommandTests {
.withExecutionTimeoutEnabled(false))) {
@Override
public Span doRun() throws Exception {
return SpanContextHolder.getCurrentSpan();
return TestSpanContextHolder.getCurrentSpan();
}
};
}

View File

@@ -39,7 +39,7 @@ import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.event.SpanReleasedEvent;
import org.springframework.cloud.sleuth.instrument.integration.TraceChannelInterceptorTests.App;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
@@ -81,7 +81,7 @@ public class TraceChannelInterceptorTests implements MessageHandler {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
this.message = message;
this.span = SpanContextHolder.getCurrentSpan();
this.span = TestSpanContextHolder.getCurrentSpan();
}
@Before
@@ -91,7 +91,7 @@ public class TraceChannelInterceptorTests implements MessageHandler {
@After
public void close() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
this.channel.unsubscribe(this);
}
@@ -103,7 +103,7 @@ public class TraceChannelInterceptorTests implements MessageHandler {
String spanId = this.message.getHeaders().get(Span.SPAN_ID_NAME, String.class);
assertNotNull("spanId was null", spanId);
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
assertFalse(this.span.isExportable());
}
@@ -133,7 +133,7 @@ public class TraceChannelInterceptorTests implements MessageHandler {
String traceId = this.message.getHeaders().get(Span.TRACE_ID_NAME, String.class);
assertNotNull("traceId was null", traceId);
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
@Test
@@ -148,7 +148,7 @@ public class TraceChannelInterceptorTests implements MessageHandler {
String traceId = this.message.getHeaders().get(Span.TRACE_ID_NAME, String.class);
assertNotNull("traceId was null", traceId);
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
// TODO: Refactor to parametrized test together with sending messages via channel
@@ -164,7 +164,7 @@ public class TraceChannelInterceptorTests implements MessageHandler {
String traceId = this.message.getHeaders().get(Span.TRACE_ID_NAME, String.class);
assertNotNull("traceId was null", traceId);
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
@Configuration

View File

@@ -28,7 +28,7 @@ import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.instrument.integration.TraceContextPropagationChannelInterceptorTests.App;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.channel.QueueChannel;
@@ -59,7 +59,7 @@ public class TraceContextPropagationChannelInterceptorTests {
@After
public void close() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@Test

View File

@@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
@@ -70,7 +70,7 @@ class TestBeanWithScheduledMethod {
@Scheduled(fixedDelay = 1L)
public void scheduledMethod() {
this.span = SpanContextHolder.getCurrentSpan();
this.span = TestSpanContextHolder.getCurrentSpan();
}
public Span getSpan() {

View File

@@ -10,7 +10,7 @@ import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
@@ -61,7 +61,7 @@ public class TraceAsyncIntegrationTests {
@After
public void cleanTrace() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@DefaultTestAutoConfiguration
@@ -82,7 +82,7 @@ public class TraceAsyncIntegrationTests {
@Async
public void invokeAsynchronousLogic() {
this.span.set(SpanContextHolder.getCurrentSpan());
this.span.set(TestSpanContextHolder.getCurrentSpan());
}
public Long getTraceId() {

View File

@@ -24,7 +24,7 @@ import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.instrument.TraceKeys;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockFilterChain;
@@ -57,7 +57,7 @@ public class TraceFilterMockChainIntegrationTests {
@Before
@SneakyThrows
public void init() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
this.context.refresh();
this.request = builder().buildRequest(new MockServletContext());
this.response = new MockHttpServletResponse();
@@ -74,7 +74,7 @@ public class TraceFilterMockChainIntegrationTests {
public void startsNewTrace() throws Exception {
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
filter.doFilter(this.request, this.response, this.filterChain);
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
@Test
@@ -84,7 +84,7 @@ public class TraceFilterMockChainIntegrationTests {
.header(Span.TRACE_ID_NAME, generator.nextLong()).buildRequest(new MockServletContext());
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
filter.doFilter(this.request, this.response, this.filterChain);
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
}

View File

@@ -34,9 +34,9 @@ import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.instrument.TraceKeys;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.sampler.IsTracingSampler;
import org.springframework.cloud.sleuth.sampler.NeverSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@@ -91,7 +91,7 @@ public class TraceFilterTests {
@Test
public void notTraced() throws Exception {
this.sampler = new IsTracingSampler();
this.sampler = NeverSampler.INSTANCE;
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
this.request = get("/favicon.ico").accept(MediaType.ALL)
@@ -100,7 +100,7 @@ public class TraceFilterTests {
filter.doFilter(this.request, this.response, this.filterChain);
assertFalse(this.span.isExportable());
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
@Test
@@ -108,7 +108,7 @@ public class TraceFilterTests {
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
filter.doFilter(this.request, this.response, this.filterChain);
verifyHttpTags();
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
@Test
@@ -117,14 +117,14 @@ public class TraceFilterTests {
Span span = this.tracer.startTrace("foo");
this.request.setAttribute(TraceFilter.TRACE_REQUEST_ATTR, span);
// It should have been removed from the thread local context so simulate that
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys);
filter.doFilter(this.request, this.response, this.filterChain);
verifyHttpTags();
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
@Test
@@ -137,7 +137,7 @@ public class TraceFilterTests {
verifyHttpTags();
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
@Test
@@ -152,7 +152,7 @@ public class TraceFilterTests {
assertThat(this.span.tags()).contains(entry("http.x-foo", "bar"));
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
@Test
@@ -168,7 +168,7 @@ public class TraceFilterTests {
assertThat(this.span.tags()).contains(entry("http.x-foo", "'bar','spam'"));
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
@Test
@@ -190,7 +190,7 @@ public class TraceFilterTests {
}
verifyHttpTags(HttpStatus.INTERNAL_SERVER_ERROR);
assertNull(SpanContextHolder.getCurrentSpan());
assertNull(TestSpanContextHolder.getCurrentSpan());
}
public void verifyHttpTags() {

View File

@@ -24,7 +24,7 @@ import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
import org.springframework.cloud.sleuth.event.ClientSentEvent;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -60,7 +60,7 @@ public class FeignTraceTests {
@After
public void close() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
this.listener.getEvents().clear();
}

View File

@@ -30,7 +30,7 @@ import org.junit.Test;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.client.ClientHttpRequestInterceptor;
@@ -64,12 +64,12 @@ public class TraceRestTemplateInterceptorTests {
this.traces = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher);
this.template.setInterceptors(Arrays.<ClientHttpRequestInterceptor>asList(
new TraceRestTemplateInterceptor(this.traces)));
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@After
public void clean() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@Test

View File

@@ -28,7 +28,7 @@ import org.mockito.Mockito;
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.ApplicationEventPublisher;
import com.netflix.zuul.context.RequestContext;
@@ -49,7 +49,7 @@ public class TracePostZuulFilterTests {
@Before
public void clean() {
RequestContext.getCurrentContext().unset();
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@Test

View File

@@ -29,9 +29,9 @@ import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.sampler.IsTracingSampler;
import org.springframework.cloud.sleuth.sampler.NeverSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.ApplicationEventPublisher;
import com.netflix.zuul.context.RequestContext;
@@ -42,9 +42,11 @@ import com.netflix.zuul.context.RequestContext;
*/
public class TracePreZuulFilterTests {
private ApplicationEventPublisher publisher = Mockito.mock(ApplicationEventPublisher.class);
private ApplicationEventPublisher publisher = Mockito
.mock(ApplicationEventPublisher.class);
private DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher);
private DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(),
this.publisher);
private TracePreZuulFilter filter = new TracePreZuulFilter(this.tracer);
@@ -52,7 +54,7 @@ public class TracePreZuulFilterTests {
@Before
public void clean() {
RequestContext.getCurrentContext().unset();
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@Test
@@ -60,17 +62,21 @@ public class TracePreZuulFilterTests {
this.tracer.startTrace("start");
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertThat(ctx.getZuulRequestHeaders().get(Span.TRACE_ID_NAME), is(notNullValue()));
assertThat(ctx.getZuulRequestHeaders().get(Span.NOT_SAMPLED_NAME), is(nullValue()));
assertThat(ctx.getZuulRequestHeaders().get(Span.TRACE_ID_NAME),
is(notNullValue()));
assertThat(ctx.getZuulRequestHeaders().get(Span.NOT_SAMPLED_NAME),
is(nullValue()));
}
@Test
public void notSampledIfNotExportable() throws Exception {
this.tracer.startTrace("start", new IsTracingSampler());
this.tracer.startTrace("start", NeverSampler.INSTANCE);
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertThat(ctx.getZuulRequestHeaders().get(Span.TRACE_ID_NAME), is(notNullValue()));
assertThat(ctx.getZuulRequestHeaders().get(Span.NOT_SAMPLED_NAME), is(notNullValue()));
assertThat(ctx.getZuulRequestHeaders().get(Span.TRACE_ID_NAME),
is(notNullValue()));
assertThat(ctx.getZuulRequestHeaders().get(Span.NOT_SAMPLED_NAME),
is(notNullValue()));
}
}

View File

@@ -7,7 +7,7 @@ import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import org.springframework.context.ApplicationEventPublisher;
import java.util.Random;
@@ -21,7 +21,7 @@ public class TraceTemplateTests {
@After
public void close() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@Test
@@ -39,7 +39,7 @@ public class TraceTemplateTests {
return traceTemplate.trace(new TraceCallback<Span>() {
@Override
public Span doInTrace(Span span) {
return SpanContextHolder.getCurrentSpan();
return TestSpanContextHolder.getCurrentSpan();
}
});
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.sleuth;
package org.springframework.cloud.sleuth.trace;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.is;
@@ -33,12 +33,12 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.event.SpanAcquiredEvent;
import org.springframework.cloud.sleuth.event.SpanReleasedEvent;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.sampler.IsTracingSampler;
import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.cloud.sleuth.sampler.NeverSampler;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
@@ -55,19 +55,20 @@ public class DefaultTracerTests {
@Before
public void setup() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
this.publisher = mock(ApplicationEventPublisher.class);
}
@After
public void clean() {
SpanContextHolder.removeCurrentSpan();
TestSpanContextHolder.removeCurrentSpan();
}
@Test
public void tracingWorks() {
DefaultTracer tracer = new DefaultTracer(new IsTracingSampler(), new Random(), this.publisher);
DefaultTracer tracer = new DefaultTracer(NeverSampler.INSTANCE, new Random(),
this.publisher);
Span span = tracer.startTrace(CREATE_SIMPLE_TRACE, new AlwaysSampler());
try {
@@ -77,8 +78,10 @@ public class DefaultTracerTests {
tracer.close(span);
}
verify(this.publisher, times(NUM_SPANS)).publishEvent(isA(SpanAcquiredEvent.class));
verify(this.publisher, times(NUM_SPANS)).publishEvent(isA(SpanReleasedEvent.class));
verify(this.publisher, times(NUM_SPANS))
.publishEvent(isA(SpanAcquiredEvent.class));
verify(this.publisher, times(NUM_SPANS))
.publishEvent(isA(SpanReleasedEvent.class));
ArgumentCaptor<ApplicationEvent> captor = ArgumentCaptor
.forClass(ApplicationEvent.class);
@@ -103,22 +106,25 @@ public class DefaultTracerTests {
@Test
public void nonExportable() {
DefaultTracer tracer = new DefaultTracer(new IsTracingSampler(), new Random(), this.publisher);
DefaultTracer tracer = new DefaultTracer(NeverSampler.INSTANCE, new Random(),
this.publisher);
Span span = tracer.startTrace(CREATE_SIMPLE_TRACE);
assertThat(span.isExportable(), is(false));
}
@Test
public void exportable() {
DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher);
DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(),
this.publisher);
Span span = tracer.startTrace(CREATE_SIMPLE_TRACE);
assertThat(span.isExportable(), is(true));
}
@Test
public void exportableInheritedFromParent() {
DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher);
Span span = tracer.startTrace(CREATE_SIMPLE_TRACE, new IsTracingSampler());
DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(),
this.publisher);
Span span = tracer.startTrace(CREATE_SIMPLE_TRACE, NeverSampler.INSTANCE);
assertThat(span.isExportable(), is(false));
Span child = tracer.joinTrace(CREATE_SIMPLE_TRACE + "/child", span);
assertThat(child.isExportable(), is(false));
@@ -126,7 +132,8 @@ public class DefaultTracerTests {
@Test
public void parentNotRemovedIfActiveOnJoin() {
DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher);
DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(),
this.publisher);
Span parent = tracer.startTrace(CREATE_SIMPLE_TRACE);
Span span = tracer.joinTrace(IMPORTANT_WORK_1, parent);
tracer.close(span);
@@ -135,8 +142,10 @@ public class DefaultTracerTests {
@Test
public void parentRemovedIfNotActiveOnJoin() {
DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher);
Span parent = Span.builder().name(CREATE_SIMPLE_TRACE).traceId(1L).spanId(1L).build();
DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(),
this.publisher);
Span parent = Span.builder().name(CREATE_SIMPLE_TRACE).traceId(1L).spanId(1L)
.build();
Span span = tracer.joinTrace(IMPORTANT_WORK_1, parent);
tracer.close(span);
assertThat(tracer.getCurrentSpan(), is(equalTo(null)));
@@ -144,9 +153,11 @@ public class DefaultTracerTests {
@Test
public void grandParentRestoredAfterAutoClose() {
DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher);
DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(),
this.publisher);
Span grandParent = tracer.startTrace(CREATE_SIMPLE_TRACE);
Span parent = Span.builder().name(IMPORTANT_WORK_1).traceId(1L).spanId(1L).build();
Span parent = Span.builder().name(IMPORTANT_WORK_1).traceId(1L).spanId(1L)
.build();
Span span = tracer.joinTrace(IMPORTANT_WORK_2, parent);
tracer.close(span);
assertThat(tracer.getCurrentSpan(), is(equalTo(grandParent)));
@@ -156,8 +167,8 @@ public class DefaultTracerTests {
List<Span> found = findSpans(spans, parentId);
assertThat("more than one span with parentId " + parentId, found.size(), is(1));
Span span = found.get(0);
assertThat("name is wrong for span with parentId " + parentId,
span.getName(), is(name));
assertThat("name is wrong for span with parentId " + parentId, span.getName(),
is(name));
return span;
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.sleuth.trace;
import org.springframework.cloud.sleuth.Span;
/**
* Test utility to access the thread context provided by the (private)
* {@link SpanContextHolder}.
*
* @author Dave Syer
*/
public class TestSpanContextHolder {
public static Span getCurrentSpan() {
return SpanContextHolder.getCurrentSpan();
}
public static void removeCurrentSpan() {
SpanContextHolder.removeCurrentSpan();
}
public static boolean isTracing() {
return SpanContextHolder.isTracing();
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.sleuth.trace;
import org.springframework.cloud.sleuth.Span;
/**
* @author Spencer Gibb
*/
public class IntegrationTestSpanContextHolder {
public static Span getCurrentSpan() {
return SpanContextHolder.getCurrentSpan();
}
public static void removeCurrentSpan() {
SpanContextHolder.removeCurrentSpan();
}
public static boolean isTracing() {
return SpanContextHolder.isTracing();
}
}

View File

@@ -15,24 +15,34 @@
*/
package tools;
import com.jayway.awaitility.Awaitility;
import com.jayway.awaitility.core.ConditionFactory;
import lombok.extern.slf4j.Slf4j;
import org.junit.After;
import org.junit.Before;
import org.springframework.cloud.sleuth.trace.SpanContextHolder;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import zipkin.Codec;
import zipkin.Span;
import java.net.URI;
import java.util.*;
import java.util.stream.Collectors;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.assertj.core.api.BDDAssertions.then;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.junit.After;
import org.junit.Before;
import org.springframework.cloud.sleuth.trace.IntegrationTestSpanContextHolder;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import com.jayway.awaitility.Awaitility;
import com.jayway.awaitility.core.ConditionFactory;
import lombok.extern.slf4j.Slf4j;
import zipkin.Codec;
import zipkin.Span;
/**
* @author Marcin Grzejszczak
*/
@@ -45,12 +55,12 @@ public abstract class AbstractIntegrationTest {
@Before
public void clearSpanBefore() {
SpanContextHolder.removeCurrentSpan();
IntegrationTestSpanContextHolder.removeCurrentSpan();
}
@After
public void clearSpanAfter() {
SpanContextHolder.removeCurrentSpan();
IntegrationTestSpanContextHolder.removeCurrentSpan();
}
public static ConditionFactory await() {

View File

@@ -15,7 +15,11 @@
*/
package tools;
import lombok.extern.slf4j.Slf4j;
import static org.assertj.core.api.BDDAssertions.then;
import java.net.URI;
import java.util.Random;
import org.springframework.cloud.sleuth.Span;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
@@ -24,10 +28,7 @@ import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.util.Random;
import static org.assertj.core.api.BDDAssertions.then;
import lombok.extern.slf4j.Slf4j;
/**
* Runnable that will send a request via the provide rest template to the
@@ -60,12 +61,12 @@ public class RequestSendingRunnable implements Runnable {
log.info("Received the following response [{}]", responseEntity);
}
private RequestEntity requestWithTraceId() {
private RequestEntity<Void> requestWithTraceId() {
HttpHeaders headers = new HttpHeaders();
headers.add(Span.TRACE_ID_NAME, Span.toHex(this.traceId));
headers.add(Span.SPAN_ID_NAME, Span.toHex(this.spanId));
URI uri = URI.create(this.url);
RequestEntity requestEntity = new RequestEntity<>(headers, HttpMethod.GET, uri);
RequestEntity<Void> requestEntity = new RequestEntity<>(headers, HttpMethod.GET, uri);
log.info("Request [" + requestEntity + "] is ready");
return requestEntity;
}