API: vendor agnostic interfaces, user should call only API interfaces
SDK: implementations
IMPORTANT !!!!:
When makeCurrent() must close!! (it returns a Scope, must close the scope. Use try{ to make sure)
When startSpan()
IMPORTANT: This method can be called only once per SpanBuilder instance and as the last method called. After this method is called calling any method is undefined behavior.
Users must manually call Span.end() to end this Span.
Use try.... finally to guarantee this
Span:
create root span:
when there is no current context
when specifically call setNoParent() before calling startSpan()
create child span:
when there is current context and call startSpan() without first calling setNoParent()
when explicitly call setParent(Context context)
built from tracer
this creates a recording (useable to record attributes) span (vs. extracted / propagated span)
example: Span span = tracer.spanBuilder("my span").startSpan();
startSpan() must be the last method called, and must manually call stopSpan();
By default, the value of Span.current() at startSpan() time will be used as parent. (meaning if there is a current span, startStan() will obtain a child span)
call setNoParent() will create a root span
span is stored in context under context.get(SpanContextKey.KEY)
Span.current() gets the span stored in Context.current() falling back to INVALID
SpanContext:
SpanContext contains:
traceId (must conform to valid format, use TraceId.from)
spanId (must conform to valid format, use SpanId.from)
TraceFlags (A valid trace flags is a byte or 2 character lowercase hex (base16) String. These options are propagated to all child spans. These determine features such as whether a Span should be traced.)
ImmutableTraceFlags contains static instances
DEFAULT (00)
SAMPLED (01)
TraceState
basically a key value map, both String
carries tracing-system specific context, for vendor-specific additional information
Serialising / DeSerialising SpanContext (propagation)
Default TextMapPropagator is the io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
saves / extracts string "tracerParent" under key "traceparent"
format of "tracerParent", which encodes the span's traceId and spanId, is:
version (2-digit) - traceId - spanId - firstTraceFlagChar secondTraceFlagChar
version - in Honeycomb SDK version is fixed "00"
flags see above
Finally SpanContext is created as (when without state)
TraceFlags traceFlags =
TraceFlags.fromByte(
OtelEncodingUtils.byteFromBase16(firstTraceFlagsChar, secondTraceFlagsChar));
return SpanContext.createFromRemoteParent(traceId, spanId, traceFlags, TraceState.getDefault());
save / extract string traceStateHeader under key "tracestate"
format of "traceStateHeader":
space separated entries, entry delimited by "=", e.g. "key=value"
This conforms to the W3C Trace Context
Extracted span is a no-functionality span (span can be serialised / remote propagated as a parent, but cannot "become alive again" in a downstream service)
ONLY used to create children
actual class is "PropagatedSpan"
Use Span.wrap(spanContext) to create span, then set as current context, then to create child span
this creates a non-recording span that has no functionality
usage of this non-recording span:
Context.current().with(theNonRecordingSpan) // stores this span into a context (i.e. Context.current()) to obtain a new context
then make it current and build a children from it (see https://opentelemetry.io/docs/instrumentation/java/manual/#context-propagation)
try (Scope scope = extractedContext.makeCurrent()) { // make the extracted non-recording span current, use try to guarantee closure
or use setParent() method of builder before startSpan()
W3C Trace Context (https://www.w3.org/TR/trace-context/)