Tracer { public Span nextSpan(TraceContextOrSamplingFlags extracted) { if (extracted == null) throw new NullPointerException("extracted == null"); TraceContext context = extracted.context(); if (context != null) return newChild(context); TraceIdContext traceIdContext = extracted.traceIdContext(); if (traceIdContext != null) { return _toSpan(null, decorateContext( InternalPropagation.instance.flags(extracted.traceIdContext()), traceIdContext.traceIdHigh(), traceIdContext.traceId(), 0L, 0L, 0L, extracted.extra() )); } SamplingFlags samplingFlags = extracted.samplingFlags(); List<Object> extra = extracted.extra(); TraceContext parent = currentTraceContext.get(); int flags; long traceIdHigh = 0L, traceId = 0L, localRootId = 0L, spanId = 0L; if (parent != null) { flags = InternalPropagation.instance.flags(parent); traceIdHigh = parent.traceIdHigh(); traceId = parent.traceId(); localRootId = parent.localRootId(); spanId = parent.spanId(); extra = concat(extra, parent.extra()); } else { flags = InternalPropagation.instance.flags(samplingFlags); } return _toSpan(parent, decorateContext(flags, traceIdHigh, traceId, localRootId, spanId, 0L, extra)); } Tracer(
    Clock clock,
    Propagation.Factory propagationFactory,
    SpanHandler spanHandler,
    PendingSpans pendingSpans,
    Sampler sampler,
    CurrentTraceContext currentTraceContext,
    boolean traceId128Bit,
    boolean supportsJoin,
    boolean alwaysSampleLocal,
    AtomicBoolean noop
  ); @Deprecated Tracer withSampler(Sampler sampler); Span newTrace(); final Span joinSpan(TraceContext context); Span newChild(TraceContext parent); Span nextSpan(TraceContextOrSamplingFlags extracted); Span toSpan(TraceContext context); SpanInScope withSpanInScope(@Nullable Span span); SpanCustomizer currentSpanCustomizer(); @Nullable Span currentSpan(); Span nextSpan(); ScopedSpan startScopedSpan(String name); ScopedSpan startScopedSpan(String name, SamplerFunction<T> samplerFunction, T arg); Span nextSpan(SamplerFunction<T> samplerFunction, T arg); Span nextSpanWithParent(SamplerFunction<T> samplerFunction, T arg,
    @Nullable TraceContext parent); ScopedSpan startScopedSpanWithParent(String name, @Nullable TraceContext parent); @Override String toString();  }
@Test public void nextSpan_defaultsToMakeNewTrace() { assertThat(tracer.nextSpan().context().parentId()).isNull(); assertThat(tracer.nextSpan(deferDecision(), false).context().parentId()).isNull(); }
@Test public void nextSpan_usesSampler() { assertThat(tracer.nextSpan().context().parentId()).isNull(); assertThat(tracer.nextSpan(neverSample(), false).context().sampled()).isFalse(); }
@Test public void nextSpan_extractedNothing_defaultsToMakeNewTrace() { Span nextSpan = tracer.nextSpan(TraceContextOrSamplingFlags.create(EMPTY)); assertThat(nextSpan.context().parentId()) .isNull(); }
@Test public void nextSpan_extractedExtra_newTrace() { TraceContextOrSamplingFlags extracted = TraceContextOrSamplingFlags.newBuilder(EMPTY).addExtra(1L).build(); assertThat(tracer.nextSpan(extracted).context().extra()) .containsExactly(1L); }
@Test public void nextSpan_extractedTraceId() { TraceIdContext traceIdContext = TraceIdContext.newBuilder().traceId(1L).build(); TraceContextOrSamplingFlags extracted = TraceContextOrSamplingFlags.create(traceIdContext); assertThat(tracer.nextSpan(extracted).context().traceId()) .isEqualTo(1L); }
@Test public void nextSpan_extractedTraceId_extra() { TraceIdContext traceIdContext = TraceIdContext.newBuilder().traceId(1L).build(); TraceContextOrSamplingFlags extracted = TraceContextOrSamplingFlags.newBuilder(traceIdContext) .addExtra(1L).build(); assertThat(tracer.nextSpan(extracted).context().extra()) .containsExactly(1L); }
@Test public void nextSpan_extractedTraceContext() { TraceContextOrSamplingFlags extracted = TraceContextOrSamplingFlags.create(context); assertThat(tracer.nextSpan(extracted).context()) .extracting(TraceContext::traceId, TraceContext::parentId) .containsExactly(1L, 2L); }
@Test public void nextSpan_extractedTraceContext_extra() { TraceContextOrSamplingFlags extracted = TraceContextOrSamplingFlags.newBuilder(context) .addExtra(1L).build(); assertThat(tracer.nextSpan(extracted).context().extra()) .contains(1L); }
@Test public void nextSpan_fromFlags_resultantSpanIsLocalRoot() { Span span = tracer.nextSpan(TraceContextOrSamplingFlags.create(SamplingFlags.SAMPLED)); assertThat(span.context().spanId()).isEqualTo(span.context().localRootId()); assertThat(span.context().isLocalRoot()).isTrue(); }
@Test public void nextSpan_fromContext_resultantSpanIsLocalRoot() { TraceContext context = TraceContext.newBuilder().traceId(1).spanId(2).build(); Span span = tracer.nextSpan(TraceContextOrSamplingFlags.create(context)); assertThat(span.context().spanId()).isEqualTo(span.context().localRootId()); assertThat(span.context().isLocalRoot()).isTrue(); Span child = tracer.nextSpan(TraceContextOrSamplingFlags.create(span.context())); assertThat(child.context().localRootId()).isEqualTo(span.context().localRootId()); assertThat(child.context().isLocalRoot()).isFalse(); }
@Test public void nextSpan_fromIdContext_resultantSpanIsLocalRoot() { TraceIdContext context = TraceIdContext.newBuilder().traceId(1).build(); Span span = tracer.nextSpan(TraceContextOrSamplingFlags.create(context)); assertThat(span.context().spanId()).isEqualTo(span.context().localRootId()); assertThat(span.context().isLocalRoot()).isTrue(); }
@Test public void localRootId_nextSpan_notYetSampled() { TraceContext context1 = TraceContext.newBuilder().traceId(1).spanId(2).build(); TraceContext context2 = TraceContext.newBuilder().traceId(1).spanId(3).build(); localRootId(context1, context2, ctx -> tracer.nextSpan(ctx)); }
@Test public void localRootId_nextSpan_notSampled() { TraceContext context1 = TraceContext.newBuilder().traceId(1).spanId(2).sampled(false).build(); TraceContext context2 = TraceContext.newBuilder().traceId(1).spanId(3).sampled(false).build(); localRootId(context1, context2, ctx -> tracer.nextSpan(ctx)); }
@Test public void localRootId_nextSpan_sampled() { TraceContext context1 = TraceContext.newBuilder().traceId(1).spanId(2).sampled(true).build(); TraceContext context2 = TraceContext.newBuilder().traceId(1).spanId(3).sampled(true).build(); localRootId(context1, context2, ctx -> tracer.nextSpan(ctx)); }
@Test public void localRootId_nextSpan_ids_notYetSampled() { TraceIdContext context1 = TraceIdContext.newBuilder().traceId(1).build(); TraceIdContext context2 = TraceIdContext.newBuilder().traceId(2).build(); localRootId(context1, context2, ctx -> tracer.nextSpan(ctx)); }
@Test public void localRootId_nextSpan_ids_notSampled() { TraceIdContext context1 = TraceIdContext.newBuilder().traceId(1).sampled(false).build(); TraceIdContext context2 = TraceIdContext.newBuilder().traceId(2).sampled(false).build(); localRootId(context1, context2, ctx -> tracer.nextSpan(ctx)); }
@Test public void localRootId_nextSpan_ids_sampled() { TraceIdContext context1 = TraceIdContext.newBuilder().traceId(1).sampled(true).build(); TraceIdContext context2 = TraceIdContext.newBuilder().traceId(2).sampled(true).build(); localRootId(context1, context2, ctx -> tracer.nextSpan(ctx)); }
@Test public void localRootId_nextSpan_flags_empty() { TraceContextOrSamplingFlags flags = TraceContextOrSamplingFlags.EMPTY; localRootId(flags, flags, ctx -> tracer.nextSpan(ctx)); }
@Test public void localRootId_nextSpan_flags_notSampled() { TraceContextOrSamplingFlags flags = TraceContextOrSamplingFlags.NOT_SAMPLED; localRootId(flags, flags, ctx -> tracer.nextSpan(ctx)); }
@Test public void localRootId_nextSpan_flags_sampled() { TraceContextOrSamplingFlags flags = TraceContextOrSamplingFlags.SAMPLED; localRootId(flags, flags, ctx -> tracer.nextSpan(ctx)); }
@Test public void localRootId_nextSpan_flags_debug() { TraceContextOrSamplingFlags flags = TraceContextOrSamplingFlags.DEBUG; localRootId(flags, flags, ctx -> tracer.nextSpan(ctx)); }