Class FinishedSpanHandler
public abstract class FinishedSpanHandler extends Object
no-op
.
Sampled spans
hit this stage before reporting to Zipkin.
This means changes to the mutable span will reflect in reported data.
When Zipkin's reporter is Reporter.NOOP
or the context is
unsampled, this will still receive spans where SamplingFlags.sampledLocal()
is true.
- Since:
- 5.4
- See Also:
alwaysSampleLocal()
-
Field Summary
Fields Modifier and Type Field Description static FinishedSpanHandler
NOOP
Use to avoid comparing against null references -
Constructor Summary
Constructors Constructor Description FinishedSpanHandler()
-
Method Summary
Modifier and Type Method Description boolean
alwaysSampleLocal()
When true, all spans become real spans even if they aren't sampled remotely.abstract boolean
handle(TraceContext context, MutableSpan span)
This is invoked after a span is finished, allowing data to be modified or reported out of process.boolean
supportsOrphans()
Normally,handle(TraceContext, MutableSpan)
is only called upon explicit termination of a span:Span.finish()
,Span.finish(long)
orSpan.flush()
.
-
Field Details
-
NOOP
Use to avoid comparing against null references
-
-
Constructor Details
-
FinishedSpanHandler
public FinishedSpanHandler()
-
-
Method Details
-
handle
This is invoked after a span is finished, allowing data to be modified or reported out of process. A return value of false means the span should be dropped completely from the stream.Changes to the input span are visible by later finished span handlers. One reason to change the input is to align tags, so that correlation occurs. For example, some may clean the tag "http.path" knowing downstream handlers such as zipkin reporting have the same value.
Returning false is the same effect as if
Span.abandon()
was called. Implementations should be careful when returning false as it can lead to broken traces. Acceptable use cases are when the span is a leaf, for example a client call to an uninstrumented database, or a server call which is known to terminate in-process (for example, health-checks). Prefer an instrumentation policy approach to this mechanism as it results in less overhead.Implementations should not hold a reference to it after this method returns. This is to allow object recycling.
- Parameters:
context
- the trace context which isSamplingFlags.sampled()
orSamplingFlags.sampledLocal()
. This includes identifiers and potentiallyextra propagated data
such as extended sampling configuration.span
- a mutable object including all data recorded with span apis. Modifications are visible to later handlers, including Zipkin.- Returns:
- true retains the span, and should almost always be used. false drops the span, making it invisible to later handlers such as Zipkin.
- See Also:
If you are scrubbing personal information, consider supporting orphans.
-
supportsOrphans
public boolean supportsOrphans()Normally,handle(TraceContext, MutableSpan)
is only called upon explicit termination of a span:Span.finish()
,Span.finish(long)
orSpan.flush()
. When this method returns true, the callback will also receive data orphaned due to spans being never terminated or data added after termination. It is important to understand this, especially if your handler is performing work like redaction. This sort of work needs to happen on all data, not just the success paths.What is an orphaned span?
Brave adds an
annotation
"brave.flush" when data remains associated with a span when it is garbage collected. This is almost always a bug. For example, callingSpan.tag(String, String)
after callingSpan.finish()
, or callingTracer.nextSpan()
yet never using the result. To track down bugs like this, set the loggerPendingSpans
to FINE level.Why handle orphaned spans?
Use cases for handling orphans include redaction, trimming the "brave.flush" annotation, logging a different way than default, or incrementing bug counters. For example, you could use the same credit card cleaner here as you do on the success path.
What shouldn't handle orphaned spans?
As this is related to bugs, no assumptions can be made about span count etc. For example, one span context can result in many calls to this handler, unrelated to the actual operation performed. Handlers that redact or clean data work for normal spans and orphans. However, aggregation handlers, such as dependency linkers or success/fail counters, can create problems if used against orphaned spans.
Implementation
By default, this method returns false, suggesting the implementation is not designed to also process orphans. Return true to indicate otherwise. Whichever choice should be constant. In other words do not sometimes return false and other times true, as the value is only read once.
Considerations for implementing
handle
When this method returns true, the
handle method
is both invoked for normal spans and also orphaned ones. The following apply when handling orphans:The
TraceContext
parameter contains minimal information, including lookup ids (traceId, spanId and localRootId) and sampling status."extra"
will be empty.The
MutableSpan
parameterincludes the annotation
"brave.flush", and whatever state was orphaned (ex a tag).- Since:
- 5.7
-
alwaysSampleLocal
public boolean alwaysSampleLocal()When true, all spans become real spans even if they aren't sampled remotely. This allows finished span handlers (such as metrics) to consider attributes that are not always visible before-the-fact, such as http paths. Defaults to false and affectsSamplingFlags.sampledLocal()
.- See Also:
handle(TraceContext, MutableSpan)
-