From f484295460a550c4ac9a2feefe9380cda64844d8 Mon Sep 17 00:00:00 2001 From: Nikolay Martynov Date: Wed, 10 Jul 2019 13:47:20 -0400 Subject: [PATCH 1/7] Kafka instrumentation: make return type more general in instrumentation matching --- .../kafka_clients/KafkaConsumerInstrumentation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java index d79e8a084b..2bad26c99e 100644 --- a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java +++ b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java @@ -1,5 +1,6 @@ package datadog.trace.instrumentation.kafka_clients; +import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType; import static datadog.trace.instrumentation.kafka_clients.KafkaDecorator.CONSUMER_DECORATE; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isPublic; @@ -55,7 +56,7 @@ public final class KafkaConsumerInstrumentation extends Instrumenter.Default { .and( takesArgument(0, String.class) .or(takesArgument(0, named("org.apache.kafka.common.TopicPartition")))) - .and(returns(Iterable.class)), + .and(returns(safeHasSuperType(named(Iterable.class.getName())))), IterableAdvice.class.getName()); transformers.put( isMethod() From 3e8b65290a18d049a67e3326cd5df0381c561bca Mon Sep 17 00:00:00 2001 From: Nikolay Martynov Date: Thu, 11 Jul 2019 10:30:44 -0400 Subject: [PATCH 2/7] Instrument records(TopicPartition) in kafka consumer --- .../KafkaConsumerInstrumentation.java | 31 +++- .../kafka_clients/TracingIterable.java | 75 +--------- .../kafka_clients/TracingIterator.java | 71 +++++++++ .../kafka_clients/TracingList.java | 140 ++++++++++++++++++ 4 files changed, 238 insertions(+), 79 deletions(-) create mode 100644 dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingIterator.java create mode 100644 dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingList.java diff --git a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java index 2bad26c99e..658741bd54 100644 --- a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java +++ b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/KafkaConsumerInstrumentation.java @@ -1,6 +1,5 @@ package datadog.trace.instrumentation.kafka_clients; -import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType; import static datadog.trace.instrumentation.kafka_clients.KafkaDecorator.CONSUMER_DECORATE; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.isPublic; @@ -13,6 +12,7 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; @@ -42,7 +42,8 @@ public final class KafkaConsumerInstrumentation extends Instrumenter.Default { packageName + ".KafkaDecorator$2", packageName + ".TextMapExtractAdapter", packageName + ".TracingIterable", - packageName + ".TracingIterable$TracingIterator", + packageName + ".TracingIterator", + packageName + ".TracingList", }; } @@ -53,11 +54,16 @@ public final class KafkaConsumerInstrumentation extends Instrumenter.Default { isMethod() .and(isPublic()) .and(named("records")) - .and( - takesArgument(0, String.class) - .or(takesArgument(0, named("org.apache.kafka.common.TopicPartition")))) - .and(returns(safeHasSuperType(named(Iterable.class.getName())))), + .and(takesArgument(0, String.class)) + .and(returns(Iterable.class)), IterableAdvice.class.getName()); + transformers.put( + isMethod() + .and(isPublic()) + .and(named("records")) + .and(takesArgument(0, named("org.apache.kafka.common.TopicPartition"))) + .and(returns(List.class)), + ListAdvice.class.getName()); transformers.put( isMethod() .and(isPublic()) @@ -78,13 +84,22 @@ public final class KafkaConsumerInstrumentation extends Instrumenter.Default { } } + public static class ListAdvice { + + @Advice.OnMethodExit(suppress = Throwable.class) + public static void wrap(@Advice.Return(readOnly = false) List iterable) { + if (iterable != null) { + iterable = new TracingList(iterable, "kafka.consume", CONSUMER_DECORATE); + } + } + } + public static class IteratorAdvice { @Advice.OnMethodExit(suppress = Throwable.class) public static void wrap(@Advice.Return(readOnly = false) Iterator iterator) { if (iterator != null) { - iterator = - new TracingIterable.TracingIterator(iterator, "kafka.consume", CONSUMER_DECORATE); + iterator = new TracingIterator(iterator, "kafka.consume", CONSUMER_DECORATE); } } } diff --git a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingIterable.java b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingIterable.java index 3757fd12ac..efe80cb1a3 100644 --- a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingIterable.java +++ b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingIterable.java @@ -1,91 +1,24 @@ package datadog.trace.instrumentation.kafka_clients; -import io.opentracing.Scope; -import io.opentracing.SpanContext; -import io.opentracing.propagation.Format; -import io.opentracing.util.GlobalTracer; import java.util.Iterator; -import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.consumer.ConsumerRecord; public class TracingIterable implements Iterable { - private final Iterable delegateIterable; + private final Iterable delegate; private final String operationName; private final KafkaDecorator decorator; public TracingIterable( - final Iterable delegateIterable, + final Iterable delegate, final String operationName, final KafkaDecorator decorator) { - this.delegateIterable = delegateIterable; + this.delegate = delegate; this.operationName = operationName; this.decorator = decorator; } @Override public Iterator iterator() { - return new TracingIterator(delegateIterable.iterator(), operationName, decorator); - } - - @Slf4j - public static class TracingIterator implements Iterator { - private final Iterator delegateIterator; - private final String operationName; - private final KafkaDecorator decorator; - - /** - * Note: this may potentially create problems if this iterator is used from different threads. - * But at the moment we cannot do much about this. - */ - private Scope currentScope; - - public TracingIterator( - final Iterator delegateIterator, - final String operationName, - final KafkaDecorator decorator) { - this.delegateIterator = delegateIterator; - this.operationName = operationName; - this.decorator = decorator; - } - - @Override - public boolean hasNext() { - if (currentScope != null) { - currentScope.close(); - currentScope = null; - } - return delegateIterator.hasNext(); - } - - @Override - public ConsumerRecord next() { - if (currentScope != null) { - // in case they didn't call hasNext()... - currentScope.close(); - currentScope = null; - } - - final ConsumerRecord next = delegateIterator.next(); - - try { - if (next != null) { - final SpanContext spanContext = - GlobalTracer.get() - .extract(Format.Builtin.TEXT_MAP, new TextMapExtractAdapter(next.headers())); - currentScope = - GlobalTracer.get().buildSpan(operationName).asChildOf(spanContext).startActive(true); - decorator.afterStart(currentScope); - decorator.onConsume(currentScope, next); - } - } catch (final Exception e) { - log.debug("Error during decoration", e); - } - return next; - } - - @Override - public void remove() { - delegateIterator.remove(); - } + return new TracingIterator(delegate.iterator(), operationName, decorator); } } diff --git a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingIterator.java b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingIterator.java new file mode 100644 index 0000000000..d6fca5a3b9 --- /dev/null +++ b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingIterator.java @@ -0,0 +1,71 @@ +package datadog.trace.instrumentation.kafka_clients; + +import io.opentracing.Scope; +import io.opentracing.SpanContext; +import io.opentracing.propagation.Format; +import io.opentracing.util.GlobalTracer; +import java.util.Iterator; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.consumer.ConsumerRecord; + +@Slf4j +public class TracingIterator implements Iterator { + private final Iterator delegateIterator; + private final String operationName; + private final KafkaDecorator decorator; + + /** + * Note: this may potentially create problems if this iterator is used from different threads. But + * at the moment we cannot do much about this. + */ + private Scope currentScope; + + public TracingIterator( + final Iterator delegateIterator, + final String operationName, + final KafkaDecorator decorator) { + this.delegateIterator = delegateIterator; + this.operationName = operationName; + this.decorator = decorator; + } + + @Override + public boolean hasNext() { + if (currentScope != null) { + currentScope.close(); + currentScope = null; + } + return delegateIterator.hasNext(); + } + + @Override + public ConsumerRecord next() { + if (currentScope != null) { + // in case they didn't call hasNext()... + currentScope.close(); + currentScope = null; + } + + final ConsumerRecord next = delegateIterator.next(); + + try { + if (next != null) { + final SpanContext spanContext = + GlobalTracer.get() + .extract(Format.Builtin.TEXT_MAP, new TextMapExtractAdapter(next.headers())); + currentScope = + GlobalTracer.get().buildSpan(operationName).asChildOf(spanContext).startActive(true); + decorator.afterStart(currentScope); + decorator.onConsume(currentScope, next); + } + } catch (final Exception e) { + log.debug("Error during decoration", e); + } + return next; + } + + @Override + public void remove() { + delegateIterator.remove(); + } +} diff --git a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingList.java b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingList.java new file mode 100644 index 0000000000..94311881fb --- /dev/null +++ b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingList.java @@ -0,0 +1,140 @@ +package datadog.trace.instrumentation.kafka_clients; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import org.apache.kafka.clients.consumer.ConsumerRecord; + +public class TracingList implements List { + private final List delegate; + private final String operationName; + private final KafkaDecorator decorator; + + public TracingList( + final List delegate, + final String operationName, + final KafkaDecorator decorator) { + this.delegate = delegate; + this.operationName = operationName; + this.decorator = decorator; + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + public boolean contains(final Object o) { + return delegate.contains(o); + } + + @Override + public Iterator iterator() { + return new TracingIterator(delegate.iterator(), operationName, decorator); + } + + @Override + public Object[] toArray() { + return delegate.toArray(); + } + + @Override + public T[] toArray(final T[] a) { + return delegate.toArray(a); + } + + @Override + public boolean add(final ConsumerRecord consumerRecord) { + return delegate.add(consumerRecord); + } + + @Override + public boolean remove(final Object o) { + return delegate.remove(o); + } + + @Override + public boolean containsAll(final Collection c) { + return delegate.containsAll(c); + } + + @Override + public boolean addAll(final Collection c) { + return delegate.addAll(c); + } + + @Override + public boolean addAll(final int index, final Collection c) { + return delegate.addAll(index, c); + } + + @Override + public boolean removeAll(final Collection c) { + return delegate.removeAll(c); + } + + @Override + public boolean retainAll(final Collection c) { + return delegate.retainAll(c); + } + + @Override + public void clear() { + delegate.clear(); + } + + @Override + public ConsumerRecord get(final int index) { + // TODO: should this be instrumented as well? + return delegate.get(index); + } + + @Override + public ConsumerRecord set(final int index, final ConsumerRecord element) { + return delegate.set(index, element); + } + + @Override + public void add(final int index, final ConsumerRecord element) { + delegate.add(index, element); + } + + @Override + public ConsumerRecord remove(final int index) { + return delegate.remove(index); + } + + @Override + public int indexOf(final Object o) { + return delegate.indexOf(o); + } + + @Override + public int lastIndexOf(final Object o) { + return delegate.lastIndexOf(o); + } + + @Override + public ListIterator listIterator() { + // TODO: should this be instrumented as well? + return delegate.listIterator(); + } + + @Override + public ListIterator listIterator(final int index) { + // TODO: should this be instrumented as well? + return delegate.listIterator(index); + } + + @Override + public List subList(final int fromIndex, final int toIndex) { + return new TracingList(delegate.subList(fromIndex, toIndex), operationName, decorator); + } +} From 765b76b0ae010f1518d227de46afe922381dc3e5 Mon Sep 17 00:00:00 2001 From: Nikolay Martynov Date: Thu, 11 Jul 2019 10:31:18 -0400 Subject: [PATCH 3/7] Fix kafka-streaming tests broken by records(TopicPartition) instrumentation --- .../KafkaStreamsProcessorInstrumentation.java | 6 ++- .../src/test/groovy/KafkaStreamsTest.groovy | 44 +++++++++++++------ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsProcessorInstrumentation.java b/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsProcessorInstrumentation.java index 07fa3754c5..fc8e4bdf19 100644 --- a/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsProcessorInstrumentation.java +++ b/dd-java-agent/instrumentation/kafka-streams-0.11/src/main/java/datadog/trace/instrumentation/kafka_streams/KafkaStreamsProcessorInstrumentation.java @@ -24,7 +24,11 @@ import org.apache.kafka.streams.processor.internals.StampedRecord; public class KafkaStreamsProcessorInstrumentation { // These two instrumentations work together to apply StreamTask.process. - // The combination of these are needed because there's not a good instrumentation point. + // The combination of these is needed because there's no good instrumentation point. + // FIXME: this instrumentation takes somewhat strange approach. It looks like Kafka Streams + // defines notions of 'processor', 'source' and 'sink'. There is no 'consumer' as such. + // Also this instrumentation doesn't define 'producer' making it 'asymmetric' - resulting + // in awkward tests and traces. We may want to revisit this in the future. @AutoService(Instrumenter.class) public static class StartInstrumentation extends Instrumenter.Default { diff --git a/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy b/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy index d74433ec11..f957b872eb 100644 --- a/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy +++ b/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy @@ -80,13 +80,13 @@ class KafkaStreamsTest extends AgentTestRunner { KStream textLines = builder.stream(STREAM_PENDING) def values = textLines .mapValues(new ValueMapper() { - @Override - String apply(String textLine) { - TEST_WRITER.waitForTraces(1) // ensure consistent ordering of traces - getTestTracer().activeSpan().setTag("asdf", "testing") - return textLine.toLowerCase() - } - }) + @Override + String apply(String textLine) { + TEST_WRITER.waitForTraces(1) // ensure consistent ordering of traces + getTestTracer().activeSpan().setTag("asdf", "testing") + return textLine.toLowerCase() + } + }) KafkaStreams streams try { @@ -115,7 +115,7 @@ class KafkaStreamsTest extends AgentTestRunner { received.value() == greeting.toLowerCase() received.key() == null - assertTraces(3) { + assertTraces(4) { trace(0, 1) { // PRODUCER span 0 span(0) { @@ -132,7 +132,25 @@ class KafkaStreamsTest extends AgentTestRunner { } } } - trace(1, 2) { + trace(1, 1) { + // CONSUMER span 0 + span(0) { + serviceName "kafka" + operationName "kafka.consume" + resourceName "Consume Topic $STREAM_PENDING" + spanType "queue" + errored false + childOf TEST_WRITER[0][0] + tags { + "component" "java-kafka" + "span.kind" "consumer" + "partition" { it >= 0 } + "offset" 0 + defaultTags(true) + } + } + } + trace(2, 2) { // STREAMING span 0 span(0) { @@ -169,7 +187,7 @@ class KafkaStreamsTest extends AgentTestRunner { } } } - trace(2, 1) { + trace(3, 1) { // CONSUMER span 0 span(0) { serviceName "kafka" @@ -177,7 +195,7 @@ class KafkaStreamsTest extends AgentTestRunner { resourceName "Consume Topic $STREAM_PROCESSED" spanType "queue" errored false - childOf TEST_WRITER[1][0] + childOf TEST_WRITER[2][0] tags { "component" "java-kafka" "span.kind" "consumer" @@ -192,8 +210,8 @@ class KafkaStreamsTest extends AgentTestRunner { def headers = received.headers() headers.iterator().hasNext() - new String(headers.headers("x-datadog-trace-id").iterator().next().value()) == "${TEST_WRITER[1][0].traceId}" - new String(headers.headers("x-datadog-parent-id").iterator().next().value()) == "${TEST_WRITER[1][0].spanId}" + new String(headers.headers("x-datadog-trace-id").iterator().next().value()) == "${TEST_WRITER[2][0].traceId}" + new String(headers.headers("x-datadog-parent-id").iterator().next().value()) == "${TEST_WRITER[2][0].spanId}" cleanup: From 3ecc7c123d7b63053a94d0b9f178f9a368bed0eb Mon Sep 17 00:00:00 2001 From: Nikolay Martynov Date: Thu, 11 Jul 2019 10:51:55 -0400 Subject: [PATCH 4/7] Wait for traces in kafka streams tests --- .../src/test/groovy/KafkaStreamsTest.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy b/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy index f957b872eb..29305d8968 100644 --- a/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy +++ b/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy @@ -57,7 +57,7 @@ class KafkaStreamsTest extends AgentTestRunner { void onMessage(ConsumerRecord record) { // ensure consistent ordering of traces // this is the last processing step so we should see 2 traces here - TEST_WRITER.waitForTraces(2) + TEST_WRITER.waitForTraces(3) getTestTracer().activeSpan().setTag("testing", 123) records.add(record) } @@ -82,7 +82,7 @@ class KafkaStreamsTest extends AgentTestRunner { .mapValues(new ValueMapper() { @Override String apply(String textLine) { - TEST_WRITER.waitForTraces(1) // ensure consistent ordering of traces + TEST_WRITER.waitForTraces(2) // ensure consistent ordering of traces getTestTracer().activeSpan().setTag("asdf", "testing") return textLine.toLowerCase() } From f4aa8be7c5b56c7aea067c5550b1f5d805b13dd6 Mon Sep 17 00:00:00 2001 From: Nikolay Martynov Date: Thu, 11 Jul 2019 11:07:17 -0400 Subject: [PATCH 5/7] Make kafka streams test more stable --- .../src/test/groovy/KafkaStreamsTest.groovy | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy b/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy index 29305d8968..dda624d385 100644 --- a/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy +++ b/dd-java-agent/instrumentation/kafka-streams-0.11/src/test/groovy/KafkaStreamsTest.groovy @@ -115,6 +115,13 @@ class KafkaStreamsTest extends AgentTestRunner { received.value() == greeting.toLowerCase() received.key() == null + if (TEST_WRITER[1][0].operationName == "kafka.produce") { + // Make sure that order of first two traces is predetermined. + // Unfortunately it looks like we cannot really control it in a better way through the code + def tmp = TEST_WRITER[1][0] + TEST_WRITER[1][0] = TEST_WRITER[0][0] + TEST_WRITER[0][0] = tmp + } assertTraces(4) { trace(0, 1) { // PRODUCER span 0 From b3c970d6c71a9bcd86443724b171d3041a1b514c Mon Sep 17 00:00:00 2001 From: Nikolay Martynov Date: Thu, 11 Jul 2019 13:45:40 -0400 Subject: [PATCH 6/7] Formatting fix --- dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java b/dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java index d09e0d1ca6..74bf6129e7 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java @@ -441,7 +441,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace @Deprecated private static Map customRuntimeTags( - final String runtimeId, Map applicationRootSpanTags) { + final String runtimeId, final Map applicationRootSpanTags) { final Map runtimeTags = new HashMap<>(applicationRootSpanTags); runtimeTags.put(Config.RUNTIME_ID_TAG, runtimeId); return Collections.unmodifiableMap(runtimeTags); From 6516bd7ad7405ab0c45db38991ce403c923e7090 Mon Sep 17 00:00:00 2001 From: Nikolay Martynov Date: Fri, 12 Jul 2019 16:26:39 -0400 Subject: [PATCH 7/7] Minor comment update --- .../trace/instrumentation/kafka_clients/TracingList.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingList.java b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingList.java index 94311881fb..f7e12cb233 100644 --- a/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingList.java +++ b/dd-java-agent/instrumentation/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/TracingList.java @@ -123,13 +123,15 @@ public class TracingList implements List { @Override public ListIterator listIterator() { - // TODO: should this be instrumented as well? + // TODO: the API for ListIterator is not really good to instrument it in context of Kafka + // Consumer so we will not do that for now return delegate.listIterator(); } @Override public ListIterator listIterator(final int index) { - // TODO: should this be instrumented as well? + // TODO: the API for ListIterator is not really good to instrument it in context of Kafka + // Consumer so we will not do that for now return delegate.listIterator(index); }