.withTraceId(traceId) .withSpanId(spanId) .withParentSpanId(parentSpanId) .withSpanName(spanName) .withSampleable(sampleableForFullyCompleteSpan) .withUserId(userId) .withSpanPurpose(spanPurpose) .withSpanStartTimeEpochMicros(startTimeEpochMicrosForFullyCompleteSpan) .withSpanStartTimeNanos(startTimeNanosForFullyCompleteSpan) .withDurationNanos(durationNanosForFullyCompletedSpan) .withTags(tags) .withTag(extraTagKey, extraTagValue) .withTags(evenMoreTags) .withTimestampedAnnotations(annotations) .withTimestampedAnnotation(extraAnnotation) .withTimestampedAnnotations(evenMoreAnnotations); Span span = builder.build();
) { Span origCallSpan = Span.newBuilder("origCall", Span.SpanPurpose.CLIENT) .withSampleable(sampled) .build(); Map<String, String> tracingHeaders = new HashMap<>(); HttpRequestTracingUtils.propagateTracingHeaders(tracingHeaders::put, origCallSpan);
Span origSpan = Span.newBuilder(UUID.randomUUID().toString(), LOCAL_ONLY).withTraceId(UUID.randomUUID().toString()).build(); origTraceStack.add(origSpan); Map<String, String> origMdcInfo = new HashMap<>();
Deque<Span> originalValidSpanStack = Tracer.getInstance().getCurrentSpanStackCopy(); Span invalidSpan = Span.generateRootSpanForNewTrace("invalidSpan", SpanPurpose.LOCAL_ONLY).build(); assertThat(invalidSpan.isCompleted()).isFalse();
Deque<Span> originalValidSpanStack = Tracer.getInstance().getCurrentSpanStackCopy(); Span invalidSpan = Span.generateRootSpanForNewTrace("invalidSpan", SpanPurpose.LOCAL_ONLY).build(); assertThat(invalidSpan.isCompleted()).isFalse();
Span span = Span.newBuilder("foo", SpanPurpose.CLIENT).build(); long nanoTimeAfterSpanCreation = System.nanoTime();
.withUserId("testUserId") .build(); assertThat(Tracer.getInstance().getCurrentSpan()).isNull(); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isNull();
? null : spy(Span.newBuilder(UUID.randomUUID().toString(), SpanPurpose.CLIENT) .withParentSpanId(UUID.randomUUID().toString()) .build());
? null : spy(Span.newBuilder(UUID.randomUUID().toString(), Span.SpanPurpose.CLIENT) .withParentSpanId(UUID.randomUUID().toString()) .build());
@Test public void startRequestWithChildSpan_should_start_valid_child_span_with_parent() { Span parentSpan = Span.generateRootSpanForNewTrace("parentspan", SpanPurpose.LOCAL_ONLY).build(); assertThat(Tracer.getInstance().getCurrentSpan()).isNull(); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isNull();
: Span.generateRootSpanForNewTrace(spanName, spanPurpose).withSampleable(isNextRootSpanSampleable()).build();
Span result = Span.generateRootSpanForNewTrace(spanName, spanPurpose).build(); long afterCallNanos = System.nanoTime(); long afterCallEpochMicros = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
Span result = Span.newBuilder(spanName, spanPurpose).build(); long afterCallNanos = System.nanoTime(); long afterCallEpochMicros = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());
? null : Span.newBuilder(UUID.randomUUID().toString(), SpanPurpose.CLIENT) .withParentSpanId(UUID.randomUUID().toString()) .build();
.withTraceId(traceId) .withParentSpanId(parentSpanId) .withSampleable(sampleable) .withUserId(userId) .build();
.withParentSpanId(TraceAndSpanIdGenerator.generateId()) .withSampleable(false) .withUserId("someUser") .build(); given(requestMock.getHeader(TraceHeaders.TRACE_ID)).willReturn(parentSpan.getTraceId()); given(requestMock.getHeader(TraceHeaders.SPAN_ID)).willReturn(parentSpan.getSpanId());
.withTraceId(traceId) .withParentSpanId(getSpanIdFromRequest(request, TraceHeaders.PARENT_SPAN_ID, false)) .withSpanId(getSpanIdFromRequest(request, TraceHeaders.SPAN_ID, true)) .withSampleable(getSpanSampleableFlag(request)) .withUserId(getUserIdFromRequestWithHeaders(request, userIdHeaderKeys)) .build();
@Test public void registerWithThread_should_work_as_advertised_if_existing_stack_is_empty() { // given getSpanStackThreadLocal().set(new LinkedList<Span>()); Tracer tracer = Tracer.getInstance(); Deque<Span> newSpanStack = new LinkedList<>(); Span parentSpan = Span.newBuilder("foo", SpanPurpose.LOCAL_ONLY).build(); Span subspan = Span.newBuilder("bar", SpanPurpose.LOCAL_ONLY).build(); newSpanStack.push(parentSpan); newSpanStack.push(subspan); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isNull(); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isNull(); // when tracer.registerWithThread(newSpanStack); // then // our stack was registered, so subspan should be current assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isEqualTo(subspan.getTraceId()); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isEqualTo(subspan.toJSON()); assertThat(tracer.getCurrentSpan()).isEqualTo(subspan); // a *copy* of the stack we passed in should have been registered, and modifying the original stack should not affect Tracer's stack Deque<Span> spanStack = getSpanStackThreadLocal().get(); assertThat(Tracer.getInstance().containsSameSpansInSameOrder(spanStack, newSpanStack)).isTrue(); assertThat(spanStack).isNotSameAs(newSpanStack); newSpanStack.push(subspan.generateChildSpan("subsub", SpanPurpose.LOCAL_ONLY)); assertThat(newSpanStack).hasSize(3); assertThat(spanStack).hasSize(2); }
@DataProvider(value = { "JSON", "KEY_VALUE" }, splitBy = "\\|") @Test public void verify_span_serialization_methods(Tracer.SpanLoggingRepresentation serializationOption) { // given Span span = Span.generateRootSpanForNewTrace(UUID.randomUUID().toString(), SpanPurpose.LOCAL_ONLY).build(); String expectedOutput; switch(serializationOption) { case JSON: expectedOutput = span.toJSON(); break; case KEY_VALUE: expectedOutput = span.toKeyValueString(); break; default: throw new IllegalArgumentException("Unhandled option: " + serializationOption); } Tracer.getInstance().setSpanLoggingRepresentation(serializationOption); // then assertThat(Tracer.getInstance().getSpanLoggingRepresentation()).isEqualTo(serializationOption); // and when String serializedString = Tracer.getInstance().serializeSpanToDesiredStringRepresentation(span); // then assertThat(serializedString).isEqualTo(expectedOutput); }
.withTraceId(badTraceId) .withSpanId(badSpanId) .withParentSpanId(badParentSpanId) .withSpanStartTimeEpochMicros(Math.abs(random.nextLong())) .withDurationNanos(Math.abs(random.nextLong())) .build();