Search in sources :

Example 11 with Annotation

use of zipkin.Annotation in project zipkin by openzipkin.

the class MySQLSpanConsumer method accept.

/** Blocking version of {@link AsyncSpanConsumer#accept} */
@Override
public void accept(List<Span> spans) {
    if (spans.isEmpty())
        return;
    try (Connection conn = datasource.getConnection()) {
        DSLContext create = context.get(conn);
        List<Query> inserts = new ArrayList<>();
        for (Span span : spans) {
            Long overridingTimestamp = authoritativeTimestamp(span);
            Long timestamp = overridingTimestamp != null ? overridingTimestamp : guessTimestamp(span);
            Map<TableField<Record, ?>, Object> updateFields = new LinkedHashMap<>();
            if (!span.name.equals("") && !span.name.equals("unknown")) {
                updateFields.put(ZIPKIN_SPANS.NAME, span.name);
            }
            // replace any tentative timestamp with the authoritative one.
            if (overridingTimestamp != null) {
                updateFields.put(ZIPKIN_SPANS.START_TS, overridingTimestamp);
            }
            if (span.duration != null) {
                updateFields.put(ZIPKIN_SPANS.DURATION, span.duration);
            }
            InsertSetMoreStep<Record> insertSpan = create.insertInto(ZIPKIN_SPANS).set(ZIPKIN_SPANS.TRACE_ID, span.traceId).set(ZIPKIN_SPANS.ID, span.id).set(ZIPKIN_SPANS.PARENT_ID, span.parentId).set(ZIPKIN_SPANS.NAME, span.name).set(ZIPKIN_SPANS.DEBUG, span.debug).set(ZIPKIN_SPANS.START_TS, timestamp).set(ZIPKIN_SPANS.DURATION, span.duration);
            if (span.traceIdHigh != 0 && schema.hasTraceIdHigh) {
                insertSpan.set(ZIPKIN_SPANS.TRACE_ID_HIGH, span.traceIdHigh);
            }
            inserts.add(updateFields.isEmpty() ? insertSpan.onDuplicateKeyIgnore() : insertSpan.onDuplicateKeyUpdate().set(updateFields));
            for (Annotation annotation : span.annotations) {
                InsertSetMoreStep<Record> insert = create.insertInto(ZIPKIN_ANNOTATIONS).set(ZIPKIN_ANNOTATIONS.TRACE_ID, span.traceId).set(ZIPKIN_ANNOTATIONS.SPAN_ID, span.id).set(ZIPKIN_ANNOTATIONS.A_KEY, annotation.value).set(ZIPKIN_ANNOTATIONS.A_TYPE, -1).set(ZIPKIN_ANNOTATIONS.A_TIMESTAMP, annotation.timestamp);
                if (span.traceIdHigh != 0 && schema.hasTraceIdHigh) {
                    insert.set(ZIPKIN_ANNOTATIONS.TRACE_ID_HIGH, span.traceIdHigh);
                }
                if (annotation.endpoint != null) {
                    insert.set(ZIPKIN_ANNOTATIONS.ENDPOINT_SERVICE_NAME, annotation.endpoint.serviceName);
                    insert.set(ZIPKIN_ANNOTATIONS.ENDPOINT_IPV4, annotation.endpoint.ipv4);
                    if (annotation.endpoint.ipv6 != null && schema.hasIpv6) {
                        insert.set(ZIPKIN_ANNOTATIONS.ENDPOINT_IPV6, annotation.endpoint.ipv6);
                    }
                    insert.set(ZIPKIN_ANNOTATIONS.ENDPOINT_PORT, annotation.endpoint.port);
                }
                inserts.add(insert.onDuplicateKeyIgnore());
            }
            for (BinaryAnnotation annotation : span.binaryAnnotations) {
                InsertSetMoreStep<Record> insert = create.insertInto(ZIPKIN_ANNOTATIONS).set(ZIPKIN_ANNOTATIONS.TRACE_ID, span.traceId).set(ZIPKIN_ANNOTATIONS.SPAN_ID, span.id).set(ZIPKIN_ANNOTATIONS.A_KEY, annotation.key).set(ZIPKIN_ANNOTATIONS.A_VALUE, annotation.value).set(ZIPKIN_ANNOTATIONS.A_TYPE, annotation.type.value).set(ZIPKIN_ANNOTATIONS.A_TIMESTAMP, timestamp);
                if (span.traceIdHigh != 0 && schema.hasTraceIdHigh) {
                    insert.set(ZIPKIN_ANNOTATIONS.TRACE_ID_HIGH, span.traceIdHigh);
                }
                if (annotation.endpoint != null) {
                    insert.set(ZIPKIN_ANNOTATIONS.ENDPOINT_SERVICE_NAME, annotation.endpoint.serviceName);
                    insert.set(ZIPKIN_ANNOTATIONS.ENDPOINT_IPV4, annotation.endpoint.ipv4);
                    if (annotation.endpoint.ipv6 != null && schema.hasIpv6) {
                        insert.set(ZIPKIN_ANNOTATIONS.ENDPOINT_IPV6, annotation.endpoint.ipv6);
                    }
                    insert.set(ZIPKIN_ANNOTATIONS.ENDPOINT_PORT, annotation.endpoint.port);
                }
                inserts.add(insert.onDuplicateKeyIgnore());
            }
        }
        create.batch(inserts).execute();
    } catch (SQLException e) {
        // TODO
        throw new RuntimeException(e);
    }
}
Also used : Query(org.jooq.Query) SQLException(java.sql.SQLException) Connection(java.sql.Connection) ArrayList(java.util.ArrayList) DSLContext(org.jooq.DSLContext) TableField(org.jooq.TableField) Span(zipkin.Span) Annotation(zipkin.Annotation) BinaryAnnotation(zipkin.BinaryAnnotation) LinkedHashMap(java.util.LinkedHashMap) BinaryAnnotation(zipkin.BinaryAnnotation) Record(org.jooq.Record)

Example 12 with Annotation

use of zipkin.Annotation in project zipkin by openzipkin.

the class CorrectForClockSkew method adjustTimestamps.

/** If any annotation has an IP with skew associated, adjust accordingly. */
static Span adjustTimestamps(Span span, ClockSkew skew) {
    List<Annotation> annotations = null;
    Long annotationTimestamp = null;
    for (int i = 0, length = span.annotations.size(); i < length; i++) {
        Annotation a = span.annotations.get(i);
        if (a.endpoint == null)
            continue;
        if (ipsMatch(skew.endpoint, a.endpoint)) {
            if (annotations == null)
                annotations = new ArrayList<>(span.annotations);
            if (span.timestamp != null && a.timestamp == span.timestamp) {
                annotationTimestamp = a.timestamp;
            }
            annotations.set(i, a.toBuilder().timestamp(a.timestamp - skew.skew).build());
        }
    }
    if (annotations != null) {
        Span.Builder builder = span.toBuilder().annotations(annotations);
        if (annotationTimestamp != null) {
            builder.timestamp(annotationTimestamp - skew.skew);
        }
        return builder.build();
    }
    // Search for a local span on the skewed endpoint
    for (int i = 0, length = span.binaryAnnotations.size(); i < length; i++) {
        BinaryAnnotation b = span.binaryAnnotations.get(i);
        if (b.endpoint == null)
            continue;
        if (b.key.equals(Constants.LOCAL_COMPONENT) && ipsMatch(skew.endpoint, b.endpoint)) {
            return span.toBuilder().timestamp(span.timestamp - skew.skew).build();
        }
    }
    return span;
}
Also used : BinaryAnnotation(zipkin.BinaryAnnotation) ArrayList(java.util.ArrayList) Span(zipkin.Span) Annotation(zipkin.Annotation) BinaryAnnotation(zipkin.BinaryAnnotation) Endpoint(zipkin.Endpoint)

Example 13 with Annotation

use of zipkin.Annotation in project zipkin by openzipkin.

the class CorrectForClockSkew method getClockSkew.

/** Use client/server annotations to determine if there's clock skew. */
@Nullable
static ClockSkew getClockSkew(Span span) {
    Map<String, Annotation> annotations = asMap(span.annotations);
    Annotation clientSend = annotations.get(Constants.CLIENT_SEND);
    Annotation clientRecv = annotations.get(Constants.CLIENT_RECV);
    Annotation serverRecv = annotations.get(Constants.SERVER_RECV);
    Annotation serverSend = annotations.get(Constants.SERVER_SEND);
    if (clientSend == null || clientRecv == null || serverRecv == null || serverSend == null) {
        return null;
    }
    Endpoint server = serverRecv.endpoint != null ? serverRecv.endpoint : serverSend.endpoint;
    if (server == null)
        return null;
    Endpoint client = clientSend.endpoint != null ? clientSend.endpoint : clientRecv.endpoint;
    if (client == null)
        return null;
    // There's no skew if the RPC is going to itself
    if (ipsMatch(server, client))
        return null;
    long clientDuration = clientRecv.timestamp - clientSend.timestamp;
    long serverDuration = serverSend.timestamp - serverRecv.timestamp;
    // This breaks if client duration is smaller than server (due to async return for example).
    if (clientDuration < serverDuration)
        return null;
    long latency = (clientDuration - serverDuration) / 2;
    // We can't see skew when send happens before receive
    if (latency < 0)
        return null;
    long skew = serverRecv.timestamp - latency - clientSend.timestamp;
    if (skew != 0L) {
        return new ClockSkew(server, skew);
    }
    return null;
}
Also used : Endpoint(zipkin.Endpoint) Annotation(zipkin.Annotation) BinaryAnnotation(zipkin.BinaryAnnotation)

Example 14 with Annotation

use of zipkin.Annotation in project zipkin by openzipkin.

the class SpanStoreTest method whenSpanTimestampIsMissingClientSendIsPreferred.

/**
   * Spans report depth-first. Make sure the client timestamp is preferred when instrumentation
   * don't add a timestamp.
   */
@Test
public void whenSpanTimestampIsMissingClientSendIsPreferred() {
    Endpoint frontend = Endpoint.create("frontend", 192 << 24 | 168 << 16 | 2);
    Annotation cs = Annotation.create((today + 50) * 1000, CLIENT_SEND, frontend);
    Annotation cr = Annotation.create((today + 150) * 1000, CLIENT_RECV, frontend);
    Endpoint backend = Endpoint.create("backend", 192 << 24 | 168 << 16 | 2);
    Annotation sr = Annotation.create((today + 95) * 1000, SERVER_RECV, backend);
    Annotation ss = Annotation.create((today + 100) * 1000, SERVER_SEND, backend);
    Span span = Span.builder().traceId(1).name("method1").id(666).build();
    // Simulate the server-side of a shared span arriving first
    accept(span.toBuilder().addAnnotation(sr).addAnnotation(ss).build());
    accept(span.toBuilder().addAnnotation(cs).addAnnotation(cr).build());
    // Make sure that the client's timestamp won
    assertThat(store().getTrace(span1.traceIdHigh, span.traceId)).containsExactly(span.toBuilder().timestamp(cs.timestamp).duration(cr.timestamp - cs.timestamp).annotations(asList(cs, sr, ss, cr)).build());
}
Also used : Endpoint(zipkin.Endpoint) Span(zipkin.Span) Annotation(zipkin.Annotation) BinaryAnnotation(zipkin.BinaryAnnotation) Test(org.junit.Test)

Example 15 with Annotation

use of zipkin.Annotation in project zipkin by openzipkin.

the class QueryRequest method test.

/** Tests the supplied trace against the current request */
public boolean test(List<Span> spans) {
    Long timestamp = ApplyTimestampAndDuration.guessTimestamp(spans.get(0));
    if (timestamp == null || timestamp < (endTs - lookback) * 1000 || timestamp > endTs * 1000) {
        return false;
    }
    Set<String> serviceNames = new LinkedHashSet<>();
    boolean testedDuration = minDuration == null && maxDuration == null;
    String spanNameToMatch = spanName;
    Set<String> annotationsToMatch = new LinkedHashSet<>(annotations);
    Map<String, String> binaryAnnotationsToMatch = new LinkedHashMap<>(binaryAnnotations);
    Set<String> currentServiceNames = new LinkedHashSet<>();
    for (Span span : spans) {
        currentServiceNames.clear();
        for (Annotation a : span.annotations) {
            if (appliesToServiceName(a.endpoint, serviceName)) {
                annotationsToMatch.remove(a.value);
            }
            if (a.endpoint != null) {
                serviceNames.add(a.endpoint.serviceName);
                currentServiceNames.add(a.endpoint.serviceName);
            }
        }
        for (BinaryAnnotation b : span.binaryAnnotations) {
            if (appliesToServiceName(b.endpoint, serviceName) && b.type == BinaryAnnotation.Type.STRING && new String(b.value, UTF_8).equals(binaryAnnotationsToMatch.get(b.key))) {
                binaryAnnotationsToMatch.remove(b.key);
            }
            if (b.endpoint != null) {
                serviceNames.add(b.endpoint.serviceName);
                currentServiceNames.add(b.endpoint.serviceName);
            }
        }
        if ((serviceName == null || currentServiceNames.contains(serviceName)) && !testedDuration) {
            if (minDuration != null && maxDuration != null) {
                testedDuration = span.duration >= minDuration && span.duration <= maxDuration;
            } else if (minDuration != null) {
                testedDuration = span.duration >= minDuration;
            }
        }
        if (span.name.equals(spanNameToMatch)) {
            spanNameToMatch = null;
        }
    }
    return (serviceName == null || serviceNames.contains(serviceName)) && spanNameToMatch == null && annotationsToMatch.isEmpty() && binaryAnnotationsToMatch.isEmpty() && testedDuration;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) BinaryAnnotation(zipkin.BinaryAnnotation) Span(zipkin.Span) Annotation(zipkin.Annotation) BinaryAnnotation(zipkin.BinaryAnnotation) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

Annotation (zipkin.Annotation)17 BinaryAnnotation (zipkin.BinaryAnnotation)14 Span (zipkin.Span)7 Test (org.junit.Test)6 ArrayList (java.util.ArrayList)5 Endpoint (zipkin.Endpoint)5 LinkedHashSet (java.util.LinkedHashSet)3 Span (com.uber.jaeger.Span)2 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2 BoundStatement (com.datastax.driver.core.BoundStatement)1 SpanContext (com.uber.jaeger.SpanContext)1 Connection (java.sql.Connection)1 SQLException (java.sql.SQLException)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 TreeMap (java.util.TreeMap)1 TreeSet (java.util.TreeSet)1 UUID (java.util.UUID)1 DSLContext (org.jooq.DSLContext)1