com.nike.wingtips.Span类的使用及代码示例

x33g5p2x  于2022-01-30 转载在 其他  
字(17.3k)|赞(0)|评价(0)|浏览(235)

本文整理了Java中com.nike.wingtips.Span类的一些代码示例,展示了Span类的具体用法。这些代码示例主要来源于Github/Stackoverflow/Maven等平台,是从一些精选项目中提取出来的代码,具有较强的参考意义,能在一定程度帮忙到你。Span类的具体详情如下:
包路径:com.nike.wingtips.Span
类名称:Span

Span介绍

[英]Represents some logical "unit of work" that is part of the larger distributed trace. A given request's trace tree is made up of all the spans with the same #traceIdand the spans are connected via parent-child relationship. The first span in the trace tree covers the entire distributed trace - it is often referred to as the root span.

For any given service call in a distributed trace there is usually one span covering the full call; that service-level span is started when a request first hits the service and #complete() is called when the response is sent to the caller, and at that point the resulting completed span is logged or otherwise sent to a span collector of some sort so the span's data can be used later for investigations/aggregations/statistics.

Extra "sub-spans" can be generated by a service if it wants additional tracing around specific functions inside the service. One sub-span example might be to create a sub-span in service A when it makes a downstream call to service B. You could then subtract #getDurationNanos() for service B's service-level span from the time spent in service A's downstream call span to determine what the network lag was for that call.

Spans support Java try-with-resources statements to help guarantee proper usage in blocking/non-async scenarios (for asynchronous scenarios please refer to the asynchronous usage section of the Wingtips readme). Here are some examples.

Overall request span using try-with-resources:

try(Span requestSpan = Tracer.getInstance().startRequestWith*(...)) { 
// Traced blocking code for overall request (not asynchronous) goes here ... 
} 
// No finally block needed to properly complete the overall request span

Subspan using try-with-resources:

try (Span subspan = Tracer.getInstance().startSubSpan(...)) { 
// Traced blocking code for subspan (not asynchronous) goes here ... 
} 
// No finally block needed to properly complete the subspan

[中]表示某个逻辑“工作单元”,它是更大的分布式跟踪的一部分。给定请求的跟踪树由具有相同#traceID的所有跨度组成,这些跨度通过父子关系连接。跟踪树中的第一个跨度覆盖了整个分布式跟踪——它通常被称为根跨度。
对于分布式跟踪中的任何给定服务调用,通常有一个跨度覆盖整个调用;该服务级别范围在请求第一次命中服务时启动,在将响应发送给调用方时调用#complete(),并在此时记录结果完成的范围,或以其他方式发送给某种类型的范围收集器,以便以后可以将该范围的数据用于调查/聚合/统计。
如果服务希望围绕服务内的特定功能进行额外跟踪,则可以生成额外的“子跨度”。一个子跨度示例可能是,当服务a对服务B进行下游调用时,在服务a中创建一个子跨度。然后,您可以从服务a的下游调用跨度中减去服务B的服务级别跨度的#GetDurationNano(),以确定该调用的网络延迟。
span支持Java try with resources语句,以帮助确保在阻塞/非异步场景中正确使用(有关异步场景,请参阅the asynchronous usage section of the Wingtips readme)。下面是一些例子。
使用try with resources的总体请求范围:

try(Span requestSpan = Tracer.getInstance().startRequestWith*(...)) { 
// Traced blocking code for overall request (not asynchronous) goes here ... 
} 
// No finally block needed to properly complete the overall request span

使用资源试用的子扫描:

try (Span subspan = Tracer.getInstance().startSubSpan(...)) { 
// Traced blocking code for subspan (not asynchronous) goes here ... 
} 
// No finally block needed to properly complete the subspan

代码示例

代码示例来源:origin: Nike-Inc/wingtips

public static void verifySpanDeepEquals(
  Span spanToVerify, Span expectedSpan, boolean allowStartTimeNanosFudgeFactor
) {
  assertThat(spanToVerify.getSpanStartTimeEpochMicros()).isEqualTo(expectedSpan.getSpanStartTimeEpochMicros());
  if (allowStartTimeNanosFudgeFactor) {
    assertThat(spanToVerify.getSpanStartTimeNanos())
      .isCloseTo(expectedSpan.getSpanStartTimeNanos(), Offset.offset(TimeUnit.MILLISECONDS.toNanos(1)));
  }
  else {
    assertThat(spanToVerify.getSpanStartTimeNanos()).isEqualTo(expectedSpan.getSpanStartTimeNanos());
  }
  assertThat(spanToVerify.isCompleted()).isEqualTo(expectedSpan.isCompleted());
  assertThat(spanToVerify.getTraceId()).isEqualTo(expectedSpan.getTraceId());
  assertThat(spanToVerify.getSpanId()).isEqualTo(expectedSpan.getSpanId());
  assertThat(spanToVerify.getParentSpanId()).isEqualTo(expectedSpan.getParentSpanId());
  assertThat(spanToVerify.getSpanName()).isEqualTo(expectedSpan.getSpanName());
  assertThat(spanToVerify.isSampleable()).isEqualTo(expectedSpan.isSampleable());
  assertThat(spanToVerify.getUserId()).isEqualTo(expectedSpan.getUserId());
  assertThat(spanToVerify.getDurationNanos()).isEqualTo(expectedSpan.getDurationNanos());
  assertThat(spanToVerify.getSpanPurpose()).isEqualTo(expectedSpan.getSpanPurpose());
  assertThat(spanToVerify.getTags()).isEqualTo(expectedSpan.getTags());
  assertThat(spanToVerify.getTimestampedAnnotations()).isEqualTo(expectedSpan.getTimestampedAnnotations());
}

代码示例来源:origin: Nike-Inc/wingtips

private Pair<Span, Map<String, String>> generateUpstreamSpanHeaders() {
  Span span = Span.newBuilder("upstreamSpan", Span.SpanPurpose.CLIENT).build();
  Map<String, String> headers = MapBuilder
    .builder(TraceHeaders.TRACE_ID, span.getTraceId())
    .put(TraceHeaders.SPAN_ID, span.getSpanId())
    .put(TraceHeaders.SPAN_NAME, span.getSpanName())
    .put(TraceHeaders.TRACE_SAMPLED, String.valueOf(span.isSampleable()))
    .build();
  return Pair.of(span, headers);
}

代码示例来源:origin: Nike-Inc/wingtips

/**
 * Sets the span variables on the MDC context.
 */
protected static void configureMDC(Span span) {
  MDC.put(TRACE_ID_MDC_KEY, span.getTraceId());
  MDC.put(SPAN_JSON_MDC_KEY, span.toJSON());
}

代码示例来源:origin: Nike-Inc/wingtips

/**
 * Helper method for adding tracing-related request attributes to the given request based on the given span.
 *
 * @param span The span for the overall request.
 * @param request The request object to add tracing-related request attributes to.
 */
protected void addTracingInfoToRequestAttributes(Span span, HttpServletRequest request) {
  request.setAttribute(TraceHeaders.TRACE_SAMPLED, span.isSampleable());
  request.setAttribute(TraceHeaders.TRACE_ID, span.getTraceId());
  request.setAttribute(TraceHeaders.SPAN_ID, span.getSpanId());
  request.setAttribute(TraceHeaders.PARENT_SPAN_ID, span.getParentSpanId());
  request.setAttribute(TraceHeaders.SPAN_NAME, span.getSpanName());
  request.setAttribute(Span.class.getName(), span);
}

代码示例来源:origin: Nike-Inc/wingtips

@Override
public zipkin.Span convertWingtipsSpanToZipkinSpan(Span wingtipsSpan, Endpoint zipkinEndpoint, String localComponentNamespace) {
  String traceId = wingtipsSpan.getTraceId();
  long startEpochMicros = wingtipsSpan.getSpanStartTimeEpochMicros();
  long durationMicros = TimeUnit.NANOSECONDS.toMicros(wingtipsSpan.getDurationNanos());
  zipkin.Span.Builder builder = createNewZipkinSpanBuilderWithSpanPurposeAnnotations(wingtipsSpan, startEpochMicros, durationMicros, zipkinEndpoint, localComponentNamespace)
    .id(nullSafeLong(wingtipsSpan.getSpanId()))
    .name(wingtipsSpan.getSpanName())
    .parentId(nullSafeLong(wingtipsSpan.getParentSpanId()))
    .timestamp(startEpochMicros)
    .traceIdHigh(traceId.length() == 32 ? nullSafeLong(traceId, 0) : 0)
    .traceId(nullSafeLong(traceId))
    .duration(durationMicros);
  
  addAllTagsToBuilderAsBinaryAnnotations(builder, wingtipsSpan.getTags(), zipkinEndpoint);
  addAllAnnotationsToBuilder(builder, wingtipsSpan.getTimestampedAnnotations(), zipkinEndpoint);
  return builder.build();
}

代码示例来源:origin: Nike-Inc/wingtips

@UseDataProvider("tagAndAnnotationScenarioDataProvider")
@Test
public void convertSpanToJSON_should_function_properly_when_there_are_no_null_values(
  TagAndAnnotationScenario scenario
) throws IOException {
  // given: valid span without any null values, span completed (so that end time is not null), and JSON string
  //      from SpanParser.convertSpanToJSON()
  Span validSpan = createFilledOutSpan(true, scenario.tags, scenario.annotations);
  assertThat(validSpan.getTraceId()).isNotEmpty();
  assertThat(validSpan.getUserId()).isNotEmpty();
  assertThat(validSpan.getParentSpanId()).isNotEmpty();
  assertThat(validSpan.getSpanName()).isNotEmpty();
  assertThat(validSpan.getSpanId()).isNotEmpty();
  assertThat(validSpan.getDurationNanos()).isNotNull();
  assertThat(validSpan.isCompleted()).isTrue();
  assertThat(validSpan.getSpanPurpose()).isNotNull();
  assertThat(validSpan.getTags()).isEqualTo(scenario.tags);
  assertThat(validSpan.getTimestampedAnnotations()).isEqualTo(scenario.annotations);
  String json = SpanParser.convertSpanToJSON(validSpan);
  
  // when: jackson is used to deserialize that JSON
  Map<String, Object> spanValuesFromJackson = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {});
  // then: the original span context and jackson's span context values should be exactly the same
  verifySpanEqualsDeserializedValues(validSpan, spanValuesFromJackson);
}

代码示例来源:origin: Nike-Inc/wingtips

@Test
public void fromHttpServletRequestOrCreateRootSpan_pulls_from_headers_if_available() {
  // given: a set of standard Span header values
  given(request.getHeader(TraceHeaders.TRACE_ID)).willReturn(sampleTraceID);
  given(request.getHeader(TraceHeaders.TRACE_SAMPLED)).willReturn(Boolean.TRUE.toString());
  given(request.getHeader(TraceHeaders.SPAN_ID)).willReturn(sampleSpanID);
  given(request.getHeader(TraceHeaders.PARENT_SPAN_ID)).willReturn(sampleParentSpanID);
  given(request.getHeader(USER_ID_HEADER_KEY)).willReturn(userId);
  // when: creating Span object from HTTP request using fromHttpServletRequestOrCreateRootSpan
  long beforeCallNanos = System.nanoTime();
  Span goodSpan = HttpSpanFactory.fromHttpServletRequestOrCreateRootSpan(request, USER_ID_HEADER_KEYS);
  long afterCallNanos = System.nanoTime();
  // then: ensure Span object gets identical values from corresponding headers
  assertThat(goodSpan.getTraceId()).isEqualTo(sampleTraceID);
  assertThat(goodSpan.isSampleable()).isTrue();
  assertThat(goodSpan.getSpanId()).isEqualTo(sampleSpanID);
  assertThat(goodSpan.getParentSpanId()).isEqualTo(sampleParentSpanID);
  assertThat(goodSpan.getUserId()).isEqualTo(userId);
  assertThat(goodSpan.getSpanStartTimeNanos()).isBetween(beforeCallNanos, afterCallNanos);
  assertThat(goodSpan.isCompleted()).isFalse();
  assertThat(goodSpan.getSpanPurpose()).isEqualTo(SpanPurpose.SERVER);
}

代码示例来源:origin: Nike-Inc/wingtips

private void verifySingleSpanCompletedAndReturnedInResponse(ExtractableResponse response,
                              long expectedMinSpanDurationMillis,
                              Span expectedUpstreamSpan) {
  // We can have a race condition where the response is sent and we try to verify here before the servlet filter
  //      has had a chance to complete the span. Wait a few milliseconds to give the servlet filter time to
  //      finish.
  waitUntilSpanRecorderHasExpectedNumSpans(1);
  
  assertThat(spanRecorder.completedSpans).hasSize(1);
  Span completedSpan = spanRecorder.completedSpans.get(0);
  String traceIdFromResponse = response.header(TraceHeaders.TRACE_ID);
  assertThat(traceIdFromResponse).isNotNull();
  assertThat(completedSpan.getTraceId()).isEqualTo(traceIdFromResponse);
  assertThat(TimeUnit.NANOSECONDS.toMillis(completedSpan.getDurationNanos()))
    .isGreaterThanOrEqualTo(expectedMinSpanDurationMillis);
  if (expectedUpstreamSpan != null) {
    assertThat(completedSpan.getTraceId()).isEqualTo(expectedUpstreamSpan.getTraceId());
    assertThat(completedSpan.getParentSpanId()).isEqualTo(expectedUpstreamSpan.getSpanId());
  }
}

代码示例来源:origin: Nike-Inc/wingtips

@Test
public void convertSpanToJSON_should_function_properly_when_there_are_null_values() throws IOException {
  // given: valid span with null values and JSON string from SpanParser.convertSpanToJSON()
  Span validSpan = Span.generateRootSpanForNewTrace(spanName, null).build();
  assertThat(validSpan.getParentSpanId()).isNull();
  assertThat(validSpan.getUserId()).isNull();
  assertThat(validSpan.getDurationNanos()).isNull();
  String json = SpanParser.convertSpanToJSON(validSpan);
  // when: jackson is used to deserialize that JSON
  Map<String, Object> spanValuesFromJackson = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {});
  // then: the original span context and jackson's span context values should be exactly the same
  verifySpanEqualsDeserializedValues(validSpan, spanValuesFromJackson);
}

代码示例来源:origin: Nike-Inc/wingtips

@Test
public void fromHttpServletRequest_generates_new_spanId_if_missing_from_headers() {
  // given: a request with a trace ID but no span ID in the headers
  String traceId = UUID.randomUUID().toString();
  given(request.getHeader(TraceHeaders.TRACE_ID)).willReturn(traceId);
  // when: we use it to create span objects
  Span firstSpan = HttpSpanFactory.fromHttpServletRequest(request, USER_ID_HEADER_KEYS);
  Span secondSpan = HttpSpanFactory.fromHttpServletRequest(request, USER_ID_HEADER_KEYS);
  // then: ensure each call generates a span with the same trace ID but new span ID
  assertThat(firstSpan.getTraceId()).isEqualTo(traceId);
  assertThat(secondSpan.getTraceId()).isEqualTo(traceId);
  assertThat(firstSpan.getSpanId()).isNotEmpty();
  assertThat(secondSpan.getSpanId()).isNotEmpty();
  assertThat(firstSpan.getSpanId()).isNotEqualTo(secondSpan.getSpanId());
}

代码示例来源:origin: Nike-Inc/riposte

private Span findCompletedSpan(String expectedSpanName, String expectedSpanHandler) {
  return spanRecorder.completedSpans
    .stream()
    .filter(
      s -> s.getSpanName().equals(expectedSpanName)
         && expectedSpanHandler.equals(s.getTags().get(WingtipsTags.SPAN_HANDLER))
    )
    .findFirst()
    .orElseThrow(
      () -> new RuntimeException(
        "Unable to find span with expected span name: " + expectedSpanName + " and span handler: "
        + expectedSpanHandler
      )
    );
}

代码示例来源:origin: Nike-Inc/wingtips

@Test
public void fromHttpServletRequestOrCreateRootSpan_returns_new_root_span_if_traceId_is_missing_from_headers() {
  // given: no trace ID in headers, but user ID exists
  given(request.getHeader(ALT_USER_ID_HEADER_KEY)).willReturn(altUserId);
  // when: creating Span object from HTTP request using fromHttpServletRequestOrCreateRootSpan
  long beforeCallNanos = System.nanoTime();
  Span newSpan = HttpSpanFactory.fromHttpServletRequestOrCreateRootSpan(request, USER_ID_HEADER_KEYS);
  long afterCallNanos = System.nanoTime();
  // then: ensure root span object is created even though there was no trace ID header, and the returned span contains the expected user ID
  assertThat(newSpan).isNotNull();
  assertThat(newSpan.getParentSpanId()).isNull();
  assertThat(newSpan.getUserId()).isEqualTo(altUserId);
  assertThat(newSpan.getSpanStartTimeNanos()).isBetween(beforeCallNanos, afterCallNanos);
  assertThat(newSpan.isCompleted()).isFalse();
  assertThat(newSpan.getSpanPurpose()).isEqualTo(SpanPurpose.SERVER);
}

代码示例来源:origin: Nike-Inc/wingtips

@Test
public void changeSpanName_works_as_expected() {
  // given
  Span span = Span.newBuilder("origSpanName", Span.SpanPurpose.SERVER).build();
  String newSpanName = UUID.randomUUID().toString();
  assertThat(span.getSpanName()).isNotEqualTo(newSpanName);
  // when
  SpanMutator.changeSpanName(span, newSpanName);
  // then
  assertThat(span.getSpanName()).isEqualTo(newSpanName);
}

代码示例来源:origin: Nike-Inc/wingtips

@Test
public void fromRequestWithHeaders_sets_user_id_to_null_if_passed_null_or_empty_userIdHeaderKeys_list() {
  // given
  String traceId = UUID.randomUUID().toString();
  given(request.getHeader(TraceHeaders.TRACE_ID)).willReturn(traceId);
  List<List<String>> badLists = Arrays.asList(null, Collections.<String>emptyList());
  for (List<String> badList : badLists) {
    // when
    Span result = HttpRequestTracingUtils.fromRequestWithHeaders(request, badList);
    // expect
    assertThat(result.getTraceId()).isEqualTo(traceId);
    assertThat(result.getUserId()).isNull();
  }
}

代码示例来源:origin: Nike-Inc/wingtips

@UseDataProvider("escapedAndUnescapedQuotesBeforeKeyOrValueEndScenarioDataProvider")
@Test
public void fromJSON_properly_handles_escaped_quotes_and_unescaped_quotes_preceded_by_backslashes(
  EscapedAndUnescapedQuotesBeforeKeyOrValueEndScenario scenario
) {
  // given
  Span span = Span.newBuilder("someSpan", SpanPurpose.CLIENT)
          .withTag(scenario.unescapedKey, scenario.unescapedValue)
          .withTimestampedAnnotation(
            TimestampedAnnotation.forEpochMicros(1234, scenario.unescapedValue)
          )
          .build();
  String json = SpanParser.convertSpanToJSON(span);
  // when
  Span result = SpanParser.fromJSON(json);
  // then
  assertThat(result.getTags().get(scenario.unescapedKey)).isEqualTo(scenario.unescapedValue);
  assertThat(result.getTimestampedAnnotations().get(0).getValue()).isEqualTo(scenario.unescapedValue);
}

代码示例来源:origin: Nike-Inc/wingtips

@Test
public void builder_withTags_does_nothing_if_passed_null() {
  // given
  Span.Builder builder = Span.newBuilder("foo", SpanPurpose.UNKNOWN);
  Map<String, String> tagsMapSpy = spy(new LinkedHashMap<>());
  Whitebox.setInternalState(builder, "tags", tagsMapSpy);
  
  // when
  Span.Builder resultingBuilder = builder.withTags(null);
  // then
  assertThat(resultingBuilder).isSameAs(builder);
  verifyZeroInteractions(tagsMapSpy);
  // and when
  Span resultingSpan = resultingBuilder.build();
  // then
  assertThat(resultingSpan.getTags()).isEmpty();
}

代码示例来源:origin: Nike-Inc/wingtips

@Test
public void setSpanName_works_as_expected() {
  // given
  Span span = Span.newBuilder("origSpanName", SpanPurpose.SERVER).build();
  String newSpanName = UUID.randomUUID().toString();
  assertThat(span.getSpanName()).isNotEqualTo(newSpanName);
  // when
  span.setSpanName(newSpanName);
  // then
  assertThat(span.getSpanName()).isEqualTo(newSpanName);
}

代码示例来源:origin: Nike-Inc/wingtips

@Test
public void getCurrentSpan_should_return_current_span() throws Exception {
  // given
  Tracer tracer = Tracer.getInstance();
  tracer.startRequestWithRootSpan("test-span");
  // when
  Span span = tracer.getCurrentSpan();
  // then
  assertThat(span).isNotNull();
  assertThat(span.getSpanName()).isEqualTo("test-span");
}

代码示例来源:origin: Nike-Inc/wingtips

/**
 * Notifies all listeners that the given span was sampled using {@link SpanLifecycleListener#spanSampled(Span)}, <b>but only if the span's {@link Span#isSampleable()}
 * method returns true!</b> If the span is not sampleable then this method does nothing.
 */
protected void notifyIfSpanSampled(Span span) {
  if (span.isSampleable()) {
    for (SpanLifecycleListener tll : spanLifecycleListeners) {
      tll.spanSampled(span);
    }
  }
}

代码示例来源:origin: Nike-Inc/wingtips

@Test
public void putTag_works_as_expected() {
  // given
  Span span = Span.newBuilder("foo", SpanPurpose.CLIENT).build();
  assertThat(span.getTags()).isEmpty();
  String tagKey = "key-" + UUID.randomUUID().toString();
  String tagValue = "value-" + UUID.randomUUID().toString();
  String otherValue = "othervalue-" + UUID.randomUUID().toString();
  // when
  span.putTag(tagKey, tagValue);
  // then
  assertThat(span.getTags()).hasSize(1);
  assertThat(span.getTags().get(tagKey)).isEqualTo(tagValue);
  // and when
  span.putTag(tagKey, otherValue);
  // then
  assertThat(span.getTags()).hasSize(1);
  assertThat(span.getTags().get(tagKey)).isEqualTo(otherValue);
}

相关文章