/** * Ensures the specified {@link Tracing} uses a {@link RequestContextCurrentTraceContext}. * * @throws IllegalStateException if {@code tracing} does not use {@link RequestContextCurrentTraceContext} */ public static void ensureScopeUsesRequestContext(Tracing tracing) { final PingPongExtra extra = new PingPongExtra(); // trace contexts are not recorded until Tracer.toSpan, so this won't end up as junk data final TraceContext dummyContext = TraceContext.newBuilder().traceId(1).spanId(1) .extra(Collections.singletonList(extra)).build(); final boolean scopeUsesRequestContext; try (Scope scope = tracing.currentTraceContext().newScope(dummyContext)) { scopeUsesRequestContext = extra.isPong(); } if (!scopeUsesRequestContext) { throw new IllegalStateException( "Tracing.currentTraceContext is not a " + RequestContextCurrentTraceContext.class .getSimpleName() + " scope. " + "Please call Tracing.Builder.currentTraceContext(" + RequestContextCurrentTraceContext.class .getSimpleName() + ".INSTANCE)."); } }
@Test public void newScope_notOnEventLoop() { final TraceContext traceContext2 = TraceContext.newBuilder().traceId(1).spanId(2).build(); try (SafeCloseable requestContextScope = mockRequestContext.push()) { try (Scope traceContextScope = currentTraceContext.newScope(traceContext)) { assertThat(traceContextScope).hasToString("InitialRequestScope"); assertThat(currentTraceContext.get()).isEqualTo(traceContext); when(eventLoop.inEventLoop()).thenReturn(false); try (Scope traceContextScope2 = currentTraceContext.newScope(traceContext2)) { assertThat(traceContextScope2).hasToString("ThreadLocalScope"); assertThat(currentTraceContext.get()).isEqualTo(traceContext2); } when(eventLoop.inEventLoop()).thenReturn(true); assertThat(currentTraceContext.get()).isEqualTo(traceContext); } // the first scope is attached to the request context and cleared when that's destroyed assertThat(currentTraceContext.get()).isEqualTo(traceContext); } }
@Test public void restoresSpanAfterRunnable() throws Exception { TraceContext context0 = TraceContext.newBuilder().traceId(3L).spanId(3L).build(); try (Scope scope0 = currentTraceContext.newScope(context0)) { attachesSpanInRunnable(); assertThat(currentTraceContext.get()) .isEqualTo(context0); verifyImplicitContext(context0); } }
.traceId(traceId) .spanId(spanId); if (sampled != null) builder.sampled(sampled.booleanValue());
TraceContext.newBuilder() .traceIdHigh(traceId[0]) .traceId(traceId[1]) .spanId(spanId) .sampled(traceTrue)
.traceId(RpcTraceContext.getTraceId()) .parentId(RpcTraceContext.getParentId()) .spanId(RpcTraceContext.getSpanId())
@Test public void restoresSpanAfterRunnable() throws Exception { TraceContext context0 = TraceContext.newBuilder().traceId(3L).spanId(3L).build(); try (Scope scope0 = currentTraceContext.newScope(context0)) { attachesSpanInRunnable(); assertThat(currentTraceContext.get()) .isEqualTo(context0); verifyImplicitContext(context0); } }
@Override public void accept(CurrentTraceContext current) { current.newScope(TraceContext.newBuilder().traceId(1L).spanId(2L).build()); } }
@Override public void accept(CurrentTraceContext current) { try (Scope ws = current.newScope(TraceContext.newBuilder().traceId(1L).spanId(2L).build())) { } } }
@Test public void verifyRoundTrip_128BitTrace() throws Exception { String high64Bits = "463ac35c9f6413ad"; String low64Bits = "48485a3953bb6124"; inject(map, high64Bits + low64Bits, null, low64Bits, true, null); verifyRoundTrip(TraceContextOrSamplingFlags.create(rootSpan.toBuilder() .traceIdHigh(HexCodec.lowerHexToUnsignedLong(high64Bits)) .traceId(HexCodec.lowerHexToUnsignedLong(low64Bits)) .spanId(HexCodec.lowerHexToUnsignedLong(low64Bits)).build())); }
public static TraceContext toTraceContext(SpanId spanId) { // visible for testing if (spanId == null) throw new NullPointerException("spanId == null"); return TraceContext.newBuilder() .traceIdHigh(spanId.traceIdHigh) .traceId(spanId.traceId) .parentId(spanId.nullableParentId()) .spanId(spanId.spanId) .debug(spanId.debug()) .sampled(spanId.sampled()).build(); }
@Override public void accept(Propagation<?> propagation) { TraceContext.Injector<Map<Object, String>> injector = propagation.injector(Map::put); TraceContext.Extractor<Map<Object, String>> extractor = propagation.extractor(Map::get); TraceContext ctx = TraceContext.newBuilder().traceId(1L).spanId(2L).sampled(false).build(); Map<Object, String> map = new LinkedHashMap<>(); injector.inject(ctx, map); assertThat(extractor.extract(map).context()) .isEqualToIgnoringGivenFields(ctx, "traceIdString", "spanIdString"); } }
.traceId(traceId) .spanId(spanId); if (sampled != null) builder.sampled(sampled.booleanValue());
@Test public void newScope_closeDoesntClearFirstScope() { final TraceContext traceContext2 = TraceContext.newBuilder().traceId(1).spanId(2).build(); try (SafeCloseable requestContextScope = mockRequestContext.push()) { try (Scope traceContextScope = currentTraceContext.newScope(traceContext)) { assertThat(traceContextScope).hasToString("InitialRequestScope"); assertThat(currentTraceContext.get()).isEqualTo(traceContext); try (Scope traceContextScope2 = currentTraceContext.newScope(traceContext2)) { assertThat(traceContextScope2).hasToString("RequestContextTraceContextScope"); assertThat(currentTraceContext.get()).isEqualTo(traceContext2); } assertThat(currentTraceContext.get()).isEqualTo(traceContext); } // the first scope is attached to the request context and cleared when that's destroyed assertThat(currentTraceContext.get()).isEqualTo(traceContext); } }
@Override public void accept(CurrentTraceContext current) { try (Scope ws = current.newScope(TraceContext.newBuilder().traceId(1L).spanId(2L).build())) { } } }
@Override public void accept(CurrentTraceContext current) { current.newScope(TraceContext.newBuilder().traceId(1L).spanId(2L).build()); } }
@Test public void newScope_respondsToPing() { final PingPongExtra extra = new PingPongExtra(); final TraceContext extraContext = TraceContext.newBuilder().traceId(1).spanId(1) .extra(Collections.singletonList(extra)).build(); try (Scope traceContextScope = currentTraceContext.newScope(extraContext)) { assertThat(traceContextScope).hasToString("NoopScope"); assertThat(extra.isPong()).isTrue(); } }
@Override public void accept(Propagation<?> propagation) { TraceContext.Injector<Map<Object, String>> injector = propagation.injector(Map::put); TraceContext.Extractor<Map<Object, String>> extractor = propagation.extractor(Map::get); TraceContext ctx = TraceContext.newBuilder().traceId(1L).spanId(2L).sampled(false).build(); Map<Object, String> map = new LinkedHashMap<>(); injector.inject(ctx, map); assertThat(extractor.extract(map).context()) .isEqualToIgnoringGivenFields(ctx, "traceIdString", "spanIdString"); } }
@Test public void verifyRoundTrip_128BitTrace() throws Exception { String high64Bits = "463ac35c9f6413ad"; String low64Bits = "48485a3953bb6124"; inject(map, high64Bits + low64Bits, null, low64Bits, true, null); verifyRoundTrip(TraceContextOrSamplingFlags.create(rootSpan.toBuilder() .traceIdHigh(HexCodec.lowerHexToUnsignedLong(high64Bits)) .traceId(HexCodec.lowerHexToUnsignedLong(low64Bits)) .spanId(HexCodec.lowerHexToUnsignedLong(low64Bits)).build())); }
@Test public void shouldSetPongIfOnlyExtra() { final PingPongExtra extra = new PingPongExtra(); final TraceContext context = TraceContext.newBuilder().traceId(1).spanId(1) .extra(Collections.singletonList(extra)).build(); PingPongExtra.maybeSetPong(context); assertThat(extra.isPong()).isTrue(); } }