use of zipkin2.Span.Kind in project zipkin by openzipkin.
the class ITDependencies method missingIntermediateSpan.
/**
* This shows a missing parent still results in a dependency link when local endpoints change
*/
@Test
protected void missingIntermediateSpan(TestInfo testInfo) throws Exception {
String testSuffix = testSuffix(testInfo);
String traceId = newTraceId();
Endpoint frontend = suffixServiceName(TestObjects.FRONTEND, testSuffix);
Endpoint backend = suffixServiceName(TestObjects.BACKEND, testSuffix);
List<Span> trace = asList(Span.newBuilder().traceId(traceId).id("20").name("get").timestamp(TODAY * 1000L).duration(350L * 1000L).kind(Kind.SERVER).localEndpoint(frontend).build(), // missing an intermediate span
Span.newBuilder().traceId(traceId).parentId("21").id("22").name("get").timestamp((TODAY + 150L) * 1000L).duration(50L * 1000L).kind(Kind.CLIENT).localEndpoint(backend).build());
processDependencies(trace);
assertThat(store().getDependencies(endTs(trace), DAY).execute()).containsOnly(DependencyLink.newBuilder().parent(frontend.serviceName()).child(backend.serviceName()).callCount(1).build());
}
use of zipkin2.Span.Kind in project zipkin by openzipkin.
the class ITDependencies method intermediateSpans.
/**
* This test confirms that the span store can process trace with intermediate spans like the below
* properly.
* <p>
* span1: SR SS span2: intermediate call span3: CS SR SS CR: Dependency 1
*/
@Test
protected void intermediateSpans(TestInfo testInfo) throws Exception {
String testSuffix = testSuffix(testInfo);
String traceId = newTraceId();
Endpoint frontend = suffixServiceName(TestObjects.FRONTEND, testSuffix);
Endpoint backend = suffixServiceName(TestObjects.BACKEND, testSuffix);
Endpoint db = suffixServiceName(TestObjects.DB, testSuffix);
List<Span> trace = asList(Span.newBuilder().traceId(traceId).id("20").name("get").timestamp(TODAY * 1000L).duration(350L * 1000L).kind(Kind.SERVER).localEndpoint(frontend).build(), Span.newBuilder().traceId(traceId).parentId("20").id("21").name("call").timestamp((TODAY + 25) * 1000L).duration(325L * 1000L).localEndpoint(frontend).build(), Span.newBuilder().traceId(traceId).parentId("21").id("22").name("get").timestamp((TODAY + 50) * 1000L).duration(250L * 1000L).kind(Kind.CLIENT).localEndpoint(frontend).build(), Span.newBuilder().traceId(traceId).parentId("21").id("22").name("get").timestamp((TODAY + 100) * 1000L).duration(150 * 1000L).shared(true).kind(Kind.SERVER).localEndpoint(backend).build(), Span.newBuilder().traceId(traceId).parentId("22").id(23L).name("call").timestamp((TODAY + 110) * 1000L).duration(130L * 1000L).name("depth4").localEndpoint(backend).build(), Span.newBuilder().traceId(traceId).parentId(23L).id(24L).name("call").timestamp((TODAY + 125) * 1000L).duration(105L * 1000L).name("depth5").localEndpoint(backend).build(), Span.newBuilder().traceId(traceId).parentId(24L).id(25L).name("get").timestamp((TODAY + 150) * 1000L).duration(50L * 1000L).kind(Kind.CLIENT).localEndpoint(backend).remoteEndpoint(db).build());
processDependencies(trace);
assertThat(store().getDependencies(TODAY + 1000, 1000L).execute()).containsOnly(DependencyLink.newBuilder().parent(frontend.serviceName()).child(backend.serviceName()).callCount(1).build(), DependencyLink.newBuilder().parent(backend.serviceName()).child(db.serviceName()).callCount(1).build());
}
use of zipkin2.Span.Kind in project zipkin by openzipkin.
the class ITSpanStore method readback_minimalErrorSpan.
/**
* The following skeletal span is used in dependency linking.
*
* <p>Notably this guards empty tag values work
*/
@Test
protected void readback_minimalErrorSpan(TestInfo testInfo) throws Exception {
String testSuffix = testSuffix(testInfo);
String serviceName = appendSuffix("isao01", testSuffix);
Span errorSpan = Span.newBuilder().traceId(newTraceId()).id("1").timestamp(TODAY * 1000L).localEndpoint(Endpoint.newBuilder().serviceName(serviceName).build()).kind(CLIENT).putTag("error", "").build();
accept(errorSpan);
QueryRequest.Builder requestBuilder = // so this doesn't die on cassandra v1
requestBuilder().serviceName(serviceName);
assertGetTracesReturns(requestBuilder.build(), asList(errorSpan));
assertGetTracesReturns(requestBuilder.parseAnnotationQuery("error").build(), asList(errorSpan));
assertGetTracesReturnsEmpty(requestBuilder.parseAnnotationQuery("error=1").build());
assertGetTraceReturns(errorSpan);
}
use of zipkin2.Span.Kind in project java by wavefrontHQ.
the class ZipkinPortUnificationHandler method processZipkinSpan.
private void processZipkinSpan(zipkin2.Span zipkinSpan) {
if (ZIPKIN_DATA_LOGGER.isLoggable(Level.FINEST)) {
ZIPKIN_DATA_LOGGER.info("Inbound Zipkin span: " + zipkinSpan.toString());
}
// Add application tags, span references, span kind and http uri, responses etc.
List<Annotation> annotations = new ArrayList<>();
// Add original Zipkin trace and span ids as tags to make finding them easier
annotations.add(new Annotation("zipkinSpanId", zipkinSpan.id()));
annotations.add(new Annotation("zipkinTraceId", zipkinSpan.traceId()));
// Set Span's References.
if (zipkinSpan.parentId() != null) {
annotations.add(new Annotation(TraceConstants.PARENT_KEY, Utils.convertToUuidString(zipkinSpan.parentId())));
}
// Set Span Kind.
if (zipkinSpan.kind() != null) {
String kind = zipkinSpan.kind().toString().toLowerCase();
annotations.add(new Annotation("span.kind", kind));
if (zipkinSpan.annotations() != null && !zipkinSpan.annotations().isEmpty()) {
annotations.add(new Annotation("_spanSecondaryId", kind));
}
}
// Set Span's service name.
String serviceName = zipkinSpan.localServiceName() == null ? DEFAULT_SERVICE : zipkinSpan.localServiceName();
annotations.add(new Annotation(SERVICE_TAG_KEY, serviceName));
String applicationName = this.proxyLevelApplicationName;
String cluster = NULL_TAG_VAL;
String shard = NULL_TAG_VAL;
String componentTagValue = NULL_TAG_VAL;
boolean isError = false;
boolean isDebugSpanTag = false;
// Set all other Span Tags.
Set<String> ignoreKeys = new HashSet<>(ImmutableSet.of(SOURCE_KEY));
if (zipkinSpan.tags() != null && zipkinSpan.tags().size() > 0) {
for (Map.Entry<String, String> tag : zipkinSpan.tags().entrySet()) {
if (!ignoreKeys.contains(tag.getKey().toLowerCase()) && !StringUtils.isBlank(tag.getValue())) {
Annotation annotation = new Annotation(tag.getKey(), tag.getValue());
switch(annotation.getKey()) {
case APPLICATION_TAG_KEY:
applicationName = annotation.getValue();
continue;
case CLUSTER_TAG_KEY:
cluster = annotation.getValue();
continue;
case SHARD_TAG_KEY:
shard = annotation.getValue();
continue;
case COMPONENT_TAG_KEY:
componentTagValue = annotation.getValue();
break;
case ERROR_SPAN_TAG_KEY:
isError = true;
// Ignore the original error value
annotation.setValue(ERROR_SPAN_TAG_VAL);
break;
case DEBUG_TAG_KEY:
isDebugSpanTag = annotation.getValue().equals(DEBUG_SPAN_TAG_VAL);
break;
}
annotations.add(annotation);
}
}
}
// Add all wavefront indexed tags. These are set based on below hierarchy.
// Span Level > Proxy Level > Default
annotations.add(new Annotation(APPLICATION_TAG_KEY, applicationName));
annotations.add(new Annotation(CLUSTER_TAG_KEY, cluster));
annotations.add(new Annotation(SHARD_TAG_KEY, shard));
// Add Sampling related annotations.
// Add a debug span tag as needed to enable sampling of this span with intelligent sampling.
boolean isDebug = zipkinSpan.debug() != null ? zipkinSpan.debug() : false;
if (!isDebugSpanTag && isDebug) {
annotations.add(new Annotation(DEBUG_SPAN_TAG_KEY, DEBUG_SPAN_TAG_VAL));
}
// Add additional annotations.
if (zipkinSpan.localEndpoint() != null && zipkinSpan.localEndpoint().ipv4() != null) {
annotations.add(new Annotation("ipv4", zipkinSpan.localEndpoint().ipv4()));
}
if (!spanLogsDisabled.get() && zipkinSpan.annotations() != null && !zipkinSpan.annotations().isEmpty()) {
annotations.add(new Annotation("_spanLogs", "true"));
}
/* Add source of the span following the below:
* 1. If "source" is provided by span tags , use it else
* 2. Default "source" to "zipkin".
*/
String sourceName = DEFAULT_SOURCE;
if (zipkinSpan.tags() != null && zipkinSpan.tags().size() > 0) {
if (zipkinSpan.tags().get(SOURCE_KEY) != null) {
sourceName = zipkinSpan.tags().get(SOURCE_KEY);
}
}
// Set spanName.
String spanName = zipkinSpan.name() == null ? DEFAULT_SPAN_NAME : zipkinSpan.name();
String spanId = Utils.convertToUuidString(zipkinSpan.id());
String traceId = Utils.convertToUuidString(zipkinSpan.traceId());
// Build wavefront span
Span wavefrontSpan = Span.newBuilder().setCustomer("dummy").setName(spanName).setSource(sourceName).setSpanId(spanId).setTraceId(traceId).setStartMillis(zipkinSpan.timestampAsLong() / 1000).setDuration(zipkinSpan.durationAsLong() / 1000).setAnnotations(annotations).build();
if (zipkinSpan.tags().containsKey(SPAN_TAG_ERROR)) {
if (ZIPKIN_DATA_LOGGER.isLoggable(Level.FINER)) {
ZIPKIN_DATA_LOGGER.info("Span id :: " + spanId + " with trace id :: " + traceId + " , includes error tag :: " + zipkinSpan.tags().get(SPAN_TAG_ERROR));
}
}
// Log Zipkin spans as well as Wavefront spans for debugging purposes.
if (ZIPKIN_DATA_LOGGER.isLoggable(Level.FINEST)) {
ZIPKIN_DATA_LOGGER.info("Converted Wavefront span: " + wavefrontSpan.toString());
}
if (preprocessorSupplier != null) {
ReportableEntityPreprocessor preprocessor = preprocessorSupplier.get();
String[] messageHolder = new String[1];
preprocessor.forSpan().transform(wavefrontSpan);
if (!preprocessor.forSpan().filter(wavefrontSpan, messageHolder)) {
if (messageHolder[0] != null) {
spanHandler.reject(wavefrontSpan, messageHolder[0]);
} else {
spanHandler.block(wavefrontSpan);
}
return;
}
}
if (sampler.sample(wavefrontSpan, discardedSpansBySampler)) {
spanHandler.report(wavefrontSpan);
if (zipkinSpan.annotations() != null && !zipkinSpan.annotations().isEmpty() && !isFeatureDisabled(spanLogsDisabled, SPANLOGS_DISABLED, null)) {
SpanLogs spanLogs = SpanLogs.newBuilder().setCustomer("default").setTraceId(wavefrontSpan.getTraceId()).setSpanId(wavefrontSpan.getSpanId()).setSpanSecondaryId(zipkinSpan.kind() != null ? zipkinSpan.kind().toString().toLowerCase() : null).setLogs(zipkinSpan.annotations().stream().map(x -> SpanLog.newBuilder().setTimestamp(x.timestamp()).setFields(ImmutableMap.of("annotation", x.value())).build()).collect(Collectors.toList())).build();
spanLogsHandler.report(spanLogs);
}
}
// report stats irrespective of span sampling.
if (wfInternalReporter != null) {
// Set post preprocessor rule values and report converted metrics/histograms from the span
List<Annotation> processedAnnotations = wavefrontSpan.getAnnotations();
for (Annotation processedAnnotation : processedAnnotations) {
switch(processedAnnotation.getKey()) {
case APPLICATION_TAG_KEY:
applicationName = processedAnnotation.getValue();
continue;
case SERVICE_TAG_KEY:
serviceName = processedAnnotation.getValue();
continue;
case CLUSTER_TAG_KEY:
cluster = processedAnnotation.getValue();
continue;
case SHARD_TAG_KEY:
shard = processedAnnotation.getValue();
continue;
case COMPONENT_TAG_KEY:
componentTagValue = processedAnnotation.getValue();
continue;
case ERROR_TAG_KEY:
isError = true;
continue;
}
}
List<Pair<String, String>> spanTags = processedAnnotations.stream().map(a -> new Pair<>(a.getKey(), a.getValue())).collect(Collectors.toList());
discoveredHeartbeatMetrics.add(reportWavefrontGeneratedData(wfInternalReporter, wavefrontSpan.getName(), applicationName, serviceName, cluster, shard, wavefrontSpan.getSource(), componentTagValue, isError, zipkinSpan.durationAsLong(), traceDerivedCustomTagKeys, spanTags, true));
}
}
use of zipkin2.Span.Kind in project java by wavefrontHQ.
the class ZipkinPortUnificationHandlerTest method testZipkinDurationSampler.
@Test
public void testZipkinDurationSampler() throws Exception {
ZipkinPortUnificationHandler handler = new ZipkinPortUnificationHandler("9411", new NoopHealthCheckManager(), mockTraceHandler, mockTraceSpanLogsHandler, null, () -> false, () -> false, null, new SpanSampler(new DurationSampler(5), () -> null), null, null);
Endpoint localEndpoint1 = Endpoint.newBuilder().serviceName("frontend").ip("10.0.0.1").build();
zipkin2.Span spanServer1 = zipkin2.Span.newBuilder().traceId("2822889fe47043bd").id("2822889fe47043bd").kind(zipkin2.Span.Kind.SERVER).name("getservice").timestamp(startTime * 1000).duration(4 * 1000).localEndpoint(localEndpoint1).putTag("http.method", "GET").putTag("http.url", "none+h1c://localhost:8881/").putTag("http.status_code", "200").addAnnotation(startTime * 1000, "start processing").build();
zipkin2.Span spanServer2 = zipkin2.Span.newBuilder().traceId("3822889fe47043bd").id("3822889fe47043bd").kind(zipkin2.Span.Kind.SERVER).name("getservice").timestamp(startTime * 1000).duration(9 * 1000).localEndpoint(localEndpoint1).putTag("http.method", "GET").putTag("http.url", "none+h1c://localhost:8881/").putTag("http.status_code", "200").addAnnotation(startTime * 1000, "start processing").build();
List<zipkin2.Span> zipkinSpanList = ImmutableList.of(spanServer1, spanServer2);
SpanBytesEncoder encoder = SpanBytesEncoder.values()[1];
ByteBuf content = Unpooled.copiedBuffer(encoder.encodeList(zipkinSpanList));
// take care of mocks.
// Reset mock
reset(mockTraceHandler, mockTraceSpanLogsHandler);
// Set Expectation
Span expectedSpan2 = Span.newBuilder().setCustomer("dummy").setStartMillis(startTime).setDuration(9).setName("getservice").setSource(DEFAULT_SOURCE).setSpanId("00000000-0000-0000-3822-889fe47043bd").setTraceId("00000000-0000-0000-3822-889fe47043bd").setAnnotations(ImmutableList.of(new Annotation("zipkinSpanId", "3822889fe47043bd"), new Annotation("zipkinTraceId", "3822889fe47043bd"), new Annotation("span.kind", "server"), new Annotation("_spanSecondaryId", "server"), new Annotation("service", "frontend"), new Annotation("http.method", "GET"), new Annotation("http.status_code", "200"), new Annotation("http.url", "none+h1c://localhost:8881/"), new Annotation("application", "Zipkin"), new Annotation("cluster", "none"), new Annotation("shard", "none"), new Annotation("ipv4", "10.0.0.1"), new Annotation("_spanLogs", "true"))).build();
mockTraceHandler.report(expectedSpan2);
expectLastCall();
mockTraceSpanLogsHandler.report(SpanLogs.newBuilder().setCustomer("default").setTraceId("00000000-0000-0000-3822-889fe47043bd").setSpanId("00000000-0000-0000-3822-889fe47043bd").setSpanSecondaryId("server").setLogs(ImmutableList.of(SpanLog.newBuilder().setTimestamp(startTime * 1000).setFields(ImmutableMap.of("annotation", "start processing")).build())).build());
expectLastCall();
replay(mockTraceHandler, mockTraceSpanLogsHandler);
ChannelHandlerContext mockCtx = createNiceMock(ChannelHandlerContext.class);
doMockLifecycle(mockCtx);
FullHttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "http://localhost:9411/api/v1/spans", content, true);
handler.handleHttpMessage(mockCtx, httpRequest);
verify(mockTraceHandler, mockTraceSpanLogsHandler);
}
Aggregations