Package brave.handler

Class SpanHandler

Direct Known Subclasses:

public abstract class SpanHandler
extends Object
This tracks one recording of a TraceContext. Common implementations include span reporting (ex to Zipkin) and data manipulation, such as redaction for security purposes.

Relationship to Span lifecycle

The pair of begin(brave.propagation.TraceContext, brave.handler.MutableSpan, brave.propagation.TraceContext) and end(brave.propagation.TraceContext, brave.handler.MutableSpan, brave.handler.SpanHandler.Cause) seems the same as the span lifecycle. In most cases it will be the same, but you cannot assume this.

A TraceContext could be recorded twice, for example, if a long operation began, called Span.flush() (recording 1) and later called Span.finish() (recording 2). A TraceContext could be abrupted by garbage collection resulting in a SpanHandler.Cause.ABANDONED. A user could even abandon a span without recording anything!

Collectors that process finished spans will need to look at the {link Cause} and MutableSpan collected. For example, SpanHandler.Cause.FINISHED is usually a good enough heuristic to find complete spans.

Advanced Notes

It is important to do work quickly as callbacks are run on the same thread as application code. However, do not mutate MutableSpan between callbacks, as it is not thread safe.

The TraceContext and MutableSpan parameter from begin(brave.propagation.TraceContext, brave.handler.MutableSpan, brave.propagation.TraceContext) will be the same reference for end(brave.propagation.TraceContext, brave.handler.MutableSpan, brave.handler.SpanHandler.Cause).

If caching the context or span parameters between callbacks, consider a WeakReference to avoid holding up garbage collection.

The begin(brave.propagation.TraceContext, brave.handler.MutableSpan, brave.propagation.TraceContext) callback primarily supports tracking of children, or partitioning of data for backend that needs to see an entire local root.