Search in sources :

Example 1 with CONSUMER

use of zipkin2.Span.Kind.CONSUMER in project brave by openzipkin.

the class TracingConsumer method poll.

/**
 * This
 */
@Override
public ConsumerRecords<K, V> poll(long timeout) {
    ConsumerRecords<K, V> records = delegate.poll(timeout);
    if (records.isEmpty() || tracing.isNoop())
        return records;
    Map<String, Span> consumerSpansForTopic = new LinkedHashMap<>();
    for (TopicPartition partition : records.partitions()) {
        String topic = partition.topic();
        List<ConsumerRecord<K, V>> recordsInPartition = records.records(partition);
        for (int i = 0, length = recordsInPartition.size(); i < length; i++) {
            ConsumerRecord<K, V> record = recordsInPartition.get(i);
            TraceContextOrSamplingFlags extracted = extractor.extract(record.headers());
            // make or reuse a span for this topic
            if (extracted.samplingFlags() != null && extracted.extra().isEmpty()) {
                Span consumerSpanForTopic = consumerSpansForTopic.get(topic);
                if (consumerSpanForTopic == null) {
                    consumerSpansForTopic.put(topic, consumerSpanForTopic = tracing.tracer().nextSpan(extracted).name("poll").kind(Span.Kind.CONSUMER).tag(KafkaTags.KAFKA_TOPIC_TAG, topic).start());
                }
                // no need to remove propagation headers as we failed to extract anything
                injector.inject(consumerSpanForTopic.context(), record.headers());
            } else {
                // we extracted request-scoped data, so cannot share a consumer span.
                Span span = tracing.tracer().nextSpan(extracted);
                if (!span.isNoop()) {
                    span.name("poll").kind(Span.Kind.CONSUMER).tag(KafkaTags.KAFKA_TOPIC_TAG, topic);
                    if (remoteServiceName != null) {
                        span.remoteEndpoint(Endpoint.newBuilder().serviceName(remoteServiceName).build());
                    }
                    // span won't be shared by other records
                    span.start().finish();
                }
                // remove prior propagation headers from the record
                tracing.propagation().keys().forEach(key -> record.headers().remove(key));
                injector.inject(span.context(), record.headers());
            }
        }
    }
    consumerSpansForTopic.values().forEach(span -> {
        if (remoteServiceName != null) {
            span.remoteEndpoint(Endpoint.newBuilder().serviceName(remoteServiceName).build());
        }
        span.finish();
    });
    return records;
}
Also used : Span(brave.Span) ConsumerRecord(org.apache.kafka.clients.consumer.ConsumerRecord) Endpoint(zipkin2.Endpoint) LinkedHashMap(java.util.LinkedHashMap) TopicPartition(org.apache.kafka.common.TopicPartition) TraceContextOrSamplingFlags(brave.propagation.TraceContextOrSamplingFlags)

Example 2 with CONSUMER

use of zipkin2.Span.Kind.CONSUMER in project brave by openzipkin.

the class ITKafkaTracing method continues_a_trace_when_only_trace_id_propagated.

@Test
public void continues_a_trace_when_only_trace_id_propagated() throws Exception {
    consumerTracing = KafkaTracing.create(Tracing.newBuilder().spanReporter(consumerSpans::add).propagationFactory(new Propagation.Factory() {

        @Override
        public <K> Propagation<K> create(Propagation.KeyFactory<K> keyFactory) {
            return new TraceIdOnlyPropagation<>(keyFactory);
        }
    }).sampler(Sampler.ALWAYS_SAMPLE).build());
    producerTracing = KafkaTracing.create(Tracing.newBuilder().spanReporter(producerSpans::add).propagationFactory(new Propagation.Factory() {

        @Override
        public <K> Propagation<K> create(Propagation.KeyFactory<K> keyFactory) {
            return new TraceIdOnlyPropagation<>(keyFactory);
        }
    }).sampler(Sampler.ALWAYS_SAMPLE).build());
    producer = createTracingProducer();
    consumer = createTracingConsumer();
    producer.send(new ProducerRecord<>(testName.getMethodName(), TEST_KEY, TEST_VALUE)).get();
    ConsumerRecords<String, String> records = consumer.poll(10000);
    assertThat(records).hasSize(1);
    Span producerSpan = producerSpans.take();
    Span consumerSpan = consumerSpans.take();
    assertThat(producerSpan.traceId()).isEqualTo(consumerSpan.traceId());
    for (ConsumerRecord<String, String> record : records) {
        TraceContext forProcessor = consumerTracing.nextSpan(record).context();
        assertThat(forProcessor.traceIdString()).isEqualTo(consumerSpan.traceId());
    }
}
Also used : Propagation(brave.propagation.Propagation) ProducerRecord(org.apache.kafka.clients.producer.ProducerRecord) TraceContext(brave.propagation.TraceContext) Span(zipkin2.Span) Test(org.junit.Test)

Example 3 with CONSUMER

use of zipkin2.Span.Kind.CONSUMER in project brave by openzipkin.

the class TracingRabbitListenerAdviceTest method reports_span_if_consume_fails.

@Test
public void reports_span_if_consume_fails() throws Throwable {
    Message message = MessageBuilder.withBody(new byte[] {}).build();
    onMessageConsumeFailed(message, new RuntimeException("expected exception"));
    assertThat(reportedSpans).extracting(Span::kind).containsExactly(CONSUMER, null);
    assertThat(reportedSpans).filteredOn(span -> span.kind() == null).extracting(Span::tags).extracting(tags -> tags.get("error")).contains("expected exception");
}
Also used : Tracing(brave.Tracing) MessageBuilder(org.springframework.amqp.core.MessageBuilder) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Span(zipkin2.Span) Test(org.junit.Test) MessageProperties(org.springframework.amqp.core.MessageProperties) Mockito.when(org.mockito.Mockito.when) ArrayList(java.util.ArrayList) List(java.util.List) Sampler(brave.sampler.Sampler) MethodInvocation(org.aopalliance.intercept.MethodInvocation) Message(org.springframework.amqp.core.Message) Assert.fail(org.junit.Assert.fail) CONSUMER(zipkin2.Span.Kind.CONSUMER) Before(org.junit.Before) Mockito.mock(org.mockito.Mockito.mock) Message(org.springframework.amqp.core.Message) Span(zipkin2.Span) Test(org.junit.Test)

Example 4 with CONSUMER

use of zipkin2.Span.Kind.CONSUMER in project brave by openzipkin.

the class TracingRabbitListenerAdviceTest method reports_span_if_consume_fails_with_no_message.

@Test
public void reports_span_if_consume_fails_with_no_message() throws Throwable {
    Message message = MessageBuilder.withBody(new byte[] {}).build();
    onMessageConsumeFailed(message, new RuntimeException());
    assertThat(reportedSpans).extracting(Span::kind).containsExactly(CONSUMER, null);
    assertThat(reportedSpans).filteredOn(span -> span.kind() == null).extracting(Span::tags).extracting(tags -> tags.get("error")).contains("RuntimeException");
}
Also used : Tracing(brave.Tracing) MessageBuilder(org.springframework.amqp.core.MessageBuilder) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Span(zipkin2.Span) Test(org.junit.Test) MessageProperties(org.springframework.amqp.core.MessageProperties) Mockito.when(org.mockito.Mockito.when) ArrayList(java.util.ArrayList) List(java.util.List) Sampler(brave.sampler.Sampler) MethodInvocation(org.aopalliance.intercept.MethodInvocation) Message(org.springframework.amqp.core.Message) Assert.fail(org.junit.Assert.fail) CONSUMER(zipkin2.Span.Kind.CONSUMER) Before(org.junit.Before) Mockito.mock(org.mockito.Mockito.mock) Message(org.springframework.amqp.core.Message) Span(zipkin2.Span) Test(org.junit.Test)

Example 5 with CONSUMER

use of zipkin2.Span.Kind.CONSUMER 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();
}
Also used : Span(zipkin2.Span) Annotation(zipkin.Annotation) BinaryAnnotation(zipkin.BinaryAnnotation) Endpoint(zipkin2.Endpoint) Kind(zipkin2.Span.Kind) Map(java.util.Map)

Aggregations

Span (zipkin2.Span)17 Test (org.junit.Test)13 Test (org.junit.jupiter.api.Test)7 LogEntry (zipkin2.collector.scribe.generated.LogEntry)6 ProducerRecord (org.apache.kafka.clients.producer.ProducerRecord)4 Call (zipkin2.Call)4 Endpoint (zipkin2.Endpoint)4 StorageComponent (zipkin2.storage.StorageComponent)4 List (java.util.List)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 TopicPartition (org.apache.kafka.common.TopicPartition)3 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)3 Before (org.junit.Before)3 Tracing (brave.Tracing)2 Sampler (brave.sampler.Sampler)2 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 TimeUnit (java.util.concurrent.TimeUnit)2 MethodInvocation (org.aopalliance.intercept.MethodInvocation)2 ConsumerRecord (org.apache.kafka.clients.consumer.ConsumerRecord)2