Search in sources :

Example 1 with DependencyLinker

use of zipkin2.internal.DependencyLinker in project zipkin by openzipkin.

the class AggregateDependencies method apply.

@Override
public List<DependencyLink> apply(DSLContext context) {
    // Subquery on trace IDs to prevent only matching the part of the trace that exists within
    // the interval: we want all of the trace.
    SelectConditionStep<Record1<Long>> traceIDs = context.selectDistinct(ZIPKIN_SPANS.TRACE_ID).from(ZIPKIN_SPANS).where(startTsBegin == startTsEnd ? ZIPKIN_SPANS.START_TS.lessOrEqual(startTsEnd) : ZIPKIN_SPANS.START_TS.between(startTsBegin, startTsEnd));
    // Lazy fetching the cursor prevents us from buffering the whole dataset in memory.
    Cursor<Record> cursor = context.selectDistinct(schema.dependencyLinkerFields).from(ZIPKIN_SPANS.leftJoin(ZIPKIN_ANNOTATIONS).on(ZIPKIN_SPANS.TRACE_ID.eq(ZIPKIN_ANNOTATIONS.TRACE_ID).and(ZIPKIN_SPANS.ID.eq(ZIPKIN_ANNOTATIONS.SPAN_ID))).and(ZIPKIN_ANNOTATIONS.A_KEY.in("lc", "cs", "ca", "sr", "sa", "ma", "mr", "ms", "error"))).where(ZIPKIN_SPANS.TRACE_ID.in(traceIDs)).groupBy(schema.dependencyLinkerGroupByFields).fetchLazy();
    Iterator<Iterator<Span>> traces = new DependencyLinkV2SpanIterator.ByTraceId(cursor.iterator(), schema.hasTraceIdHigh);
    if (!traces.hasNext())
        return Collections.emptyList();
    DependencyLinker linker = new DependencyLinker();
    List<Span> nextTrace = new ArrayList<>();
    while (traces.hasNext()) {
        Iterator<Span> i = traces.next();
        while (i.hasNext()) nextTrace.add(i.next());
        linker.putTrace(nextTrace);
        nextTrace.clear();
    }
    return linker.link();
}
Also used : DependencyLinker(zipkin2.internal.DependencyLinker) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) Record(org.jooq.Record) Span(zipkin2.Span) Record1(org.jooq.Record1)

Example 2 with DependencyLinker

use of zipkin2.internal.DependencyLinker in project zipkin by openzipkin.

the class DependencyLinker method putTrace.

/**
 * All {@code spans} must have the same trace id.
 */
public DependencyLinker putTrace(List<Span> spans) {
    if (spans.isEmpty())
        return this;
    SpanNode traceTree = builder.build(spans);
    if (logger.isLoggable(FINE))
        logger.fine("traversing trace tree, breadth-first");
    for (Iterator<SpanNode> i = traceTree.traverse(); i.hasNext(); ) {
        SpanNode current = i.next();
        Span currentSpan = current.span();
        if (logger.isLoggable(FINE)) {
            logger.fine("processing " + currentSpan);
        }
        Kind kind = currentSpan.kind();
        // spans, we proceed to use the name the client chose.
        if (Kind.CLIENT.equals(kind) && !current.children().isEmpty()) {
            continue;
        }
        String serviceName = currentSpan.localServiceName();
        String remoteServiceName = currentSpan.remoteServiceName();
        if (kind == null) {
            // Treat unknown type of span as a client span if we know both sides
            if (serviceName != null && remoteServiceName != null) {
                kind = Kind.CLIENT;
            } else {
                logger.fine("non remote span; skipping");
                continue;
            }
        }
        String child;
        String parent;
        switch(kind) {
            case SERVER:
            case CONSUMER:
                child = serviceName;
                parent = remoteServiceName;
                if (current == traceTree) {
                    // we are the root-most span.
                    if (parent == null) {
                        logger.fine("root's client is unknown; skipping");
                        continue;
                    }
                }
                break;
            case CLIENT:
            case PRODUCER:
                parent = serviceName;
                child = remoteServiceName;
                break;
            default:
                logger.fine("unknown kind; skipping");
                continue;
        }
        boolean isError = currentSpan.tags().containsKey("error");
        if (kind == Kind.PRODUCER || kind == Kind.CONSUMER) {
            if (parent == null || child == null) {
                logger.fine("cannot link messaging span to its broker; skipping");
            } else {
                addLink(parent, child, isError);
            }
            continue;
        }
        // Local spans may be between the current node and its remote parent
        Span remoteAncestor = firstRemoteAncestor(current);
        String remoteAncestorName;
        if (remoteAncestor != null && (remoteAncestorName = remoteAncestor.localServiceName()) != null) {
            // Check for this and backfill a link from the nearest remote to that service as necessary.
            if (kind == Kind.CLIENT && serviceName != null && !remoteAncestorName.equals(serviceName)) {
                logger.fine("detected missing link to client span");
                // we don't know if there's an error here
                addLink(remoteAncestorName, serviceName, false);
            }
            if (kind == Kind.SERVER || parent == null)
                parent = remoteAncestorName;
            // client, we need to check it for errors.
            if (!isError && Kind.CLIENT.equals(remoteAncestor.kind()) && currentSpan.parentId() != null && currentSpan.parentId().equals(remoteAncestor.id())) {
                isError = remoteAncestor.tags().containsKey("error");
            }
        }
        if (parent == null || child == null) {
            logger.fine("cannot find remote ancestor; skipping");
            continue;
        }
        addLink(parent, child, isError);
    }
    return this;
}
Also used : Kind(zipkin2.Span.Kind) Span(zipkin2.Span)

Example 3 with DependencyLinker

use of zipkin2.internal.DependencyLinker in project zipkin by openzipkin.

the class ITDependencies method aggregateLinks.

/**
 * Returns links aggregated by midnight
 */
public static Map<Long, List<DependencyLink>> aggregateLinks(List<Span> spans) {
    Map<Long, DependencyLinker> midnightToLinker = new LinkedHashMap<>();
    for (List<Span> trace : GroupByTraceId.create(false).map(spans)) {
        long midnightOfTrace = flooredTraceTimestamp(trace);
        DependencyLinker linker = midnightToLinker.get(midnightOfTrace);
        if (linker == null)
            midnightToLinker.put(midnightOfTrace, (linker = new DependencyLinker()));
        linker.putTrace(trace);
    }
    Map<Long, List<DependencyLink>> result = new LinkedHashMap<>();
    midnightToLinker.forEach((midnight, linker) -> result.put(midnight, linker.link()));
    return result;
}
Also used : DependencyLinker(zipkin2.internal.DependencyLinker) ArrayList(java.util.ArrayList) Arrays.asList(java.util.Arrays.asList) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) Span(zipkin2.Span) V1Span(zipkin2.v1.V1Span) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

Span (zipkin2.Span)3 ArrayList (java.util.ArrayList)2 DependencyLinker (zipkin2.internal.DependencyLinker)2 Arrays.asList (java.util.Arrays.asList)1 Iterator (java.util.Iterator)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Collectors.toList (java.util.stream.Collectors.toList)1 Record (org.jooq.Record)1 Record1 (org.jooq.Record1)1 Kind (zipkin2.Span.Kind)1 V1Span (zipkin2.v1.V1Span)1