Search in sources :

Example 1 with Span

use of zipkin.Span in project zipkin by openzipkin.

the class ZipkinServerTest method readsBackSpanName.

@Test
public void readsBackSpanName() throws Exception {
    String service = "web";
    Endpoint endpoint = Endpoint.create(service, 127 << 24 | 1, 80);
    Annotation ann = Annotation.create(System.currentTimeMillis() * 1000, SERVER_RECV, endpoint);
    Span span = Span.builder().id(1L).traceId(1L).name("get").addAnnotation(ann).build();
    // write the span to the server
    performAsync(post("/api/v1/spans").content(Codec.JSON.writeSpans(asList(span)))).andExpect(status().isAccepted());
    // sleep as the the storage operation is async
    Thread.sleep(1000);
    // read back the span name, given its service
    mockMvc.perform(get("/api/v1/spans?serviceName=" + service)).andExpect(status().isOk()).andExpect(content().string("[\"" + span.name + "\"]"));
}
Also used : Endpoint(zipkin.Endpoint) Span(zipkin.Span) Annotation(zipkin.Annotation) Test(org.junit.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest)

Example 2 with Span

use of zipkin.Span in project zipkin by openzipkin.

the class ZipkinServerIntegrationTest method readsRawTrace.

@Test
public void readsRawTrace() throws Exception {
    Span span = TRACE.get(0);
    // write the span to the server, twice
    performAsync(post("/api/v1/spans").content(Codec.JSON.writeSpans(asList(span)))).andExpect(status().isAccepted());
    performAsync(post("/api/v1/spans").content(Codec.JSON.writeSpans(asList(span)))).andExpect(status().isAccepted());
    // sleep as the the storage operation is async
    Thread.sleep(1500);
    // Default will merge by span id
    mockMvc.perform(get(format("/api/v1/trace/%016x", span.traceId))).andExpect(status().isOk()).andExpect(content().string(new String(Codec.JSON.writeSpans(asList(span)), UTF_8)));
    // In the in-memory (or cassandra) stores, a raw read will show duplicate span rows.
    mockMvc.perform(get(format("/api/v1/trace/%016x?raw", span.traceId))).andExpect(status().isOk()).andExpect(content().string(new String(Codec.JSON.writeSpans(asList(span, span)), UTF_8)));
}
Also used : Span(zipkin.Span) Test(org.junit.Test) SpringBootTest(org.springframework.boot.test.context.SpringBootTest)

Example 3 with Span

use of zipkin.Span in project zipkin by openzipkin.

the class CassandraSpanConsumer method accept.

/**
   * This fans out into many requests, last count was 8 * spans.size. If any of these fail, the
   * returned future will fail. Most callers drop or log the result.
   */
@Override
public ListenableFuture<Void> accept(List<Span> rawSpans) {
    ImmutableSet.Builder<ListenableFuture<?>> futures = ImmutableSet.builder();
    ImmutableList.Builder<Span> spans = ImmutableList.builder();
    for (Span span : rawSpans) {
        // indexing occurs by timestamp, so derive one if not present.
        Long timestamp = guessTimestamp(span);
        spans.add(span);
        boolean isServerRecvSpan = isServerRecvSpan(span);
        futures.add(storeSpan(span.traceId, timestamp != null ? timestamp : 0L, isServerRecvSpan, String.format("%s%d_%d_%d", span.traceIdHigh == 0 ? "" : span.traceIdHigh + "_", span.id, span.annotations.hashCode(), span.binaryAnnotations.hashCode()), // store the raw span without any adjustments
        ByteBuffer.wrap(Codec.THRIFT.writeSpan(span))));
        for (String serviceName : span.serviceNames()) {
            // SpanStore.getServiceNames
            futures.add(storeServiceName(serviceName));
            if (!span.name.isEmpty()) {
                // SpanStore.getSpanNames
                futures.add(storeSpanName(serviceName, span.name));
            }
        }
    }
    futures.addAll(indexer.index(spans.build()));
    return transform(Futures.allAsList(futures.build()), TO_VOID);
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableList(com.google.common.collect.ImmutableList) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Span(zipkin.Span)

Example 4 with Span

use of zipkin.Span in project zipkin by openzipkin.

the class CassandraSpanConsumer method accept.

/**
   * This fans out into many requests, last count was 2 * spans.size. If any of these fail, the
   * returned future will fail. Most callers drop or log the result.
   */
@Override
public ListenableFuture<Void> accept(List<Span> rawSpans) {
    ImmutableSet.Builder<ListenableFuture<?>> futures = ImmutableSet.builder();
    for (Span span : rawSpans) {
        // indexing occurs by timestamp, so derive one if not present.
        Long timestamp = guessTimestamp(span);
        TraceIdUDT traceId = new TraceIdUDT(span.traceIdHigh, span.traceId);
        boolean isServerRecvSpan = isServerRecvSpan(span);
        futures.add(storeSpan(span, traceId, isServerRecvSpan, timestamp));
        for (String serviceName : span.serviceNames()) {
            // QueryRequest.min/maxDuration
            if (timestamp != null) {
                // Contract for Repository.storeTraceServiceSpanName is to store the span twice, once with
                // the span name and another with empty string.
                futures.add(storeTraceServiceSpanName(serviceName, span.name, timestamp, span.duration, traceId));
                if (!span.name.isEmpty()) {
                    // If span.name == "", this would be redundant
                    futures.add(storeTraceServiceSpanName(serviceName, "", timestamp, span.duration, traceId));
                }
                futures.add(storeServiceSpanName(serviceName, span.name));
            }
        }
    }
    return transform(Futures.allAsList(futures.build()), TO_VOID);
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Span(zipkin.Span) TraceIdUDT(zipkin.storage.cassandra3.Schema.TraceIdUDT)

Example 5 with Span

use of zipkin.Span in project zipkin by openzipkin.

the class Indexer method index.

ImmutableSet<ListenableFuture<?>> index(List<Span> spans) {
    // First parse each span into partition keys used to support query requests
    Builder<PartitionKeyToTraceId, Long> parsed = ImmutableSetMultimap.builder();
    for (Span span : spans) {
        Long timestamp = guessTimestamp(span);
        if (timestamp == null)
            continue;
        for (String partitionKey : index.partitionKeys(span)) {
            parsed.put(new PartitionKeyToTraceId(index.table(), partitionKey, span.traceId), // index precision is millis
            1000 * (timestamp / 1000));
        }
    }
    // The parsed results may include inserts that already occur, or are redundant as they don't
    // impact QueryRequest.endTs or QueryRequest.loopback. For example, a parsed timestamp could
    // be between timestamps of rows that already exist for a particular trace.
    ImmutableSetMultimap<PartitionKeyToTraceId, Long> maybeInsert = parsed.build();
    ImmutableSetMultimap<PartitionKeyToTraceId, Long> toInsert;
    if (sharedState == null) {
        // special-case when caching is disabled.
        toInsert = maybeInsert;
    } else {
        // Optimized results will be smaller when the input includes traces with local spans, or when
        // other threads indexed the same trace.
        toInsert = entriesThatIncreaseGap(sharedState, maybeInsert);
        if (maybeInsert.size() > toInsert.size() && LOG.isDebugEnabled()) {
            int delta = maybeInsert.size() - toInsert.size();
            LOG.debug("optimized out {}/{} inserts into {}", delta, maybeInsert.size(), index.table());
        }
    }
    // For each entry, insert a new row in the index table asynchronously
    ImmutableSet.Builder<ListenableFuture<?>> result = ImmutableSet.builder();
    for (Map.Entry<PartitionKeyToTraceId, Long> entry : toInsert.entries()) {
        BoundStatement bound = bindWithName(prepared, boundName).setLong("trace_id", entry.getKey().traceId).setBytesUnsafe("ts", timestampCodec.serialize(entry.getValue()));
        if (indexTtl != null) {
            bound.setInt("ttl_", indexTtl);
        }
        index.bindPartitionKey(bound, entry.getKey().partitionKey);
        result.add(session.executeAsync(bound));
    }
    return result.build();
}
Also used : Span(zipkin.Span) ImmutableSet(com.google.common.collect.ImmutableSet) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map) BoundStatement(com.datastax.driver.core.BoundStatement)

Aggregations

Span (zipkin.Span)102 Test (org.junit.Test)83 Endpoint (zipkin.Endpoint)21 BinaryAnnotation (zipkin.BinaryAnnotation)12 ArrayList (java.util.ArrayList)10 Annotation (zipkin.Annotation)10 CodecTest (zipkin.CodecTest)9 CorrectForClockSkew.isLocalSpan (zipkin.internal.CorrectForClockSkew.isLocalSpan)9 ByteBuffer (java.nio.ByteBuffer)8 List (java.util.List)8 Buffer (okio.Buffer)8 LinkedHashMap (java.util.LinkedHashMap)6 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)5 ImmutableList (com.google.common.collect.ImmutableList)4 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)4 LinkedList (java.util.LinkedList)4 Constants (zipkin.Constants)4 ImmutableSet (com.google.common.collect.ImmutableSet)3 IOException (java.io.IOException)3 Arrays.asList (java.util.Arrays.asList)3