use of zipkin.Annotation in project zipkin by openzipkin.
the class CassandraUtil method annotationKeys.
/**
* Returns keys that concatenate the serviceName associated with an annotation or a binary
* annotation.
*
* <p>Note: in the case of binary annotations, only string types are returned, as that's the only
* queryable type, per {@link QueryRequest#binaryAnnotations}.
*
* @see QueryRequest#annotations
* @see QueryRequest#binaryAnnotations
*/
static Set<String> annotationKeys(Span span) {
Set<String> annotationKeys = new LinkedHashSet<>();
for (Annotation a : span.annotations) {
// don't index core annotations as they aren't queryable
if (Constants.CORE_ANNOTATIONS.contains(a.value))
continue;
if (a.endpoint != null && !a.endpoint.serviceName.isEmpty()) {
annotationKeys.add(a.endpoint.serviceName + ":" + a.value);
}
}
for (BinaryAnnotation b : span.binaryAnnotations) {
if (b.type == BinaryAnnotation.Type.STRING && b.endpoint != null && !b.endpoint.serviceName.isEmpty() && b.value.length <= LONGEST_VALUE_TO_INDEX * 4) {
// UTF_8 is up to 4bytes/char
String value = new String(b.value, UTF_8);
if (value.length() > LONGEST_VALUE_TO_INDEX)
continue;
annotationKeys.add(b.endpoint.serviceName + ":" + b.key + ":" + new String(b.value, UTF_8));
}
}
return annotationKeys;
}
use of zipkin.Annotation in project jaeger-client-java by jaegertracing.
the class ZipkinSenderTest method testFlushSendsSpan.
@Test
public void testFlushSendsSpan() throws Exception {
Span expectedSpan = (Span) tracer.buildSpan("raza").startManual();
assertEquals(0, sender.append(expectedSpan));
assertEquals(1, sender.flush());
List<List<zipkin.Span>> traces = zipkinRule.getTraces();
assertEquals(traces.size(), 1);
assertEquals(traces.get(0).size(), 1);
zipkin.Span actualSpan = traces.get(0).get(0);
SpanContext context = expectedSpan.context();
assertEquals(context.getTraceId(), actualSpan.traceId);
assertEquals(context.getSpanId(), actualSpan.id);
assertEquals(context.getParentId(), (long) actualSpan.parentId);
assertEquals(expectedSpan.getOperationName(), actualSpan.name);
for (BinaryAnnotation binaryAnnotation : actualSpan.binaryAnnotations) {
assertEquals(tracer.getServiceName(), binaryAnnotation.endpoint.serviceName);
}
for (Annotation annotation : actualSpan.annotations) {
assertEquals(tracer.getServiceName(), annotation.endpoint.serviceName);
}
}
use of zipkin.Annotation in project brave by openzipkin.
the class V2SpanConverter method toSpan.
/**
* Converts the input, parsing {@link Span#kind()} into RPC annotations.
*/
public static zipkin.Span toSpan(Span in) {
String traceId = in.traceId();
zipkin.Span.Builder result = zipkin.Span.builder().traceId(HexCodec.lowerHexToUnsignedLong(traceId)).parentId(in.parentId() != null ? HexCodec.lowerHexToUnsignedLong(in.parentId()) : null).id(HexCodec.lowerHexToUnsignedLong(in.id())).debug(in.debug()).name(// avoid a NPE
in.name() != null ? in.name() : "");
if (traceId.length() == 32) {
result.traceIdHigh(HexCodec.lowerHexToUnsignedLong(traceId, 0));
}
long startTs = in.timestamp() == null ? 0L : in.timestamp();
Long endTs = in.duration() == null ? 0L : in.timestamp() + in.duration();
if (startTs != 0L) {
result.timestamp(startTs);
result.duration(in.duration());
}
zipkin.Endpoint local = in.localEndpoint() != null ? toEndpoint(in.localEndpoint()) : null;
zipkin.Endpoint remote = in.remoteEndpoint() != null ? toEndpoint(in.remoteEndpoint()) : null;
Kind kind = in.kind();
Annotation cs = null, sr = null, ss = null, cr = null, ms = null, mr = null, ws = null, wr = null;
String remoteEndpointType = null;
boolean wroteEndpoint = false;
for (int i = 0, length = in.annotations().size(); i < length; i++) {
zipkin2.Annotation input = in.annotations().get(i);
Annotation a = Annotation.create(input.timestamp(), input.value(), local);
if (a.value.length() == 2) {
if (a.value.equals(Constants.CLIENT_SEND)) {
kind = Kind.CLIENT;
cs = a;
remoteEndpointType = SERVER_ADDR;
} else if (a.value.equals(Constants.SERVER_RECV)) {
kind = Kind.SERVER;
sr = a;
remoteEndpointType = CLIENT_ADDR;
} else if (a.value.equals(Constants.SERVER_SEND)) {
kind = Kind.SERVER;
ss = a;
} else if (a.value.equals(Constants.CLIENT_RECV)) {
kind = Kind.CLIENT;
cr = a;
} else if (a.value.equals(Constants.MESSAGE_SEND)) {
kind = Kind.PRODUCER;
ms = a;
} else if (a.value.equals(Constants.MESSAGE_RECV)) {
kind = Kind.CONSUMER;
mr = a;
} else if (a.value.equals(Constants.WIRE_SEND)) {
ws = a;
} else if (a.value.equals(Constants.WIRE_RECV)) {
wr = a;
} else {
wroteEndpoint = true;
result.addAnnotation(a);
}
} else {
wroteEndpoint = true;
result.addAnnotation(a);
}
}
if (kind != null) {
switch(kind) {
case CLIENT:
remoteEndpointType = Constants.SERVER_ADDR;
if (startTs != 0L)
cs = Annotation.create(startTs, Constants.CLIENT_SEND, local);
if (endTs != 0L)
cr = Annotation.create(endTs, Constants.CLIENT_RECV, local);
break;
case SERVER:
remoteEndpointType = Constants.CLIENT_ADDR;
if (startTs != 0L)
sr = Annotation.create(startTs, Constants.SERVER_RECV, local);
if (endTs != 0L)
ss = Annotation.create(endTs, Constants.SERVER_SEND, local);
break;
case PRODUCER:
remoteEndpointType = Constants.MESSAGE_ADDR;
if (startTs != 0L)
ms = Annotation.create(startTs, Constants.MESSAGE_SEND, local);
if (endTs != 0L)
ws = Annotation.create(endTs, Constants.WIRE_SEND, local);
break;
case CONSUMER:
remoteEndpointType = Constants.MESSAGE_ADDR;
if (startTs != 0L && endTs != 0L) {
wr = Annotation.create(startTs, Constants.WIRE_RECV, local);
mr = Annotation.create(endTs, Constants.MESSAGE_RECV, local);
} else if (startTs != 0L) {
mr = Annotation.create(startTs, Constants.MESSAGE_RECV, local);
}
break;
default:
throw new AssertionError("update kind mapping");
}
}
for (Map.Entry<String, String> tag : in.tags().entrySet()) {
wroteEndpoint = true;
result.addBinaryAnnotation(BinaryAnnotation.create(tag.getKey(), tag.getValue(), local));
}
if (cs != null || sr != null || ss != null || cr != null || ws != null || wr != null || ms != null || mr != null) {
if (cs != null)
result.addAnnotation(cs);
if (sr != null)
result.addAnnotation(sr);
if (ss != null)
result.addAnnotation(ss);
if (cr != null)
result.addAnnotation(cr);
if (ws != null)
result.addAnnotation(ws);
if (wr != null)
result.addAnnotation(wr);
if (ms != null)
result.addAnnotation(ms);
if (mr != null)
result.addAnnotation(mr);
wroteEndpoint = true;
} else if (local != null && remote != null) {
// special-case when we are missing core annotations, but we have both address annotations
result.addBinaryAnnotation(BinaryAnnotation.address(CLIENT_ADDR, local));
wroteEndpoint = true;
remoteEndpointType = SERVER_ADDR;
}
if (remoteEndpointType != null && remote != null) {
result.addBinaryAnnotation(BinaryAnnotation.address(remoteEndpointType, remote));
}
// don't report server-side timestamp on shared or incomplete spans
if (Boolean.TRUE.equals(in.shared()) && sr != null) {
result.timestamp(null).duration(null);
}
if (local != null && !wroteEndpoint) {
// create a dummy annotation
result.addBinaryAnnotation(BinaryAnnotation.create(LOCAL_COMPONENT, "", local));
}
return result.build();
}
use of zipkin.Annotation in project zipkin by openzipkin.
the class CassandraSpanConsumer method storeSpan.
/**
* Store the span in the underlying storage for later retrieval.
*/
ListenableFuture<?> storeSpan(Span span, TraceIdUDT traceId, boolean isServerRecvSpan, Long timestamp) {
try {
if ((null == timestamp || 0 == timestamp) && !isServerRecvSpan && metadata.compactionClass.contains("TimeWindowCompactionStrategy")) {
LOG.warn("Span {} in trace {} had no timestamp. " + "If this happens a lot consider switching back to SizeTieredCompactionStrategy for " + "{}.traces", span.id, span.traceId, session.getLoggedKeyspace());
}
List<AnnotationUDT> annotations = new ArrayList<>(span.annotations.size());
for (Annotation annotation : span.annotations) {
annotations.add(new AnnotationUDT(annotation));
}
List<BinaryAnnotationUDT> binaryAnnotations = new ArrayList<>(span.binaryAnnotations.size());
for (BinaryAnnotation annotation : span.binaryAnnotations) {
binaryAnnotations.add(new BinaryAnnotationUDT(annotation));
}
Set<String> annotationKeys = CassandraUtil.annotationKeys(span);
if (!strictTraceId && traceId.getHigh() != 0L) {
storeSpan(span, new TraceIdUDT(0L, traceId.getLow()), isServerRecvSpan, timestamp);
}
BoundStatement bound = bindWithName(insertSpan, "insert-span").set("trace_id", traceId, TraceIdUDT.class).setUUID("ts_uuid", new UUID(UUIDs.startOf(null != timestamp ? (timestamp / 1000) : 0).getMostSignificantBits(), UUIDs.random().getLeastSignificantBits())).setLong("id", span.id).setString("span_name", span.name).setList("annotations", annotations).setList("binary_annotations", binaryAnnotations).setString("all_annotations", Joiner.on(',').join(annotationKeys));
if (null != span.timestamp) {
bound = bound.setLong("ts", span.timestamp);
}
if (null != span.duration) {
bound = bound.setLong("duration", span.duration);
}
if (null != span.parentId) {
bound = bound.setLong("parent_id", span.parentId);
}
return session.executeAsync(bound);
} catch (RuntimeException ex) {
return Futures.immediateFailedFuture(ex);
}
}
use of zipkin.Annotation in project zipkin by openzipkin.
the class CassandraUtil method annotationKeys.
/**
* Returns keys that concatenate the serviceName associated with an annotation or a binary
* annotation.
*
* <p>Note: Annotations are delimited with colons while Binary Annotations are delimited with
* semi-colons. This is because the returned keys are joined on comma and queried with LIKE. For
* example, a span with the annotation "foo" and a binary annotation "bar" -> "baz" would end up
* in a cell "service:foo,service:bar:baz". A query for the annotation "bar" would satisfy as
* "service:bar" is a substring of that cell. This is imprecise. By joining binary annotations on
* semicolon, this mismatch cannot happen.
*
* <p>Note: in the case of binary annotations, only string types are returned, as that's the only
* queryable type, per {@link QueryRequest#binaryAnnotations}.
*
* @see QueryRequest#annotations
* @see QueryRequest#binaryAnnotations
*/
static Set<String> annotationKeys(Span span) {
Set<String> annotationKeys = new LinkedHashSet<>();
for (Annotation a : span.annotations) {
// don't index core annotations as they aren't queryable
if (Constants.CORE_ANNOTATIONS.contains(a.value))
continue;
if (a.endpoint != null && !a.endpoint.serviceName.isEmpty()) {
annotationKeys.add(a.endpoint.serviceName + ":" + a.value);
}
}
for (BinaryAnnotation b : span.binaryAnnotations) {
if (b.type != BinaryAnnotation.Type.STRING || b.endpoint == null || b.endpoint.serviceName.isEmpty() || b.value.length > LONGEST_VALUE_TO_INDEX * 4) {
// UTF_8 is up to 4bytes/char
continue;
}
String value = new String(b.value, UTF_8);
if (value.length() > LONGEST_VALUE_TO_INDEX)
continue;
annotationKeys.add(b.endpoint.serviceName + ";" + b.key + ";" + new String(b.value, UTF_8));
}
return annotationKeys;
}
Aggregations