|
19 | 19 | import io.opentelemetry.instrumentation.kafkaclients.common.v0_11.internal.TracingIterable; |
20 | 20 | import io.opentelemetry.instrumentation.kafkaclients.common.v0_11.internal.TracingIterator; |
21 | 21 | import io.opentelemetry.instrumentation.kafkaclients.common.v0_11.internal.TracingList; |
| 22 | +import io.opentelemetry.instrumentation.kafkaclients.common.v0_11.internal.TracingListIterator; |
22 | 23 | import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; |
23 | 24 | import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; |
24 | 25 | import java.util.Iterator; |
25 | 26 | import java.util.List; |
| 27 | +import java.util.ListIterator; |
26 | 28 | import net.bytebuddy.asm.Advice; |
27 | | -import net.bytebuddy.asm.Advice.AssignReturned; |
28 | 29 | import net.bytebuddy.description.type.TypeDescription; |
29 | 30 | import net.bytebuddy.matcher.ElementMatcher; |
30 | 31 | import org.apache.kafka.clients.consumer.ConsumerRecord; |
@@ -60,62 +61,95 @@ public void transform(TypeTransformer transformer) { |
60 | 61 | .and(takesArguments(0)) |
61 | 62 | .and(returns(Iterator.class)), |
62 | 63 | ConsumerRecordsInstrumentation.class.getName() + "$IteratorAdvice"); |
| 64 | + transformer.applyAdviceToMethod( |
| 65 | + isMethod() |
| 66 | + .and(isPublic()) |
| 67 | + .and(named("listIterator")) |
| 68 | + .and(takesArguments(0)) |
| 69 | + .and(returns(ListIterator.class)), |
| 70 | + ConsumerRecordsInstrumentation.class.getName() + "$ListIteratorAdvice"); |
63 | 71 | } |
64 | 72 |
|
65 | 73 | @SuppressWarnings("unused") |
66 | 74 | public static class IterableAdvice { |
67 | 75 |
|
68 | | - @AssignReturned.ToReturned |
| 76 | + @SuppressWarnings("unchecked") |
69 | 77 | @Advice.OnMethodExit(suppress = Throwable.class) |
70 | | - public static <K, V> Iterable<ConsumerRecord<K, V>> wrap( |
| 78 | + public static <K, V> void wrap( |
71 | 79 | @Advice.This ConsumerRecords<?, ?> records, |
72 | | - @Advice.Return Iterable<ConsumerRecord<K, V>> iterable) { |
| 80 | + @Advice.Return(readOnly = false) Iterable<ConsumerRecord<K, V>> iterable) { |
73 | 81 |
|
74 | 82 | // it's important not to suppress consumer span creation here because this instrumentation can |
75 | 83 | // leak the context and so there may be a leaked consumer span in the context, in which |
76 | 84 | // case it's important to overwrite the leaked span instead of suppressing the correct span |
77 | 85 | // (https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/1947) |
78 | 86 | KafkaConsumerContext consumerContext = KafkaConsumerContextUtil.get(records); |
79 | | - return TracingIterable.wrap( |
80 | | - iterable, consumerProcessInstrumenter(), wrappingEnabledSupplier(), consumerContext); |
| 87 | + iterable = |
| 88 | + TracingIterable.wrap( |
| 89 | + iterable, consumerProcessInstrumenter(), wrappingEnabledSupplier(), consumerContext); |
81 | 90 | } |
82 | 91 | } |
83 | 92 |
|
84 | 93 | @SuppressWarnings("unused") |
85 | 94 | public static class ListAdvice { |
86 | 95 |
|
87 | | - @AssignReturned.ToReturned |
| 96 | + @SuppressWarnings("unchecked") |
88 | 97 | @Advice.OnMethodExit(suppress = Throwable.class) |
89 | | - public static <K, V> List<ConsumerRecord<K, V>> wrap( |
| 98 | + public static <K, V> void wrap( |
90 | 99 | @Advice.This ConsumerRecords<?, ?> records, |
91 | | - @Advice.Return List<ConsumerRecord<K, V>> list) { |
| 100 | + @Advice.Return(readOnly = false) List<ConsumerRecord<K, V>> list) { |
92 | 101 |
|
93 | 102 | // it's important not to suppress consumer span creation here because this instrumentation can |
94 | 103 | // leak the context and so there may be a leaked consumer span in the context, in which |
95 | 104 | // case it's important to overwrite the leaked span instead of suppressing the correct span |
96 | 105 | // (https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/1947) |
97 | 106 | KafkaConsumerContext consumerContext = KafkaConsumerContextUtil.get(records); |
98 | | - return TracingList.wrap( |
99 | | - list, consumerProcessInstrumenter(), wrappingEnabledSupplier(), consumerContext); |
| 107 | + list = |
| 108 | + TracingList.wrap( |
| 109 | + list, consumerProcessInstrumenter(), wrappingEnabledSupplier(), consumerContext); |
100 | 110 | } |
101 | 111 | } |
102 | 112 |
|
103 | 113 | @SuppressWarnings("unused") |
104 | 114 | public static class IteratorAdvice { |
105 | 115 |
|
106 | | - @AssignReturned.ToReturned |
| 116 | + @SuppressWarnings("unchecked") |
| 117 | + @Advice.OnMethodExit(suppress = Throwable.class) |
| 118 | + public static <K, V> void wrap( |
| 119 | + @Advice.This ConsumerRecords<?, ?> records, |
| 120 | + @Advice.Return(readOnly = false) Iterator<ConsumerRecord<K, V>> iterator) { |
| 121 | + |
| 122 | + // it's important not to suppress consumer span creation here because this instrumentation can |
| 123 | + // leak the context and so there may be a leaked consumer span in the context, in which |
| 124 | + // case it's important to overwrite the leaked span instead of suppressing the correct span |
| 125 | + // (https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/1947) |
| 126 | + KafkaConsumerContext consumerContext = KafkaConsumerContextUtil.get(records); |
| 127 | + iterator = |
| 128 | + TracingIterator.wrap( |
| 129 | + iterator, consumerProcessInstrumenter(), wrappingEnabledSupplier(), consumerContext); |
| 130 | + } |
| 131 | + } |
| 132 | + |
| 133 | + @SuppressWarnings("unused") |
| 134 | + public static class ListIteratorAdvice { |
| 135 | + |
| 136 | + @SuppressWarnings("unchecked") |
107 | 137 | @Advice.OnMethodExit(suppress = Throwable.class) |
108 | | - public static <K, V> Iterator<ConsumerRecord<K, V>> wrap( |
| 138 | + public static <K, V> void wrap( |
109 | 139 | @Advice.This ConsumerRecords<?, ?> records, |
110 | | - @Advice.Return Iterator<ConsumerRecord<K, V>> iterator) { |
| 140 | + @Advice.Return(readOnly = false) ListIterator<ConsumerRecord<K, V>> listIterator) { |
111 | 141 |
|
112 | 142 | // it's important not to suppress consumer span creation here because this instrumentation can |
113 | 143 | // leak the context and so there may be a leaked consumer span in the context, in which |
114 | 144 | // case it's important to overwrite the leaked span instead of suppressing the correct span |
115 | 145 | // (https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/1947) |
116 | 146 | KafkaConsumerContext consumerContext = KafkaConsumerContextUtil.get(records); |
117 | | - return TracingIterator.wrap( |
118 | | - iterator, consumerProcessInstrumenter(), wrappingEnabledSupplier(), consumerContext); |
| 147 | + listIterator = |
| 148 | + TracingListIterator.wrap( |
| 149 | + listIterator, |
| 150 | + consumerProcessInstrumenter(), |
| 151 | + wrappingEnabledSupplier(), |
| 152 | + consumerContext); |
119 | 153 | } |
120 | 154 | } |
121 | 155 | } |
0 commit comments