本文整理了Java中com.nike.wingtips.Span
类的一些代码示例,展示了Span
类的具体用法。这些代码示例主要来源于Github
/Stackoverflow
/Maven
等平台,是从一些精选项目中提取出来的代码,具有较强的参考意义,能在一定程度帮忙到你。Span
类的具体详情如下:
包路径:com.nike.wingtips.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);
}
内容来源于网络,如有侵权,请联系作者删除!