Class MutableSpan
- java.lang.Object
-
- brave.handler.MutableSpan
-
- All Implemented Interfaces:
Cloneable
public final class MutableSpan extends Object implements Cloneable
This represents a span except for itsTraceContext. It is mutable, for late adjustments.Notes
Between
SpanHandler.begin(TraceContext, MutableSpan, TraceContext)andSpanHandler.end(TraceContext, MutableSpan, SpanHandler.Cause), Brave owns this reference, synchronizing where necessary as updates come from different application threads.Upon end, Brave no longer makes updates. It invokes each
SpanHandler, one-by-one on the same thread. This means subsequent handlers do not have to synchronize to view updates from a prior one. However, it does imply they must make mutations on the same thread.In other words, this type is not thread safe. If you need to mutate this span in a different thread, use the copy constructor.
MutableSpan.error() vs MutableSpan.tag("error")
Iftag(String)returns a result for "error", it was from a layered api, instrumentation or the user.error()is usually an uncaught exception and does not imply there's a tag "error".Here are examples of a span with
error(), but no "error" tag:brave.Span.error(new OutOfMemoryError()) -> MutableSpan.error(new OutOfMemoryError())brave.Span.error(new RpcException()) -> MutableSpan.error(new RpcException())brave.Span.error(new NullPointerException()) -> MutableSpan.error(new NullPointerException())
The above are examples of exceptions that users typically do not process, so are unlikely to parse into an "error" tag. The opposite is also true as not all errors are derived from
Throwable. Particularly, RPC frameworks often do not use exceptions as error signals.Here are examples of a span with an "error" tag, but no
error():io.opentracing.Span.tag(ERROR, true) -> MutableSpan.tag("error", "true")brave.SpanCustomizer.tag("error", "") -> MutableSpan.tag("error", "")brave.Span.tag("error", "CANCELLED") -> MutableSpan.tag("error", "CANCELLED")
The above examples are using in-band apis in Brave.
SpanHandleris after the fact. Since there is no default "error" tag, span handlers here can tell the difference between explicitly set error messages, and what's needed by their format. For example, those only looking at Zipkin clones may forget thaterror()exists for custom formats including metrics!Here are examples of
SpanHandler.end(TraceContext, MutableSpan, SpanHandler.Cause)implementations that process errors:MutableSpan.tag("error", "")to redact the error message from ZipkinMutableSpan.error() -> MutableSpan.tag("exception", normalized)to match metrics dimensionMutableSpan.error() -> CustomFormat.stackTracefor sophisticated trace formats
In summary, Brave intentionally does not default an "error"
tag(String)fromerror(). This allowsSpanHandlerinstances that report data be as simple as an error bit, or advanced enough to keep a stacktrace and also a user tag.- Since:
- 5.4
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interfaceMutableSpan.AnnotationConsumer<T>static interfaceMutableSpan.AnnotationUpdaterstatic interfaceMutableSpan.TagConsumer<T>static interfaceMutableSpan.TagUpdater
-
Constructor Summary
Constructors Constructor Description MutableSpan()MutableSpan(MutableSpan toCopy)MutableSpan(TraceContext context, MutableSpan defaults)Creates a new instance from the given context, and defaults in the span.
-
Method Summary
All Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description voidannotate(long timestamp, String value)Calling this adds an annotation, such as done inSpanCustomizer.annotate(String).intannotationCount()Collection<Map.Entry<Long,String>>annotations()A read-only view of the current annotations as a collection of(epochMicroseconds -> value).longannotationTimestampAt(int i)Returns the epoch microseconds of the annotation at the givenindexor throwsIndexOutOfBoundsExceptionif the index is invalid.StringannotationValueAt(int i)Returns the possibly empty value of the annotation at the givenindexor throwsIndexOutOfBoundsExceptionif the index is invalid.booleancontainsAnnotation(String value)Returns true if an annotation with the given value exists in this span.booleandebug()Returns true if the context was debug.booleanequals(Object o)Throwableerror()Returns the error ornull.voiderror(Throwable error)Calling this overrides any previous value, such as {@link brave.Span#error(Throwable).longfinishTimestamp()Returns the span finish timestamp or zero.voidfinishTimestamp(long finishTimestamp)Calling this overrides any previous value, such asSpan.finish(long)orScopedSpan.finish().<T> voidforEachAnnotation(MutableSpan.AnnotationConsumer<T> annotationConsumer, T target)Iterates over all annotations for purposes such as copying values.voidforEachAnnotation(MutableSpan.AnnotationUpdater annotationUpdater)Allows you to update or drop annotations for purposes such as redaction.<T> voidforEachTag(MutableSpan.TagConsumer<T> tagConsumer, T target)Iterates over all tags for purposes such as copying values.voidforEachTag(MutableSpan.TagUpdater tagUpdater)Allows you to update or drop tags for purposes such as redaction.inthashCode()Stringid()Returns the span ID.voidid(String id)Calling this overrides the span ID.booleanisEmpty()Deprecated.Since 5.12 useequals(Object)against a base value.Span.Kindkind()Returns the span kind ornull.voidkind(Span.Kind kind)Calling this overrides any previous value, such as {@link brave.Span#kind(Kind).StringlocalIp()Returns the primary IP address associated with this service ornull.booleanlocalIp(String localIp)Calling this overrides any previous value, such asTracing.Builder.localIp(String).intlocalPort()Returns the primary listen port associated with this service or zero.voidlocalPort(int localPort)Calling this overrides any previous value, such asTracing.Builder.localPort(int).StringlocalRootId()Returns the local root IDvoidlocalRootId(String localRootId)Calling this overrides the local root ID.StringlocalServiceName()Returns the label of this node in the service graph ornull.voidlocalServiceName(String localServiceName)Calling this overrides any previous value, such asTracing.Builder.localServiceName(String).Stringname()Returns the span name ornullvoidname(String name)Calling this overrides any previous value, such asSpanCustomizer.name(String).StringparentId()Returns the parent ID ornullvoidparentId(String parentId)Calling this overrides the parent ID.StringremoteIp()Returns the IP of the remote service ornull.voidremoteIp(String remoteIp)Calling this overrides any previous value, such as fromSpan.remoteIpAndPort(String, int).booleanremoteIpAndPort(String remoteIp, int remotePort)WhenremoteIpis notnull, calling this overrides any previous value, such asSpan.remoteIpAndPort(String, int).intremotePort()Returns the port of the remote service or zero.voidremotePort(int remotePort)Calling this overrides any previous value, such as fromSpan.remoteIpAndPort(String, int).StringremoteServiceName()Returns the primary label of the remote service ornull.voidremoteServiceName(String remoteServiceName)Calling this overrides any previous value, such asSpan.remoteServiceName(String).StringremoveTag(String key)Removes and returns the last tag value associated with the key or returnsnullif it was never set.voidsetDebug()Calling this is unexpected as it should only be initialized bySamplingFlags.debug().voidsetShared()Calling this is unexpected as it should only be initialized byTraceContext.shared().booleanshared()Returns true if the context was shared.longstartTimestamp()Returns the span start timestamp or zero.voidstartTimestamp(long startTimestamp)Calling this overrides any previous value, such asSpan.start(long)orTracer.startScopedSpan(String).Stringtag(String key)Returns the last tag value associated with the key ornull.voidtag(String key, String value)Calling this overrides any previous value, such asSpanCustomizer.tag(String, String).inttagCount()StringtagKeyAt(int i)Returns the tag key at the givenindexor throwsIndexOutOfBoundsExceptionif the index is invalid.Map<String,String>tags()A read-only view of the current tags a map.StringtagValueAt(int i)Returns the possibly empty value at the givenindexor throwsIndexOutOfBoundsExceptionif the index is invalid.StringtoString()StringtraceId()Returns the trace IDvoidtraceId(String traceId)Calling this overrides the trace ID.voidunsetDebug()voidunsetShared()
-
-
-
Constructor Detail
-
MutableSpan
public MutableSpan()
- Since:
- 5.4
-
MutableSpan
public MutableSpan(TraceContext context, @Nullable MutableSpan defaults)
Creates a new instance from the given context, and defaults in the span.Note: It is unexpected to have context properties also in the span defaults. The context will win in this case, as opposed to throwing an exception.
- Since:
- 5.12
-
MutableSpan
public MutableSpan(MutableSpan toCopy)
- Since:
- 5.12
-
-
Method Detail
-
isEmpty
@Deprecated public boolean isEmpty()
Deprecated.Since 5.12 useequals(Object)against a base value.- Since:
- 5.4
-
traceId
public void traceId(String traceId)
Calling this overrides the trace ID.- See Also:
traceId()
-
localRootId
@Nullable public String localRootId()
Returns the local root ID- Since:
- 5.12
-
localRootId
public void localRootId(String localRootId)
Calling this overrides the local root ID.- See Also:
localRootId()
-
parentId
public void parentId(@Nullable String parentId)Calling this overrides the parent ID.- See Also:
parentId()
-
name
public void name(@Nullable String name)Calling this overrides any previous value, such asSpanCustomizer.name(String).- See Also:
name()
-
startTimestamp
public long startTimestamp()
Returns the span start timestamp or zero.- Since:
- 5.4
-
startTimestamp
public void startTimestamp(long startTimestamp)
Calling this overrides any previous value, such asSpan.start(long)orTracer.startScopedSpan(String).- See Also:
startTimestamp()
-
finishTimestamp
public long finishTimestamp()
Returns the span finish timestamp or zero.- Since:
- 5.4
-
finishTimestamp
public void finishTimestamp(long finishTimestamp)
Calling this overrides any previous value, such asSpan.finish(long)orScopedSpan.finish().- See Also:
finishTimestamp()
-
kind
public void kind(@Nullable Span.Kind kind)Calling this overrides any previous value, such as {@link brave.Span#kind(Kind).- See Also:
kind()
-
localServiceName
@Nullable public String localServiceName()
Returns the label of this node in the service graph ornull.Note: This is initialized from
Tracing.Builder.localServiceName(String). handlers that want to conditionally replace the value should compare against the same value given to the tracing component.- Since:
- 5.4
-
localServiceName
public void localServiceName(@Nullable String localServiceName)Calling this overrides any previous value, such asTracing.Builder.localServiceName(String).- See Also:
localServiceName()
-
localIp
@Nullable public String localIp()
Returns the primary IP address associated with this service ornull.Note: This is initialized from
Tracing.Builder.localIp(String). handlers that want to conditionally replace the value should compare against the same value given to the tracing component.- Since:
- 5.4
-
localIp
public boolean localIp(@Nullable String localIp)Calling this overrides any previous value, such asTracing.Builder.localIp(String).- See Also:
localIp()
-
localPort
public int localPort()
Returns the primary listen port associated with this service or zero.Note: This is initialized from
Tracing.Builder.localPort(int). handlers that want to conditionally replace the value should compare against the same value given to the tracing component.- Since:
- 5.4
-
localPort
public void localPort(int localPort)
Calling this overrides any previous value, such asTracing.Builder.localPort(int).- See Also:
localPort()
-
remoteServiceName
@Nullable public String remoteServiceName()
Returns the primary label of the remote service ornull.- Since:
- 5.4
- See Also:
remoteIp(),remotePort()
-
remoteServiceName
public void remoteServiceName(@Nullable String remoteServiceName)Calling this overrides any previous value, such asSpan.remoteServiceName(String).- See Also:
remoteServiceName()
-
remoteIp
@Nullable public String remoteIp()
Returns the IP of the remote service ornull.- Since:
- 5.4
- See Also:
remoteServiceName(),remotePort()
-
remoteIp
public void remoteIp(@Nullable String remoteIp)Calling this overrides any previous value, such as fromSpan.remoteIpAndPort(String, int).- See Also:
remoteIpAndPort(String, int)
-
remotePort
public int remotePort()
Returns the port of the remote service or zero.- Since:
- 5.4
- See Also:
remoteServiceName(),remoteIp()
-
remotePort
public void remotePort(int remotePort)
Calling this overrides any previous value, such as fromSpan.remoteIpAndPort(String, int).- See Also:
remoteIpAndPort(String, int)
-
remoteIpAndPort
public boolean remoteIpAndPort(@Nullable String remoteIp, int remotePort)WhenremoteIpis notnull, calling this overrides any previous value, such asSpan.remoteIpAndPort(String, int).- See Also:
remoteServiceName(),remoteIp(),remotePort()
-
error
public void error(@Nullable Throwable error)Calling this overrides any previous value, such as {@link brave.Span#error(Throwable).- See Also:
error()
-
debug
public boolean debug()
Returns true if the context was debug.- Since:
- 5.4
-
setDebug
public void setDebug()
Calling this is unexpected as it should only be initialized bySamplingFlags.debug().- Since:
- 5.4
- See Also:
debug(),unsetDebug()
-
unsetDebug
public void unsetDebug()
- Since:
- 5.12
- See Also:
setDebug()
-
shared
public boolean shared()
Returns true if the context was shared.- Since:
- 5.4
-
setShared
public void setShared()
Calling this is unexpected as it should only be initialized byTraceContext.shared().- Since:
- 5.4
- See Also:
shared(),unsetShared()
-
unsetShared
public void unsetShared()
- Since:
- 5.12
- See Also:
setShared()
-
annotationCount
public int annotationCount()
- Since:
- 5.12
- See Also:
annotationTimestampAt(int),annotationValueAt(int)
-
annotationTimestampAt
public long annotationTimestampAt(int i)
Returns the epoch microseconds of the annotation at the givenindexor throwsIndexOutOfBoundsExceptionif the index is invalid.
-
annotationValueAt
public String annotationValueAt(int i)
Returns the possibly empty value of the annotation at the givenindexor throwsIndexOutOfBoundsExceptionif the index is invalid.
-
annotations
public Collection<Map.Entry<Long,String>> annotations()
A read-only view of the current annotations as a collection of(epochMicroseconds -> value).- Since:
- 5.12
- See Also:
forEachAnnotation(AnnotationConsumer, Object)
-
forEachAnnotation
public <T> void forEachAnnotation(MutableSpan.AnnotationConsumer<T> annotationConsumer, T target)
Iterates over all annotations for purposes such as copying values. Unlikeannotations(), using this is allocation free.Ex.
// During initialization, cache an annotation consumer function: annotationConsumer = (target, timestamp, value) -> target.add(tuple(timestamp, value)); // Re-use that function while processing spans. List<Tuple<Long, String>> list = new ArrayList<>(); span.forEachAnnotation(annotationConsumer, list);- Since:
- 5.4
- See Also:
forEachAnnotation(AnnotationUpdater),annotations()
-
forEachAnnotation
public void forEachAnnotation(MutableSpan.AnnotationUpdater annotationUpdater)
Allows you to update or drop annotations for purposes such as redaction.Ex.
// During initialization, cache an annotation updater function: annotationRedacter = (timestamp, value) -> badWords.contains(value) ? null : value; // Re-use that function while processing spans. span.forEachAnnotation(annotationRedacter);- Since:
- 5.4
- See Also:
forEachAnnotation(AnnotationConsumer, Object)
-
containsAnnotation
public boolean containsAnnotation(String value)
Returns true if an annotation with the given value exists in this span.- Since:
- 5.4
- See Also:
forEachAnnotation(AnnotationConsumer, Object),forEachAnnotation(AnnotationUpdater)
-
annotate
public void annotate(long timestamp, String value)Calling this adds an annotation, such as done inSpanCustomizer.annotate(String).- Since:
- 5.4
- See Also:
forEachAnnotation(AnnotationConsumer, Object),forEachAnnotation(AnnotationUpdater)
-
tagCount
public int tagCount()
- Since:
- 5.12
- See Also:
tagKeyAt(int),tagValueAt(int)
-
tagKeyAt
public String tagKeyAt(int i)
Returns the tag key at the givenindexor throwsIndexOutOfBoundsExceptionif the index is invalid.
-
tagValueAt
public String tagValueAt(int i)
Returns the possibly empty value at the givenindexor throwsIndexOutOfBoundsExceptionif the index is invalid.
-
tags
public Map<String,String> tags()
A read-only view of the current tags a map.- Since:
- 5.12
- See Also:
forEachTag(TagConsumer, Object)
-
tag
@Nullable public String tag(String key)
Returns the last tag value associated with the key ornull.- Since:
- 5.4
-
removeTag
@Nullable public String removeTag(String key)
Removes and returns the last tag value associated with the key or returnsnullif it was never set.Ex. to remove any tag named "remoteServiceName" and set it as
remoteServiceName(String)instead:String remoteServiceName = span.removeTag("peer.service"); if (remoteServiceName != null) span.remoteServiceName(remoteServiceName);- Since:
- 5.12
-
forEachTag
public <T> void forEachTag(MutableSpan.TagConsumer<T> tagConsumer, T target)
Iterates over all tags for purposes such as copying values. Unliketags(), using this is allocation free.Ex.
Map<String, String> tags = new LinkedHashMap<>(); span.forEachTag(Map::put, tags);- Since:
- 5.4
- See Also:
forEachTag(TagUpdater),tag(String),tags()
-
forEachTag
public void forEachTag(MutableSpan.TagUpdater tagUpdater)
Allows you to update or drop tags for purposes such as redaction.Ex.
// During initialization, cache an tag updater function: tagRedacter = (key, value) -> badWords.contains(value) ? null : value; // Re-use that function while processing spans. span.forEachTag(tagRedacter);- Since:
- 5.4
- See Also:
forEachTag(TagConsumer, Object),tag(String)
-
tag
public void tag(String key, String value)
Calling this overrides any previous value, such asSpanCustomizer.tag(String, String).- See Also:
tag(String)
-
-