public final class SpanBuilder extends Object
SpanBuilder is used to construct Span instances which define arbitrary scopes of
code that are sampled for distributed tracing as a single atomic unit.
This is a simple example where all the work is being done within a single scope and a single thread and the Context is automatically propagated:
class MyClass {
private static final Tracer tracer = Tracing.getTracer();
void doWork {
// Create a Span as a child of the current Span.
try (NonThrowingCloseable ss = tracer.spanBuilder("MyChildSpan").startScopedSpan()) {
tracer.getCurrentSpan().addAnnotation("my annotation");
doSomeWork(); // Here the new span is in the current Context, so it can be used
// implicitly anywhere down the stack.
}
}
}
There might be cases where you do not perform all the work inside one static scope and the Context is automatically propagated:
class MyRpcServerInterceptorListener implements RpcServerInterceptor.Listener {
private static final Tracer tracer = Tracing.getTracer();
private Span mySpan;
public MyRpcInterceptor() {}
public void onRequest(String rpcName, Metadata metadata) {
// Create a Span as a child of the remote Span.
mySpan = tracer.spanBuilderWithRemoteParent(
getTraceContextFromMetadata(metadata), rpcName).startSpan();
}
public void onExecuteHandler(ServerCallHandler serverCallHandler) {
try (NonThrowingCloseable ws = tracer.withSpan(mySpan)) {
tracer.getCurrentSpan().addAnnotation("Start rpc execution.");
serverCallHandler.run(); // Here the new span is in the current Context, so it can be
// used implicitly anywhere down the stack.
}
}
// Called when the RPC is canceled and guaranteed onComplete will not be called.
public void onCancel() {
// IMPORTANT: DO NOT forget to ended the Span here as the work is done.
mySpan.end(EndSpanOptions.builder().setStatus(Status.CANCELLED));
}
// Called when the RPC is done and guaranteed onCancel will not be called.
public void onComplete(RpcStatus rpcStatus) {
// IMPORTANT: DO NOT forget to ended the Span here as the work is done.
mySpan.end(EndSpanOptions.builder().setStatus(rpcStatusToCanonicalTraceStatus(status));
}
}
This is a simple example where all the work is being done within a single scope and the Context is manually propagated:
class MyClass {
private static final Tracer tracer = Tracing.getTracer();
void DoWork() {
Span span = tracer.spanBuilder(null, "MyRootSpan").startSpan();
span.addAnnotation("my annotation");
try {
doSomeWork(span); // Manually propagate the new span down the stack.
} finally {
// To make sure we end the span even in case of an exception.
span.end(); // Manually end the span.
}
}
}
If your Java version is less than Java SE 7, see startSpan() and startScopedSpan() for usage examples.
| Modifier and Type | Method and Description |
|---|---|
SpanBuilder |
becomeRoot()
If called this will force the newly created
Span to be a root span. |
SpanBuilder |
setParentLinks(List<Span> parentLinks)
Sets the
List of parent links. |
SpanBuilder |
setRecordEvents(boolean recordEvents)
Sets the option
Span.Options.RECORD_EVENTS for the newly created Span. |
SpanBuilder |
setSampler(Sampler sampler)
Sets the
Sampler to use. |
NonThrowingCloseable |
startScopedSpan()
Starts a new new span and sets it as the
current span. |
Span |
startSpan()
Starts a new
Span. |
public SpanBuilder setSampler(@Nullable Sampler sampler)
Sampler to use. If a null value is passed, the implementation will
provide a default.sampler - The Sampler to use when determining sampling for a Span.public SpanBuilder setParentLinks(@Nullable List<Span> parentLinks)
List of parent links. Links are used to link Spans in different
traces. Used (for example) in batching operations, where a single batch handler processes
multiple requests from different traces.parentLinks - New links to be added.public SpanBuilder setRecordEvents(boolean recordEvents)
Span.Options.RECORD_EVENTS for the newly created Span. If not
called, the implementation will provide a default.recordEvents - New value determining if this Span should have events recorded.public SpanBuilder becomeRoot()
Span to be a root span. As a consequence,
any parent specified (or inherited from the Context) will be ignored (N.B. does not apply to
linked parents set through setParentLinks(java.util.List<com.google.instrumentation.trace.Span>)).
This is useful when Tracer.spanBuilder(String) is used and the newly created Span needs to be decoupled from the parent Span.
public Span startSpan()
Span.
Users must manually call Span.end() or Span.end(EndSpanOptions) to
end this Span.
Does not install the newly created Span to the current Context.
Example of usage:
class MyClass {
private static final Tracer tracer = Tracing.getTracer();
void DoWork() {
Span span = tracer.spanBuilder(null, "MyRootSpan").startSpan();
span.addAnnotation("my annotation");
try {
doSomeWork(span); // Manually propagate the new span down the stack.
} finally {
// To make sure we end the span even in case of an exception.
span.end(); // Manually end the span.
}
}
}
Span.public NonThrowingCloseable startScopedSpan()
current span.
Enters the scope of code where the newly created Span is in the current Context, and
returns an object that represents that scope. The scope is exited when the returned object is
closed then the previous Context is restored and the newly created Span is ended using
Span.end(com.google.instrumentation.trace.EndSpanOptions).
Supports try-with-resource idiom.
Example of usage:
class MyClass {
private static final Tracer tracer = Tracing.getTracer();
void doWork {
// Create a Span as a child of the current Span.
try (NonThrowingCloseable ss = tracer.spanBuilder("MyChildSpan").startScopedSpan()) {
tracer.getCurrentSpan().addAnnotation("my annotation");
doSomeWork(); // Here the new span is in the current Context, so it can be used
// implicitly anywhere down the stack. Anytime in this closure the span
// can be accessed via tracer.getCurrentSpan().
}
}
}
Prior to Java SE 7, you can use a finally block to ensure that a resource is closed (the
Span is ended and removed from the Context) regardless of whether the try statement
completes normally or abruptly.
Example of usage prior to Java SE7:
class MyClass {
private static Tracer tracer = Tracing.getTracer();
void doWork {
// Create a Span as a child of the current Span.
NonThrowingCloseable ss = tracer.spanBuilder("MyChildSpan").startScopedSpan();
try {
tracer.getCurrentSpan().addAnnotation("my annotation");
doSomeWork(); // Here the new span is in the current Context, so it can be used
// implicitly anywhere down the stack. Anytime in this closure the span
// can be accessed via tracer.getCurrentSpan().
} finally {
ss.close();
}
}
}
Span will be set to the
current Context.