Prototype codes of supporting leaf span
This commit is contained in:
parent
c3259afae0
commit
9e4026e9b5
|
|
@ -83,7 +83,7 @@ public class Span {
|
|||
* means no parent span if this {@link TraceSegment}.
|
||||
* @param operationName {@link #operationName}
|
||||
*/
|
||||
private Span(int spanId, int parentSpanId, String operationName) {
|
||||
protected Span(int spanId, int parentSpanId, String operationName) {
|
||||
this(spanId, parentSpanId, operationName, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ public class Span {
|
|||
* @param operationName {@link #operationName}
|
||||
* @param startTime given start timestamp.
|
||||
*/
|
||||
private Span(int spanId, int parentSpanId, String operationName, long startTime) {
|
||||
protected Span(int spanId, int parentSpanId, String operationName, long startTime) {
|
||||
this();
|
||||
this.spanId = spanId;
|
||||
this.parentSpanId = parentSpanId;
|
||||
|
|
@ -200,17 +200,17 @@ public class Span {
|
|||
*
|
||||
* @return this Span instance, for chaining
|
||||
*/
|
||||
public final Span setTag(String key, String value) {
|
||||
public Span setTag(String key, String value) {
|
||||
tagsWithStr.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Span setTag(String key, boolean value) {
|
||||
public Span setTag(String key, boolean value) {
|
||||
tagsWithBool.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final Span setTag(String key, Integer value) {
|
||||
public Span setTag(String key, Integer value) {
|
||||
tagsWithInt.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -359,6 +359,10 @@ public class Span {
|
|||
return Collections.unmodifiableList(logs);
|
||||
}
|
||||
|
||||
public boolean isLeaf() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Span{" +
|
||||
|
|
|
|||
|
|
@ -55,11 +55,19 @@ public class ContextManager implements TracerContextListener, BootService {
|
|||
}
|
||||
|
||||
public static Span createSpan(String operationName) {
|
||||
return get().createSpan(operationName);
|
||||
return get().createSpan(operationName, false);
|
||||
}
|
||||
|
||||
public static Span createSpan(String operationName, long startTime) {
|
||||
return get().createSpan(operationName, startTime);
|
||||
return get().createSpan(operationName, startTime, false);
|
||||
}
|
||||
|
||||
public static Span createLeafSpan(String operationName) {
|
||||
return get().createSpan(operationName, true);
|
||||
}
|
||||
|
||||
public static Span createLeafSpan(String operationName, long startTime) {
|
||||
return get().createSpan(operationName, startTime, true);
|
||||
}
|
||||
|
||||
public static Span activeSpan() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
package org.skywalking.apm.agent.core.context;
|
||||
|
||||
import org.skywalking.apm.trace.Span;
|
||||
import org.skywalking.apm.trace.TraceSegment;
|
||||
|
||||
/**
|
||||
* LeafSpan is a special type of {@link Span}
|
||||
*
|
||||
* In rpc-client tracing scenario, one component could constitute by many other rpc-client.
|
||||
* e.g Feign constitutes by okhttp, apache httpclient, etc.
|
||||
*
|
||||
* By having leaf concept, no need so many spans for single rpc call.
|
||||
*
|
||||
* @author wusheng
|
||||
*/
|
||||
public class LeafSpan extends Span {
|
||||
private int stackDepth = 0;
|
||||
|
||||
/**
|
||||
* Create a new span, by given span id and give startTime but no parent span id,
|
||||
* No parent span id means that, this Span is the first span of the {@link TraceSegment}
|
||||
*
|
||||
* @param spanId given by the creator, and must be unique id in the {@link TraceSegment}
|
||||
* @param operationName {@link #operationName}
|
||||
* @param startTime given start time of span
|
||||
*/
|
||||
public LeafSpan(int spanId, String operationName, long startTime) {
|
||||
super(spanId, -1, operationName, startTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new span, by given span id, parent span, operationName and startTime.
|
||||
* This span must belong a {@link TraceSegment}, also is a part of Distributed Trace.
|
||||
*
|
||||
* @param spanId given by the creator, and must be unique id in the {@link TraceSegment}
|
||||
* @param parentSpan {@link Span}
|
||||
* @param operationName {@link #operationName}
|
||||
* @param startTime given start timestamp
|
||||
*/
|
||||
public LeafSpan(int spanId, Span parentSpan, String operationName, long startTime) {
|
||||
super(spanId, parentSpan.getSpanId(), operationName, startTime);
|
||||
}
|
||||
|
||||
void push() {
|
||||
stackDepth++;
|
||||
}
|
||||
|
||||
void pop() {
|
||||
stackDepth--;
|
||||
}
|
||||
|
||||
boolean isFinished() {
|
||||
return stackDepth == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isInOwnerContext() {
|
||||
return stackDepth == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the string name for the logical operation this span represents,
|
||||
* only when this is in context of the leaf span owner.
|
||||
*
|
||||
* @return this Span instance, for chaining
|
||||
*/
|
||||
@Override
|
||||
public Span setOperationName(String operationName) {
|
||||
if (isInOwnerContext()) {
|
||||
super.setOperationName(operationName);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a key:value tag on the Span,
|
||||
* only when this is in context of the leaf span owner.
|
||||
*
|
||||
* @return this Span instance, for chaining
|
||||
*/
|
||||
@Override
|
||||
public final Span setTag(String key, String value) {
|
||||
if (isInOwnerContext()) {
|
||||
super.setTag(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Span setTag(String key, boolean value) {
|
||||
if (isInOwnerContext()) {
|
||||
super.setTag(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Span setTag(String key, Integer value) {
|
||||
if (isInOwnerContext()) {
|
||||
super.setTag(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
@ -46,26 +46,40 @@ public final class TracerContext {
|
|||
* @param operationName {@link Span#operationName}
|
||||
* @return the new active span.
|
||||
*/
|
||||
public Span createSpan(String operationName) {
|
||||
return this.createSpan(operationName, System.currentTimeMillis());
|
||||
public Span createSpan(String operationName, boolean isLeaf) {
|
||||
return this.createSpan(operationName, System.currentTimeMillis(), isLeaf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new span, as an active span, by the given operationName and startTime;
|
||||
*
|
||||
* @param operationName {@link Span#operationName}
|
||||
* @param startTime {@link Span#startTime}
|
||||
* @param startTime {@link Span#startTime}
|
||||
* @param isLeaf is true, if the span is a leaf in trace tree.
|
||||
* @return
|
||||
*/
|
||||
public Span createSpan(String operationName, long startTime) {
|
||||
public Span createSpan(String operationName, long startTime, boolean isLeaf) {
|
||||
Span parentSpan = peek();
|
||||
Span span;
|
||||
if (parentSpan == null) {
|
||||
span = new Span(spanIdGenerator++, operationName, startTime);
|
||||
if (isLeaf) {
|
||||
span = new LeafSpan(spanIdGenerator++, operationName, startTime);
|
||||
} else {
|
||||
span = new Span(spanIdGenerator++, operationName, startTime);
|
||||
}
|
||||
push(span);
|
||||
} else if (parentSpan.isLeaf()) {
|
||||
span = parentSpan;
|
||||
LeafSpan leafSpan = (LeafSpan)span;
|
||||
leafSpan.push();
|
||||
} else {
|
||||
span = new Span(spanIdGenerator++, parentSpan, operationName, startTime);
|
||||
if (isLeaf) {
|
||||
span = new LeafSpan(spanIdGenerator++, parentSpan, operationName, startTime);
|
||||
} else {
|
||||
span = new Span(spanIdGenerator++, parentSpan, operationName, startTime);
|
||||
}
|
||||
push(span);
|
||||
}
|
||||
push(span);
|
||||
return span;
|
||||
}
|
||||
|
||||
|
|
@ -98,6 +112,13 @@ public final class TracerContext {
|
|||
|
||||
public void stopSpan(Span span, Long endTime) {
|
||||
Span lastSpan = peek();
|
||||
if (lastSpan.isLeaf()) {
|
||||
LeafSpan leafSpan = (LeafSpan)lastSpan;
|
||||
leafSpan.pop();
|
||||
if (!leafSpan.isFinished()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (lastSpan == span) {
|
||||
pop().finish(segment, endTime);
|
||||
} else {
|
||||
|
|
@ -142,7 +163,7 @@ public final class TracerContext {
|
|||
* Ref this {@link ContextCarrier} to this {@link TraceSegment}
|
||||
*
|
||||
* @param carrier holds the snapshot, if get this {@link ContextCarrier} from remote, make sure {@link
|
||||
* ContextCarrier#deserialize(String)} called.
|
||||
* ContextCarrier#deserialize(String)} called.
|
||||
*/
|
||||
public void extract(ContextCarrier carrier) {
|
||||
if (carrier.isValid()) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public class TracerContextTestCase {
|
|||
@Test
|
||||
public void testSpanLifeCycle() {
|
||||
TracerContext context = new TracerContext();
|
||||
Span span = context.createSpan("/serviceA");
|
||||
Span span = context.createSpan("/serviceA", false);
|
||||
|
||||
Assert.assertEquals(span, context.activeSpan());
|
||||
|
||||
|
|
@ -35,8 +35,8 @@ public class TracerContextTestCase {
|
|||
@Test
|
||||
public void testChildOfSpan() {
|
||||
TracerContext context = new TracerContext();
|
||||
Span serviceSpan = context.createSpan("/serviceA");
|
||||
Span dbSpan = context.createSpan("db/preparedStatement/execute");
|
||||
Span serviceSpan = context.createSpan("/serviceA", false);
|
||||
Span dbSpan = context.createSpan("db/preparedStatement/execute", false);
|
||||
|
||||
Assert.assertEquals(dbSpan, context.activeSpan());
|
||||
|
||||
|
|
@ -60,8 +60,8 @@ public class TracerContextTestCase {
|
|||
@Test
|
||||
public void testInject() {
|
||||
TracerContext context = new TracerContext();
|
||||
Span serviceSpan = context.createSpan("/serviceA");
|
||||
Span dbSpan = context.createSpan("db/preparedStatement/execute");
|
||||
Span serviceSpan = context.createSpan("/serviceA", false);
|
||||
Span dbSpan = context.createSpan("db/preparedStatement/execute", false);
|
||||
Tags.PEER_HOST.set(dbSpan, "127.0.0.1");
|
||||
Tags.PEER_PORT.set(dbSpan, 8080);
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ public class TracerContextTestCase {
|
|||
|
||||
TracerContext context = new TracerContext();
|
||||
context.extract(carrier);
|
||||
Span span = context.createSpan("/serviceC");
|
||||
Span span = context.createSpan("/serviceC", false);
|
||||
|
||||
TracerContext.ListenerManager.add(TestTracerContextListener.INSTANCE);
|
||||
final TraceSegment[] finishedSegmentCarrier = TestTracerContextListener.INSTANCE.finishedSegmentCarrier;
|
||||
|
|
|
|||
Loading…
Reference in New Issue