Simplfy some of the core API interfaces and add javadocs
This commit is contained in:
@@ -20,50 +20,50 @@ public class MilliSpan implements Span {
|
||||
@NonFinal
|
||||
private long end = 0;
|
||||
private String name;
|
||||
private String traceId;
|
||||
private final String traceId;
|
||||
@Singular
|
||||
private List<String> parents;
|
||||
private String spanId;
|
||||
private final String spanId;
|
||||
private Map<String, String> kVAnnotations = new LinkedHashMap<>();
|
||||
private String processId;
|
||||
private final String processId;
|
||||
@Singular
|
||||
private List<TimelineAnnotation> timelineAnnotations = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public synchronized void stop() {
|
||||
if (end == 0) {
|
||||
if (begin == 0) {
|
||||
throw new IllegalStateException("Span for " + name
|
||||
if (this.end == 0) {
|
||||
if (this.begin == 0) {
|
||||
throw new IllegalStateException("Span for " + this.name
|
||||
+ " has not been started");
|
||||
}
|
||||
end = System.currentTimeMillis();
|
||||
this.end = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long getAccumulatedMillis() {
|
||||
if (begin == 0) {
|
||||
if (this.begin == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (end > 0) {
|
||||
return end - begin;
|
||||
if (this.end > 0) {
|
||||
return this.end - this.begin;
|
||||
}
|
||||
return System.currentTimeMillis() - begin;
|
||||
return System.currentTimeMillis() - this.begin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isRunning() {
|
||||
return begin != 0 && end == 0;
|
||||
return this.begin != 0 && this.end == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addKVAnnotation(String key, String value) {
|
||||
kVAnnotations.put(key, value);
|
||||
this.kVAnnotations.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTimelineAnnotation(String msg) {
|
||||
timelineAnnotations.add(new TimelineAnnotation(System.currentTimeMillis(), msg));
|
||||
this.timelineAnnotations.add(new TimelineAnnotation(System.currentTimeMillis(), msg));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ public final class NullScope extends TraceScope {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Span detach() {
|
||||
public SpanIdentifiers detach() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.Map;
|
||||
* to keep following the parents of a span until you arrive at a span with no
|
||||
* parents.<p/>
|
||||
*/
|
||||
public interface Span {
|
||||
public interface Span extends SpanIdentifiers {
|
||||
/**
|
||||
* The block has completed, stop the clock
|
||||
*/
|
||||
@@ -45,20 +45,6 @@ public interface Span {
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* A pseudo-unique (random) number assigned to this span instance.<p/>
|
||||
* <p/>
|
||||
* The spanId is immutable and cannot be changed. It is safe to access this
|
||||
* from multiple threads.
|
||||
*/
|
||||
String getSpanId();
|
||||
|
||||
/**
|
||||
* A pseudo-unique (random) number assigned to the trace associated with this
|
||||
* span
|
||||
*/
|
||||
String getTraceId();
|
||||
|
||||
/**
|
||||
* Returns the parent IDs of the span.<p/>
|
||||
* <p/>
|
||||
@@ -89,11 +75,4 @@ public interface Span {
|
||||
* Will never be null.
|
||||
*/
|
||||
List<TimelineAnnotation> getTimelineAnnotations();
|
||||
|
||||
/**
|
||||
* Return a unique id for the process from which this Span originated.<p/>
|
||||
* <p/>
|
||||
* Will never be null.
|
||||
*/
|
||||
String getProcessId();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 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;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public interface SpanIdentifiers {
|
||||
|
||||
/**
|
||||
* A pseudo-unique (random) number assigned to this span instance.<p/>
|
||||
* <p/>
|
||||
* The spanId is immutable and cannot be changed. It is safe to access this
|
||||
* from multiple threads.
|
||||
*/
|
||||
String getSpanId();
|
||||
|
||||
/**
|
||||
* A pseudo-unique (random) number assigned to the trace associated with this
|
||||
* span
|
||||
*/
|
||||
String getTraceId();
|
||||
|
||||
/**
|
||||
* Return a unique id for the process from which this Span originated.<p/>
|
||||
* <p/>
|
||||
* Will never be null.
|
||||
*/
|
||||
String getProcessId();
|
||||
|
||||
}
|
||||
@@ -3,36 +3,34 @@ package org.springframework.cloud.sleuth;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* The Trace class is the primary way to interact with the library. It provides
|
||||
* methods to create and manipulate spans.
|
||||
* The Trace class is the primary way to interact with the library. It provides methods to
|
||||
* create and manipulate spans.
|
||||
*
|
||||
* A 'Span' represents a length of time. It has many other attributes such as a
|
||||
* name, ID, and even potentially a set of key/value strings attached to
|
||||
* it.
|
||||
* A 'Span' represents a length of time. It has many other attributes such as a name, ID,
|
||||
* and even potentially a set of key/value strings attached to it.
|
||||
*
|
||||
* Each thread in your application has a single currently active currentSpan
|
||||
* associated with it. When this is non-null, it represents the current
|
||||
* operation that the thread is doing. Spans are NOT thread-safe, and must
|
||||
* never be used by multiple threads at once. With care, it is possible to
|
||||
* safely pass a Span object between threads, but in most cases this is not
|
||||
* necessary.
|
||||
* Each thread in your application has a single currently active currentSpan associated
|
||||
* with it. When this is non-null, it represents the current operation that the thread is
|
||||
* doing. Spans are NOT thread-safe, and must never be used by multiple threads at once.
|
||||
* With care, it is possible to safely pass a Span object between threads, but in most
|
||||
* cases this is not necessary.
|
||||
*
|
||||
* A 'TraceScope' can either be empty, or contain a Span. TraceScope objects
|
||||
* implement the Java's Closeable interface. Similar to file descriptors, they
|
||||
* must be closed after they are created. When a TraceScope contains a Span,
|
||||
* this span is closed when the scope is closed.
|
||||
* A 'TraceScope' can either be empty, or contain a Span. TraceScope objects implement the
|
||||
* Java's Closeable interface. Similar to file descriptors, they must be closed after they
|
||||
* are created. When a TraceScope contains a Span, this span is closed when the scope is
|
||||
* closed.
|
||||
*
|
||||
* The 'startSpan' methods in this class do a few things:
|
||||
* <ul>
|
||||
* <li>Create a new Span which has this thread's currentSpan as one of its parents.</li>
|
||||
* <li>Set currentSpan to the new Span.</li>
|
||||
* <li>Create a TraceSpan object to manage the new Span.</li>
|
||||
* <li>Create a new Span which has this thread's currentSpan as one of its parents.</li>
|
||||
* <li>Set currentSpan to the new Span.</li>
|
||||
* <li>Create a TraceSpan object to manage the new Span.</li>
|
||||
* </ul>
|
||||
*
|
||||
* Closing a TraceScope does a few things:
|
||||
* <ul>
|
||||
* <li>It closes the span which the scope was managing.</li>
|
||||
* <li>Set currentSpan to the previous currentSpan (which may be null).</li>
|
||||
* <li>It closes the span which the scope was managing.</li>
|
||||
* <li>Set currentSpan to the previous currentSpan (which may be null).</li>
|
||||
* </ul>
|
||||
*/
|
||||
public interface Trace {
|
||||
@@ -41,33 +39,37 @@ public interface Trace {
|
||||
String TRACE_ID_NAME = "Trace-Id";
|
||||
|
||||
/**
|
||||
* Creates a new trace scope.
|
||||
* Creates a trace scope wrapping a new span.
|
||||
* <p/>
|
||||
* If this thread has a currently active trace span, the trace scope we create
|
||||
* here will contain a new span descending from the currently active span.
|
||||
* If there is no currently active trace span, the trace scope we create will
|
||||
* be empty.
|
||||
* If this thread has a currently active span, it will be the parent of the span we
|
||||
* create here, and the trace scope will contain the new span and the parent. If there
|
||||
* is no currently active trace span, the trace scope we create will be empty.
|
||||
*
|
||||
* @param name The name field for the new span to create.
|
||||
*/
|
||||
TraceScope startSpan(String name);
|
||||
|
||||
TraceScope startSpan(String name, TraceInfo tinfo);
|
||||
|
||||
/**
|
||||
* Creates a new trace scope.
|
||||
* Creates a new trace scope with a specific parent. The parent might be in another
|
||||
* process or thread.
|
||||
* <p/>
|
||||
* If this thread has a currently active trace span, it must be the 'parent'
|
||||
* span that you pass in here as a parameter. The trace scope we create here
|
||||
* will contain a new span which is a child of 'parent'.
|
||||
* If this thread has a currently active trace span, it must be the 'parent' span that
|
||||
* you pass in here as a parameter. The trace scope we create here will contain a new
|
||||
* span which is a child of 'parent'.
|
||||
*
|
||||
* @param name The name field for the new span to create.
|
||||
*/
|
||||
TraceScope startSpan(String name, Span parent);
|
||||
TraceScope startSpan(String name, SpanIdentifiers parent);
|
||||
|
||||
<T> TraceScope startSpan(String name, Sampler<T> s);
|
||||
|
||||
<T> TraceScope startSpan(String name, Sampler<T> s, T info);
|
||||
/**
|
||||
* Start a new span if the sampler allows it or if we are already tracing in this
|
||||
* thread. A sampler can be used to limit the number of traces created.
|
||||
*
|
||||
* @param name the name of the span
|
||||
* @param sampler a sampler to decide whether to create the span or not
|
||||
* @param info the samplers context information
|
||||
*/
|
||||
<T> TraceScope startSpan(String name, Sampler<T> sampler, T info);
|
||||
|
||||
/**
|
||||
* Pick up an existing span from another thread.
|
||||
|
||||
@@ -6,7 +6,8 @@ import lombok.Data;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
public class TraceInfo {
|
||||
public class TraceInfo implements SpanIdentifiers {
|
||||
private final String traceId;
|
||||
private final String spanId;
|
||||
private String processId;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.io.Closeable;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.Value;
|
||||
import lombok.experimental.NonFinal;
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
import org.springframework.cloud.sleuth.event.SpanStoppedEvent;
|
||||
import org.springframework.cloud.sleuth.util.ExceptionUtils;
|
||||
@@ -16,7 +15,6 @@ import org.springframework.context.ApplicationEventPublisher;
|
||||
*/
|
||||
@Value
|
||||
@NonFinal
|
||||
@CommonsLog
|
||||
public class TraceScope implements Closeable {
|
||||
|
||||
private final ApplicationEventPublisher publisher;
|
||||
@@ -47,14 +45,14 @@ public class TraceScope implements Closeable {
|
||||
*
|
||||
* @return the same Span object
|
||||
*/
|
||||
public Span detach() {
|
||||
public SpanIdentifiers detach() {
|
||||
if (this.detached) {
|
||||
ExceptionUtils.error("Tried to detach trace span " + this.span + " but " +
|
||||
"it has already been detached.");
|
||||
}
|
||||
this.detached = true;
|
||||
|
||||
Span cur = TraceContextHolder.getCurrentSpan();
|
||||
SpanIdentifiers cur = TraceContextHolder.getCurrentSpan();
|
||||
if (cur != this.span) {
|
||||
ExceptionUtils.error("Tried to detach trace span " + this.span + " but " +
|
||||
"it is not the current span for the " +
|
||||
@@ -73,7 +71,7 @@ public class TraceScope implements Closeable {
|
||||
return;
|
||||
}
|
||||
this.detached = true;
|
||||
Span cur = TraceContextHolder.getCurrentSpan();
|
||||
SpanIdentifiers cur = TraceContextHolder.getCurrentSpan();
|
||||
if (cur != this.span) {
|
||||
ExceptionUtils.error("Tried to close trace span " + this.span + " but " +
|
||||
"it is not the current span for the " +
|
||||
|
||||
@@ -25,13 +25,13 @@ public class TraceAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Sampler<?> defaultSampler() {
|
||||
public Sampler<Void> defaultSampler() {
|
||||
return new IsTracingSampler();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Trace trace(Sampler<?> sampler, IdGenerator idGenerator,
|
||||
public Trace trace(Sampler<Void> sampler, IdGenerator idGenerator,
|
||||
ApplicationEventPublisher publisher) {
|
||||
return new DefaultTrace(sampler, idGenerator, publisher);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@ package org.springframework.cloud.sleuth.instrument;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanIdentifiers;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceScope;
|
||||
|
||||
@@ -12,27 +13,28 @@ import org.springframework.cloud.sleuth.TraceScope;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
public class TraceCallable<V> extends TraceDelegate<Callable<V>> implements Callable<V> {
|
||||
|
||||
public TraceCallable(Trace trace, Callable<V> delagate) {
|
||||
super(trace, delagate);
|
||||
}
|
||||
|
||||
public TraceCallable(Trace trace, Callable<V> delagate, Span parent) {
|
||||
super(trace, delagate, parent);
|
||||
public TraceCallable(Trace trace, Callable<V> delegate, SpanIdentifiers parent) {
|
||||
super(trace, delegate, parent);
|
||||
}
|
||||
|
||||
public TraceCallable(Trace trace, Callable<V> delagate, Span parent, String name) {
|
||||
super(trace, delagate, parent, name);
|
||||
public TraceCallable(Trace trace, Callable<V> delegate, SpanIdentifiers parent, String name) {
|
||||
super(trace, delegate, parent, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V call() throws Exception {
|
||||
if (this.parent != null) {
|
||||
if (this.getParent() != null) {
|
||||
TraceScope scope = startSpan();
|
||||
|
||||
try {
|
||||
return this.delagate.call();
|
||||
return this.getDelegate().call();
|
||||
}
|
||||
finally {
|
||||
scope.close();
|
||||
@@ -40,7 +42,7 @@ public class TraceCallable<V> extends TraceDelegate<Callable<V>> implements Call
|
||||
|
||||
}
|
||||
else {
|
||||
return this.delagate.call();
|
||||
return this.getDelegate().call();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.springframework.cloud.sleuth.instrument;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import lombok.Getter;
|
||||
|
||||
import org.springframework.cloud.sleuth.SpanIdentifiers;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.TraceScope;
|
||||
@@ -8,24 +10,25 @@ import org.springframework.cloud.sleuth.TraceScope;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Getter
|
||||
public abstract class TraceDelegate<T> {
|
||||
|
||||
protected final Trace trace;
|
||||
protected final T delagate;
|
||||
protected final Span parent;
|
||||
protected final String name;
|
||||
|
||||
public TraceDelegate(Trace trace, T delagate) {
|
||||
this(trace, delagate, TraceContextHolder.getCurrentSpan(), null);
|
||||
private final Trace trace;
|
||||
private final T delegate;
|
||||
private final SpanIdentifiers parent;
|
||||
private final String name;
|
||||
|
||||
public TraceDelegate(Trace trace, T delegate) {
|
||||
this(trace, delegate, TraceContextHolder.getCurrentSpan(), null);
|
||||
}
|
||||
|
||||
public TraceDelegate(Trace trace, T delagate, Span parent) {
|
||||
this(trace, delagate, parent, null);
|
||||
public TraceDelegate(Trace trace, T delegate, SpanIdentifiers parent) {
|
||||
this(trace, delegate, parent, null);
|
||||
}
|
||||
|
||||
public TraceDelegate(Trace trace, T delagate, Span parent, String name) {
|
||||
public TraceDelegate(Trace trace, T delegate, SpanIdentifiers parent, String name) {
|
||||
this.trace = trace;
|
||||
this.delagate = delagate;
|
||||
this.delegate = delegate;
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
}
|
||||
@@ -35,6 +38,6 @@ public abstract class TraceDelegate<T> {
|
||||
}
|
||||
|
||||
protected String getSpanName() {
|
||||
return this.name == null ? Thread.currentThread().getName() : name;
|
||||
return this.name == null ? Thread.currentThread().getName() : this.name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.springframework.cloud.sleuth.instrument;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanIdentifiers;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceScope;
|
||||
|
||||
@@ -18,28 +18,28 @@ public class TraceRunnable extends TraceDelegate<Runnable> implements Runnable {
|
||||
super(trace, delagate);
|
||||
}
|
||||
|
||||
public TraceRunnable(Trace trace, Runnable delagate, Span parent) {
|
||||
public TraceRunnable(Trace trace, Runnable delagate, SpanIdentifiers parent) {
|
||||
super(trace, delagate, parent);
|
||||
}
|
||||
|
||||
public TraceRunnable(Trace trace, Runnable delagate, Span parent, String name) {
|
||||
public TraceRunnable(Trace trace, Runnable delagate, SpanIdentifiers parent, String name) {
|
||||
super(trace, delagate, parent, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (this.parent != null) {
|
||||
if (this.getParent() != null) {
|
||||
TraceScope scope = startSpan();
|
||||
|
||||
try {
|
||||
this.delagate.run();
|
||||
this.getDelegate().run();
|
||||
}
|
||||
finally {
|
||||
scope.close();
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.delagate.run();
|
||||
this.getDelegate().run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public class TraceFilter extends OncePerRequestFilter {
|
||||
if (!skip) {
|
||||
String spanId = getHeader(request, response, SPAN_ID_NAME);
|
||||
String traceId = getHeader(request, response, TRACE_ID_NAME);
|
||||
String name = this.urlPathHelper.getPathWithinApplication(request);
|
||||
String name = "http" + this.urlPathHelper.getPathWithinApplication(request);
|
||||
if (hasText(spanId) && hasText(traceId)) {
|
||||
|
||||
TraceInfo traceInfo = new TraceInfo(traceId, spanId);
|
||||
|
||||
@@ -5,9 +5,9 @@ import org.springframework.cloud.sleuth.Sampler;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class AlwaysSampler implements Sampler<Object> {
|
||||
public class AlwaysSampler implements Sampler<Void> {
|
||||
@Override
|
||||
public boolean next(Object info) {
|
||||
public boolean next(Void info) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ import org.springframework.cloud.sleuth.TraceContextHolder;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class IsTracingSampler implements Sampler<Object> {
|
||||
public class IsTracingSampler implements Sampler<Void> {
|
||||
|
||||
@Override
|
||||
public boolean next(Object info) {
|
||||
public boolean next(Void info) {
|
||||
return TraceContextHolder.getCurrentSpan() != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.springframework.cloud.sleuth.slf4j;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanIdentifiers;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.event.SpanStartedEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
@@ -16,7 +16,7 @@ public class Slf4jSpanStartedListener implements ApplicationListener<SpanStarted
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(SpanStartedEvent event) {
|
||||
Span span = event.getSpan();
|
||||
SpanIdentifiers span = event.getSpan();
|
||||
MDC.put(Trace.SPAN_ID_NAME, span.getSpanId());
|
||||
MDC.put(Trace.TRACE_ID_NAME, span.getTraceId());
|
||||
//TODO: what log level?
|
||||
|
||||
@@ -9,9 +9,9 @@ import org.springframework.cloud.sleuth.MilliSpan;
|
||||
import org.springframework.cloud.sleuth.NullScope;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanIdentifiers;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.TraceInfo;
|
||||
import org.springframework.cloud.sleuth.TraceScope;
|
||||
import org.springframework.cloud.sleuth.event.SpanStartedEvent;
|
||||
import org.springframework.cloud.sleuth.instrument.TraceCallable;
|
||||
@@ -23,13 +23,13 @@ import org.springframework.context.ApplicationEventPublisher;
|
||||
*/
|
||||
public class DefaultTrace implements Trace {
|
||||
|
||||
private final Sampler<?> defaultSampler;
|
||||
private final Sampler<Void> defaultSampler;
|
||||
|
||||
private final IdGenerator idGenerator;
|
||||
|
||||
private final ApplicationEventPublisher publisher;
|
||||
|
||||
public DefaultTrace(Sampler<?> defaultSampler, IdGenerator idGenerator,
|
||||
public DefaultTrace(Sampler<Void> defaultSampler, IdGenerator idGenerator,
|
||||
ApplicationEventPublisher publisher) {
|
||||
this.defaultSampler = defaultSampler;
|
||||
this.idGenerator = idGenerator;
|
||||
@@ -37,75 +37,45 @@ public class DefaultTrace implements Trace {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TraceScope startSpan(String name) {
|
||||
return this.startSpan(name, this.defaultSampler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TraceScope startSpan(String name, TraceInfo tinfo) {
|
||||
if (tinfo == null) return doStart(null);
|
||||
MilliSpan span = MilliSpan.builder()
|
||||
.begin(System.currentTimeMillis())
|
||||
.name(name)
|
||||
.traceId(tinfo.getTraceId())
|
||||
.spanId(this.idGenerator.create())
|
||||
.parent(tinfo.getSpanId())
|
||||
.build();
|
||||
return doStart(span);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TraceScope startSpan(String name, Span parent) {
|
||||
public TraceScope startSpan(String name, SpanIdentifiers parent) {
|
||||
if (parent == null) {
|
||||
return startSpan(name);
|
||||
}
|
||||
Span currentSpan = getCurrentSpan();
|
||||
if ((currentSpan != null) && (currentSpan != parent)) {
|
||||
error("HTrace client error: thread " +
|
||||
Thread.currentThread().getName() + " tried to start a new Span " +
|
||||
"with parent " + parent.toString() + ", but there is already a " +
|
||||
"currentSpan " + currentSpan);
|
||||
SpanIdentifiers currentSpan = getCurrentSpan();
|
||||
if (currentSpan != null && !parent.equals(currentSpan)) {
|
||||
error("HTrace client error: thread " + Thread.currentThread().getName()
|
||||
+ " tried to start a new Span " + "with parent " + parent.toString()
|
||||
+ ", but there is already a " + "currentSpan " + currentSpan);
|
||||
}
|
||||
return doStart(createChild(parent, name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> TraceScope startSpan(String name, Sampler<T> s) {
|
||||
return startSpan(name, s, null);
|
||||
public TraceScope startSpan(String name) {
|
||||
return this.startSpan(name, this.defaultSampler, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> TraceScope startSpan(String name, Sampler<T> s, T info) {
|
||||
Span span = null;
|
||||
if (TraceContextHolder.isTracing() || s.next(info)) {
|
||||
span = createNew(name);
|
||||
span = createChild(getCurrentSpan(), name);
|
||||
}
|
||||
return doStart(span);
|
||||
}
|
||||
|
||||
protected Span createNew(String name) {
|
||||
Span parent = getCurrentSpan();
|
||||
protected Span createChild(SpanIdentifiers parent, String name) {
|
||||
if (parent == null) {
|
||||
return MilliSpan.builder()
|
||||
.begin(System.currentTimeMillis())
|
||||
.name(name)
|
||||
.traceId(this.idGenerator.create())
|
||||
.spanId(this.idGenerator.create())
|
||||
return MilliSpan.builder().begin(System.currentTimeMillis()).name(name)
|
||||
.traceId(this.idGenerator.create()).spanId(this.idGenerator.create())
|
||||
.build();
|
||||
}
|
||||
else {
|
||||
return MilliSpan.builder().begin(System.currentTimeMillis()).name(name)
|
||||
.traceId(parent.getTraceId()).parent(parent.getSpanId())
|
||||
.spanId(this.idGenerator.create()).processId(parent.getProcessId())
|
||||
.build();
|
||||
} else {
|
||||
return createChild(parent, name);
|
||||
}
|
||||
}
|
||||
|
||||
protected Span createChild(Span parent, String childname) {
|
||||
return MilliSpan.builder()
|
||||
.begin(System.currentTimeMillis())
|
||||
.name(childname)
|
||||
.traceId(parent.getTraceId())
|
||||
.parent(parent.getSpanId())
|
||||
.spanId(this.idGenerator.create())
|
||||
.processId(parent.getProcessId())
|
||||
.build();
|
||||
}
|
||||
|
||||
protected TraceScope doStart(Span span) {
|
||||
@@ -118,7 +88,8 @@ public class DefaultTrace implements Trace {
|
||||
@Override
|
||||
public TraceScope continueSpan(Span span) {
|
||||
// Return an empty TraceScope that does nothing on close
|
||||
if (span == null) return NullScope.INSTANCE;
|
||||
if (span == null)
|
||||
return NullScope.INSTANCE;
|
||||
Span oldSpan = getCurrentSpan();
|
||||
TraceContextHolder.setCurrentSpan(span);
|
||||
return new TraceScope(this.publisher, span, oldSpan);
|
||||
@@ -144,7 +115,8 @@ public class DefaultTrace implements Trace {
|
||||
@Override
|
||||
public <V> Callable<V> wrap(Callable<V> callable) {
|
||||
if (TraceContextHolder.isTracing()) {
|
||||
return new TraceCallable<>(this, callable, TraceContextHolder.getCurrentSpan());
|
||||
return new TraceCallable<>(this, callable,
|
||||
TraceContextHolder.getCurrentSpan());
|
||||
}
|
||||
return callable;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ package org.springframework.cloud.sleuth;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
import static org.mockito.Mockito.isA;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -38,7 +38,7 @@ public class DefaultTraceTests {
|
||||
DefaultTrace trace = new DefaultTrace(new IsTracingSampler(),
|
||||
new RandomUuidGenerator(), publisher);
|
||||
|
||||
TraceScope scope = trace.startSpan(CREATE_SIMPLE_TRACE, new AlwaysSampler());
|
||||
TraceScope scope = trace.startSpan(CREATE_SIMPLE_TRACE, new AlwaysSampler(), null);
|
||||
try {
|
||||
importantWork1(trace);
|
||||
}
|
||||
@@ -62,15 +62,15 @@ public class DefaultTraceTests {
|
||||
|
||||
assertThat("spans was wrong size", spans.size(), is(NUM_SPANS));
|
||||
|
||||
Span root = assertSpan(spans, null, CREATE_SIMPLE_TRACE);
|
||||
Span child = assertSpan(spans, root.getSpanId(), IMPORTANT_WORK_1);
|
||||
Span grandChild = assertSpan(spans, child.getSpanId(), IMPORTANT_WORK_2);
|
||||
SpanIdentifiers root = assertSpan(spans, null, CREATE_SIMPLE_TRACE);
|
||||
SpanIdentifiers child = assertSpan(spans, root.getSpanId(), IMPORTANT_WORK_1);
|
||||
SpanIdentifiers grandChild = assertSpan(spans, child.getSpanId(), IMPORTANT_WORK_2);
|
||||
|
||||
List<Span> gen4 = findSpans(spans, grandChild.getSpanId());
|
||||
assertThat("gen4 was non-empty", gen4.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
private Span assertSpan(List<Span> spans, String parentId, String name) {
|
||||
private SpanIdentifiers assertSpan(List<Span> spans, String parentId, String name) {
|
||||
List<Span> found = findSpans(spans, parentId);
|
||||
assertThat("more than one span with parentId " + parentId, found.size(), is(1));
|
||||
Span span = found.get(0);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.springframework.cloud.sleuth.sample;
|
||||
|
||||
import com.github.kristofa.brave.LoggingSpanCollectorImpl;
|
||||
import com.github.kristofa.brave.SpanCollector;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
|
||||
@@ -8,7 +8,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanIdentifiers;
|
||||
import org.springframework.cloud.sleuth.Trace;
|
||||
import org.springframework.cloud.sleuth.TraceContextHolder;
|
||||
import org.springframework.cloud.sleuth.TraceScope;
|
||||
@@ -47,7 +47,7 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
return new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
Span currentSpan = TraceContextHolder.getCurrentSpan();
|
||||
SpanIdentifiers currentSpan = TraceContextHolder.getCurrentSpan();
|
||||
return "async hi: "+currentSpan;
|
||||
}
|
||||
};
|
||||
@@ -67,7 +67,7 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
|
||||
@SneakyThrows
|
||||
@RequestMapping("/traced")
|
||||
public String traced() {
|
||||
TraceScope scope = this.trace.startSpan("customTraceEndpoint", new AlwaysSampler());
|
||||
TraceScope scope = this.trace.startSpan("customTraceEndpoint", new AlwaysSampler(), null);
|
||||
final Random random = new Random();
|
||||
int millis = random.nextInt(1000);
|
||||
log.info("Sleeping for {} millis", millis);
|
||||
|
||||
@@ -13,8 +13,11 @@ import lombok.extern.apachecommons.CommonsLog;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.cloud.sleuth.SpanIdentifiers;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.TimelineAnnotation;
|
||||
import org.springframework.cloud.sleuth.event.SpanStoppedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
|
||||
import com.github.kristofa.brave.SpanCollector;
|
||||
import com.twitter.zipkin.gen.Annotation;
|
||||
@@ -22,8 +25,6 @@ import com.twitter.zipkin.gen.AnnotationType;
|
||||
import com.twitter.zipkin.gen.BinaryAnnotation;
|
||||
import com.twitter.zipkin.gen.Endpoint;
|
||||
import com.twitter.zipkin.gen.zipkinCoreConstants;
|
||||
import org.springframework.cloud.sleuth.event.SpanStoppedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -47,7 +48,7 @@ public class SleuthTracer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given HTrace span to a Zipkin Span.
|
||||
* Converts a given Sleuth span to a Zipkin Span.
|
||||
* <ul>
|
||||
* <li>First set the start annotation. [CS, SR], depending whether it is a client service or not.
|
||||
* <li>Set other id's, etc [TraceId's etc]
|
||||
@@ -82,8 +83,8 @@ public class SleuthTracer {
|
||||
|
||||
public Integer getPort() {
|
||||
Integer port;
|
||||
if (serverProperties.getPort() != null) {
|
||||
port = serverProperties.getPort();
|
||||
if (this.serverProperties.getPort() != null) {
|
||||
port = this.serverProperties.getPort();
|
||||
} else {
|
||||
port = 8080; //TODO: support random port
|
||||
}
|
||||
@@ -92,20 +93,20 @@ public class SleuthTracer {
|
||||
|
||||
public int getAddress() {
|
||||
String address;
|
||||
if (serverProperties.getAddress() != null) {
|
||||
address = serverProperties.getAddress().getHostAddress();
|
||||
if (this.serverProperties.getAddress() != null) {
|
||||
address = this.serverProperties.getAddress().getHostAddress();
|
||||
} else {
|
||||
address = "127.0.0.1"; //TODO: get address from config
|
||||
}
|
||||
return ipAddressToInt(address);
|
||||
}
|
||||
|
||||
public String getServiceName(Span span) {
|
||||
public String getServiceName(SpanIdentifiers span) {
|
||||
String serviceName;
|
||||
if (span.getProcessId() != null) {
|
||||
serviceName = span.getProcessId().toLowerCase();
|
||||
} else {
|
||||
serviceName = appName;
|
||||
serviceName = this.appName;
|
||||
}
|
||||
return serviceName;
|
||||
}
|
||||
@@ -125,21 +126,21 @@ public class SleuthTracer {
|
||||
* Add annotations from the sleuth Span.
|
||||
*/
|
||||
private List<Annotation> createZipkinAnnotations(Span span,
|
||||
Endpoint ep) {
|
||||
Endpoint endpoint) {
|
||||
List<Annotation> annotationList = new ArrayList<>();
|
||||
|
||||
int duration = (int)(span.getEnd() - span.getBegin());
|
||||
|
||||
// add first zipkin annotation.
|
||||
annotationList.add(createZipkinAnnotation(zipkinCoreConstants.CLIENT_SEND, span.getBegin(), 0, ep, true));
|
||||
annotationList.add(createZipkinAnnotation(zipkinCoreConstants.SERVER_RECV, span.getBegin(), 0, ep, true));
|
||||
annotationList.add(createZipkinAnnotation(zipkinCoreConstants.CLIENT_SEND, span.getBegin(), 0, endpoint, true));
|
||||
annotationList.add(createZipkinAnnotation(zipkinCoreConstants.SERVER_RECV, span.getBegin(), 0, endpoint, true));
|
||||
// add sleuth time annotation
|
||||
for (TimelineAnnotation ta : span.getTimelineAnnotations()) {
|
||||
annotationList.add(createZipkinAnnotation(ta.getMsg(), ta.getTime(), 0, ep, true));
|
||||
annotationList.add(createZipkinAnnotation(ta.getMsg(), ta.getTime(), 0, endpoint, true));
|
||||
}
|
||||
// add last zipkin annotation
|
||||
annotationList.add(createZipkinAnnotation(zipkinCoreConstants.SERVER_SEND, span.getEnd(), duration, ep, false));
|
||||
annotationList.add(createZipkinAnnotation(zipkinCoreConstants.CLIENT_RECV, span.getEnd(), duration, ep, false));
|
||||
annotationList.add(createZipkinAnnotation(zipkinCoreConstants.SERVER_SEND, span.getEnd(), duration, endpoint, false));
|
||||
annotationList.add(createZipkinAnnotation(zipkinCoreConstants.CLIENT_RECV, span.getEnd(), duration, endpoint, false));
|
||||
return annotationList;
|
||||
}
|
||||
|
||||
@@ -149,7 +150,7 @@ public class SleuthTracer {
|
||||
* @return list of Annotations that could be added to Zipkin Span.
|
||||
*/
|
||||
private List<BinaryAnnotation> createZipkinBinaryAnnotations(Span span,
|
||||
Endpoint ep) {
|
||||
Endpoint endpoint) {
|
||||
List<BinaryAnnotation> l = new ArrayList<>();
|
||||
for (Map.Entry<String, String> e : span.getKVAnnotations().entrySet()) {
|
||||
BinaryAnnotation binaryAnn = new BinaryAnnotation();
|
||||
@@ -160,7 +161,7 @@ public class SleuthTracer {
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
log.error("Error encoding string as UTF-8", ex);
|
||||
}
|
||||
binaryAnn.setHost(ep);
|
||||
binaryAnn.setHost(endpoint);
|
||||
l.add(binaryAnn);
|
||||
}
|
||||
return l;
|
||||
@@ -171,13 +172,13 @@ public class SleuthTracer {
|
||||
*
|
||||
* @param value Annotation value
|
||||
* @param time timestamp will be extracted
|
||||
* @param ep the endopint this annotation will be associated with.
|
||||
* @param endpoint the endpoint this annotation will be associated with.
|
||||
* @param sendRequest use the first or last timestamp.
|
||||
*/
|
||||
private static Annotation createZipkinAnnotation(String value, long time, int duration,
|
||||
Endpoint ep, boolean sendRequest) {
|
||||
Endpoint endpoint, boolean sendRequest) {
|
||||
Annotation annotation = new Annotation();
|
||||
annotation.setHost(ep);
|
||||
annotation.setHost(endpoint);
|
||||
|
||||
// Zipkin is in microseconds
|
||||
if (sendRequest) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.springframework.cloud.sleuth.zipkin;
|
||||
import lombok.Data;
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
import org.springframework.cloud.sleuth.SpanIdentifiers;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.event.SpanStartedEvent;
|
||||
import org.springframework.cloud.sleuth.event.SpanStoppedEvent;
|
||||
@@ -64,7 +65,7 @@ public class ZipkinSpanListener {
|
||||
return context.getName();
|
||||
}
|
||||
|
||||
protected void postTrace(Span context) {
|
||||
protected void postTrace(SpanIdentifiers context) {
|
||||
// We can submit this in any case. When server state is not set or
|
||||
// we should not trace this request nothing will happen.
|
||||
log.debug("Sending server send.");
|
||||
|
||||
Reference in New Issue
Block a user