Class SpanBuilder
- java.lang.Object
-
- io.opencensus.trace.SpanBuilder
-
- Direct Known Subclasses:
SpanBuilder.NoopSpanBuilder
,SpanBuilderImpl
public abstract class SpanBuilder extends java.lang.Object
SpanBuilder
is used to constructSpan
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 (Scope 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 (Scope 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 parent) { Span childSpan = tracer.spanBuilderWithExplicitParent("MyChildSpan", parent).startSpan(); childSpan.addAnnotation("my annotation"); try { doSomeWork(childSpan); // Manually propagate the new span down the stack. } finally { // To make sure we end the span even in case of an exception. childSpan.end(); // Manually end the span. } } }
If your Java version is less than Java SE 7, see
startSpan()
andstartScopedSpan()
for usage examples.- Since:
- 0.5
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description (package private) static class
SpanBuilder.NoopSpanBuilder
-
Constructor Summary
Constructors Constructor Description SpanBuilder()
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description abstract SpanBuilder
setParentLinks(java.util.List<Span> parentLinks)
Sets theList
of parent links.abstract SpanBuilder
setRecordEvents(boolean recordEvents)
Sets the optionSpan.Options.RECORD_EVENTS
for the newly createdSpan
.abstract SpanBuilder
setSampler(Sampler sampler)
Sets theSampler
to use.SpanBuilder
setSpanKind(Span.Kind spanKind)
Sets theSpan.Kind
for the newly createdSpan
.Scope
startScopedSpan()
Starts a new span and sets it as thecurrent span
.abstract Span
startSpan()
Starts a newSpan
.<V> V
startSpanAndCall(java.util.concurrent.Callable<V> callable)
Starts a new span and calls the givenCallable
with the newly createdSpan
as the currentSpan
, and ends theSpan
after theCallable
is called.void
startSpanAndRun(java.lang.Runnable runnable)
Starts a new span and runs the givenRunnable
with the newly createdSpan
as the currentSpan
, and ends theSpan
after theRunnable
is run.
-
-
-
Method Detail
-
setSampler
public abstract SpanBuilder setSampler(Sampler sampler)
Sets theSampler
to use. If not set, the implementation will provide a default.- Parameters:
sampler
- theSampler
to use when determining sampling for aSpan
.- Returns:
- this.
- Since:
- 0.5
-
setParentLinks
public abstract SpanBuilder setParentLinks(java.util.List<Span> parentLinks)
Sets theList
of parent links. Links are used to linkSpan
s in different traces. Used (for example) in batching operations, where a single batch handler processes multiple requests from different traces.- Parameters:
parentLinks
- new links to be added.- Returns:
- this.
- Throws:
java.lang.NullPointerException
- ifparentLinks
isnull
.- Since:
- 0.5
-
setRecordEvents
public abstract SpanBuilder setRecordEvents(boolean recordEvents)
Sets the optionSpan.Options.RECORD_EVENTS
for the newly createdSpan
. If not called, the implementation will provide a default.- Parameters:
recordEvents
- new value determining if thisSpan
should have events recorded.- Returns:
- this.
- Since:
- 0.5
-
setSpanKind
public SpanBuilder setSpanKind(@Nullable Span.Kind spanKind)
Sets theSpan.Kind
for the newly createdSpan
. If not called, the implementation will provide a default.- Parameters:
spanKind
- the kind of the newly createdSpan
.- Returns:
- this.
- Since:
- 0.14
-
startSpan
public abstract Span startSpan()
Starts a newSpan
.Users must manually call
Span.end()
orSpan.end(EndSpanOptions)
to end thisSpan
.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 parent) { Span childSpan = tracer.spanBuilderWithExplicitParent("MyChildSpan", parent).startSpan(); childSpan.addAnnotation("my annotation"); try { doSomeWork(childSpan); // Manually propagate the new span down the stack. } finally { // To make sure we end the span even in case of an exception. childSpan.end(); // Manually end the span. } } }
- Returns:
- the newly created
Span
. - Since:
- 0.5
-
startScopedSpan
@MustBeClosed public final Scope startScopedSpan()
Starts a new span and sets it as thecurrent span
.Enters the scope of code where the newly created
Span
is in the current Context, and returns an object that represents that scope. When the returned object is closed, the scope is exited, the previous Context is restored, and the newly createdSpan
is ended usingSpan.end(io.opencensus.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 (Scope 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. Scope 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(); } } }
WARNING: The try-with-resources feature to auto-close spans as described above can sound very tempting due to its convenience, but it comes with an important and easy-to-miss trade-off: the span will be closed before any
catch
orfinally
blocks get a chance to execute. So if you need to catch any exceptions and log information about them (for example), then you do not want to use the try-with-resources shortcut because that logging will not be tagged with the span info of the span it logically falls under, and if you try to retrieveTracer.getCurrentSpan()
then you'll either get the parent span if one exists orBlankSpan
if there was no parent span. This can be confusing and seem counter-intuitive, but it's the way try-with-resources works.- Returns:
- an object that defines a scope where the newly created
Span
will be set to the current Context. - Since:
- 0.5
-
startSpanAndRun
public final void startSpanAndRun(java.lang.Runnable runnable)
Starts a new span and runs the givenRunnable
with the newly createdSpan
as the currentSpan
, and ends theSpan
after theRunnable
is run.Any error will end up as a
Status.UNKNOWN
.tracer.spanBuilder("MyRunnableSpan").startSpanAndRun(myRunnable);
It is equivalent with the following code:
Span span = tracer.spanBuilder("MyRunnableSpan").startSpan(); Runnable newRunnable = tracer.withSpan(span, myRunnable); try { newRunnable.run(); } finally { span.end(); }
- Parameters:
runnable
- theRunnable
to run in theSpan
.- Since:
- 0.11.0
-
startSpanAndCall
public final <V> V startSpanAndCall(java.util.concurrent.Callable<V> callable) throws java.lang.Exception
Starts a new span and calls the givenCallable
with the newly createdSpan
as the currentSpan
, and ends theSpan
after theCallable
is called.Any error will end up as a
Status.UNKNOWN
.MyResult myResult = tracer.spanBuilder("MyCallableSpan").startSpanAndCall(myCallable);
It is equivalent with the following code:
Span span = tracer.spanBuilder("MyCallableSpan").startSpan();
Callable<MyResult>
newCallable = tracer.withSpan(span, myCallable); MyResult myResult = null; try { myResult = newCallable.call(); } finally { span.end(); } );- Parameters:
callable
- theCallable
to run in theSpan
.- Throws:
java.lang.Exception
- Since:
- 0.11.0
-
-