Class Tracer
public class Tracer extends Object
// 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 classTracer.SpanInScopeA span remains in the scope it was bound to until close is called. -
Method Summary
Modifier and Type Method Description SpancurrentSpan()Returns the current span in scope or null if there isn't one.SpanCustomizercurrentSpanCustomizer()Returns a customizer for current span in scope or noop if there isn't one.SpanjoinSpan(TraceContext context)Joining is re-using the same trace and span ids extracted from an incoming RPC request.SpannewChild(TraceContext parent)Explicitly creates a child within an existing trace.SpannewTrace()Explicitly creates a new trace.SpannextSpan()Returns a new child span if there's acurrentSpan()or a new trace if there isn't.SpannextSpan(TraceContextOrSamplingFlags extracted)This creates a new span based on parameters extracted from an incoming request.<T> SpannextSpan(SamplerFunction<T> samplerFunction, T arg)LikenextSpan()except when there is no trace in process, the samplertriggersagainst the supplied argument.<T> SpannextSpanWithParent(SamplerFunction<T> samplerFunction, T arg, TraceContext parent)LikenextSpan(SamplerFunction, Object)except this controls the parent context explicitly.ScopedSpanstartScopedSpan(String name)Returns a new child span if there's acurrentSpan()or a new trace if there isn't.<T> ScopedSpanstartScopedSpan(String name, SamplerFunction<T> samplerFunction, T arg)LikestartScopedSpan(String)except when there is no trace in process, the samplertriggersagainst the supplied argument.ScopedSpanstartScopedSpanWithParent(String name, TraceContext parent)Same asstartScopedSpan(String), except ignores the current trace context.SpantoSpan(TraceContext context)Converts the context to a Span object after decorating it for propagationStringtoString()TracerwithSampler(Sampler sampler)Deprecated.Tracer.SpanInScopewithSpanInScope(Span span)Makes the given span the "current span" and returns an object that exits that scope on close.
-
Method Details
-
withSampler
Deprecated.- Since:
- 4.19
-
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
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
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
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
Converts the context to a Span object after decorating it for propagation -
withSpanInScope
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
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
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
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
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
LikestartScopedSpan(String)except when there is no trace in process, the samplertriggersagainst the supplied argument.- Parameters:
name- thespan namesamplerFunction- invoked if there's nocurrent tracearg- parameter toSamplerFunction.trySample(Object)- Since:
- 5.8
- See Also:
nextSpan(SamplerFunction, Object)
-
nextSpan
LikenextSpan()except when there is no trace in process, the samplertriggersagainst the supplied argument.- Parameters:
samplerFunction- invoked if there's nocurrent tracearg- 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 tracearg- parameter toSamplerFunction.trySample(Object)parent- of the new span, ornullif it should have no parent- Since:
- 5.10
- See Also:
nextSpan(SamplerFunction, Object)
-
startScopedSpanWithParent
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.
-
toString
-