Class Tracer
- java.lang.Object
-
- brave.Tracer
-
public class Tracer extends Object
Using a tracer, you can create a root span capturing the critical path of a request. Child spans can be created to allocate latency relating to outgoing requests. When tracing single-threaded code, just run it inside a scoped span:// Start a new trace or a span within an existing trace representing an operation ScopedSpan span = tracer.startScopedSpan("encode"); try { // The span is in "scope" so that downstream code such as loggers can see trace IDs return encoder.encode(); } catch (RuntimeException | Error e) { span.error(e); // Unless you handle exceptions, you might not know the operation failed! throw e; } finally { span.finish(); }
When you need more features, or finer control, use the Span type:
// Start a new trace or a span within an existing trace representing an operation Span span = tracer.nextSpan().name("encode").start(); // Put the span in "scope" so that downstream code such as loggers can see trace IDs try (SpanInScope ws = tracer.withSpanInScope(span)) { return encoder.encode(); } catch (RuntimeException | Error e) { span.error(e); // Unless you handle exceptions, you might not know the operation failed! throw e; } finally { span.finish(); // note the scope is independent of the span. Always finish a span. }
Both of the above examples report the exact same span on finish!
- See Also:
Span
,ScopedSpan
,Propagation
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
Tracer.SpanInScope
A span remains in the scope it was bound to until close is called.
-
Method Summary
All Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description Span
currentSpan()
Returns the current span in scope or null if there isn't one.SpanCustomizer
currentSpanCustomizer()
Returns a customizer for current span in scope or noop if there isn't one.Span
joinSpan(TraceContext context)
Joining is re-using the same trace and span ids extracted from an incoming RPC request.Span
newChild(TraceContext parent)
Explicitly creates a child within an existing trace.Span
newTrace()
Explicitly creates a new trace.Span
nextSpan()
Returns a new child span if there's acurrentSpan()
or a new trace if there isn't.Span
nextSpan(TraceContextOrSamplingFlags extracted)
This creates a new span based on parameters extracted from an incoming request.<T> Span
nextSpan(SamplerFunction<T> samplerFunction, T arg)
LikenextSpan()
except when there is no trace in process, the samplertriggers
against the supplied argument.<T> Span
nextSpanWithParent(SamplerFunction<T> samplerFunction, T arg, TraceContext parent)
LikenextSpan(SamplerFunction, Object)
except this controls the parent context explicitly.ScopedSpan
startScopedSpan(String name)
Returns a new child span if there's acurrentSpan()
or a new trace if there isn't.<T> ScopedSpan
startScopedSpan(String name, SamplerFunction<T> samplerFunction, T arg)
LikestartScopedSpan(String)
except when there is no trace in process, the samplertriggers
against the supplied argument.ScopedSpan
startScopedSpanWithParent(String name, TraceContext parent)
Same asstartScopedSpan(String)
, except ignores the current trace context.Span
toSpan(TraceContext context)
Converts the context to a Span object after decorating it for propagation.String
toString()
Tracer
withSampler(Sampler sampler)
Deprecated.Tracer.SpanInScope
withSpanInScope(Span span)
Makes the given span the "current span" and returns an object that exits that scope on close.
-
-
-
Method Detail
-
withSampler
@Deprecated public Tracer withSampler(Sampler sampler)
Deprecated.- Since:
- 4.19
-
newTrace
public Span newTrace()
Explicitly creates a new trace. The result will be a root span (no parent span ID).To implicitly create a new trace, or a span within an existing one, use
nextSpan()
.
-
joinSpan
public final Span joinSpan(TraceContext context)
Joining is re-using the same trace and span ids extracted from an incoming RPC request. This should not be used for messaging operations, asnextSpan(TraceContextOrSamplingFlags)
is a better choice.When this incoming context is sampled, we assume this is a shared span, one where the caller and the current tracer report to the same span IDs. If no sampling decision occurred yet, we have exclusive access to this span ID.
Here's an example of conditionally joining a span, depending on if a trace context was extracted from an incoming request.
extracted = extractor.extract(request); span = contextOrFlags.context() != null ? tracer.joinSpan(contextOrFlags.context()) : tracer.nextSpan(extracted);
Note: When
Propagation.Factory.supportsJoin()
is false, this will always fork a new child vianewChild(TraceContext)
.
-
newChild
public Span newChild(TraceContext parent)
Explicitly creates a child within an existing trace. The result will be have its parent ID set to the input's span ID. If a sampling decision has not yet been made, one will happen here.To implicitly create a new trace, or a span within an existing one, use
nextSpan()
.
-
nextSpan
public Span nextSpan(TraceContextOrSamplingFlags extracted)
This creates a new span based on parameters extracted from an incoming request. This will always result in a new span. If no trace identifiers were extracted, a span will be created based on the implicit context in the same manner asnextSpan()
. If a sampling decision has not yet been made, one will happen here.Ex.
extracted = extractor.extract(request); span = tracer.nextSpan(extracted);
Note: Unlike
joinSpan(TraceContext)
, this does not attempt to re-use extracted span IDs. This means the extracted context (if any) is the parent of the span returned.Note: If a context could be extracted from the input, that trace is resumed, not whatever the
currentSpan()
was. Make sure you re-applywithSpanInScope(Span)
so that data is written to the correct trace.
-
toSpan
public Span toSpan(TraceContext context)
Converts the context to a Span object after decorating it for propagation.This api is not advised for routine use. It is better to hold a reference to a span created elsewhere vs rely on implicit lookups.
-
withSpanInScope
public Tracer.SpanInScope withSpanInScope(@Nullable Span span)
Makes the given span the "current span" and returns an object that exits that scope on close. Calls tocurrentSpan()
andcurrentSpanCustomizer()
will affect this span until the return value is closed.The most convenient way to use this method is via the try-with-resources idiom. Ex.
// Assume a framework interceptor uses this method to set the inbound span as current try (SpanInScope ws = tracer.withSpanInScope(span)) { return inboundRequest.invoke(); // note: try-with-resources closes the scope *before* the catch block } catch (RuntimeException | Error e) { span.error(e); throw e; } finally { span.finish(); } // An unrelated framework interceptor can now lookup the correct parent for outbound requests Span parent = tracer.currentSpan() Span span = tracer.nextSpan().name("outbound").start(); // parent is implicitly looked up try (SpanInScope ws = tracer.withSpanInScope(span)) { return outboundRequest.invoke(); // note: try-with-resources closes the scope *before* the catch block } catch (RuntimeException | Error e) { span.error(e); throw e; } finally { span.finish(); }
When tracing in-process commands, prefer
startScopedSpan(String)
which scopes by default.Note: While downstream code might affect the span, calling this method, and calling close on the result have no effect on the input. For example, calling close on the result does not finish the span. Not only is it safe to call close, you must call close to end the scope, or risk leaking resources associated with the scope.
- Parameters:
span
- span to place into scope or null to clear the scope
-
currentSpanCustomizer
public SpanCustomizer currentSpanCustomizer()
Returns a customizer for current span in scope or noop if there isn't one.Unlike
CurrentSpanCustomizer
, this represents a single span. Accordingly, this reference should not be saved as a field. That said, it is more efficient to save this result as a method-local variable vs repeated calls.
-
currentSpan
@Nullable public Span currentSpan()
Returns the current span in scope or null if there isn't one.When entering user code, prefer
currentSpanCustomizer()
as it is a stable type and will never return null.
-
nextSpan
public Span nextSpan()
Returns a new child span if there's acurrentSpan()
or a new trace if there isn't.Prefer
startScopedSpan(String)
if you are tracing a synchronous function or code block.
-
startScopedSpan
public ScopedSpan startScopedSpan(String name)
Returns a new child span if there's acurrentSpan()
or a new trace if there isn't. The result is the "current span" untilScopedSpan.finish()
is called. Here's an example:ScopedSpan span = tracer.startScopedSpan("encode"); try { // The span is in "scope" so that downstream code such as loggers can see trace IDs return encoder.encode(); } catch (RuntimeException | Error e) { span.error(e); // Unless you handle exceptions, you might not know the operation failed! throw e; } finally { span.finish(); }
-
startScopedSpan
public <T> ScopedSpan startScopedSpan(String name, SamplerFunction<T> samplerFunction, T arg)
LikestartScopedSpan(String)
except when there is no trace in process, the samplertriggers
against the supplied argument.- Parameters:
name
- thespan name
samplerFunction
- invoked if there's nocurrent trace
arg
- parameter toSamplerFunction.trySample(Object)
- Since:
- 5.8
- See Also:
nextSpan(SamplerFunction, Object)
-
nextSpan
public <T> Span nextSpan(SamplerFunction<T> samplerFunction, T arg)
LikenextSpan()
except when there is no trace in process, the samplertriggers
against the supplied argument.- Parameters:
samplerFunction
- invoked if there's nocurrent trace
arg
- parameter toSamplerFunction.trySample(Object)
- Since:
- 5.8
- See Also:
startScopedSpan(String, SamplerFunction, Object)
,nextSpan(TraceContextOrSamplingFlags)
-
nextSpanWithParent
public <T> Span nextSpanWithParent(SamplerFunction<T> samplerFunction, T arg, @Nullable TraceContext parent)
LikenextSpan(SamplerFunction, Object)
except this controls the parent context explicitly. This is useful when an invocation context is propagated manually, commonly the case with asynchronous client frameworks.- Parameters:
samplerFunction
- invoked if there's nocurrent trace
arg
- parameter toSamplerFunction.trySample(Object)
parent
- of the new span, ornull
if it should have no parent- Since:
- 5.10
- See Also:
nextSpan(SamplerFunction, Object)
-
startScopedSpanWithParent
public ScopedSpan startScopedSpanWithParent(String name, @Nullable TraceContext parent)
Same asstartScopedSpan(String)
, except ignores the current trace context.Use this when you are creating a scoped span in a method block where the parent was created. You can also use this to force a new trace by passing null parent.
-
-