io.opentelemetry.javaagent.instrumentation.kafkaclients.v0_11.metrics.KafkaMetricsConsumerInstrumentation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opentelemetry-javaagent-kafka-clients-0.11 Show documentation
Show all versions of opentelemetry-javaagent-kafka-clients-0.11 Show documentation
Instrumentation of Java libraries using OpenTelemetry.
The newest version!
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.kafkaclients.v0_11.metrics;
import static io.opentelemetry.javaagent.instrumentation.kafkaclients.v0_11.metrics.KafkaMetricsUtil.enhanceConfig;
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
public class KafkaMetricsConsumerInstrumentation implements TypeInstrumentation {
@Override
public ElementMatcher typeMatcher() {
return named("org.apache.kafka.clients.consumer.KafkaConsumer");
}
@Override
public void transform(TypeTransformer transformer) {
transformer.applyAdviceToMethod(
isConstructor().and(takesArgument(0, Map.class)),
this.getClass().getName() + "$ConstructorMapAdvice");
transformer.applyAdviceToMethod(
isConstructor().and(takesArgument(0, Properties.class)),
this.getClass().getName() + "$ConstructorPropertiesAdvice");
}
@SuppressWarnings("unused")
public static class ConstructorMapAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Argument(value = 0, readOnly = false) Map config) {
// In versions of spring-kafka prior to 2.5.0.RC1, when the `ProducerPerThread`
// of DefaultKafkaProducerFactory is set to true, the `config` object entering
// this advice block can be shared across multiple threads. Directly modifying
// `config` could lead to unexpected item loss due to race conditions, where
// some entries might be lost as different threads attempt to modify it
// concurrently.
//
// To prevent such issues, a copy of the `config` should be created here before
// any modifications are made. This ensures that each thread operates on its
// own independent copy of the configuration, thereby eliminating the risk of
// configurations corruption.
//
// More detailed information:
// https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/12538
// ensure config is a mutable map and avoid concurrency conflicts
config = new HashMap<>(config);
enhanceConfig(config);
}
}
@SuppressWarnings("unused")
public static class ConstructorPropertiesAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(@Advice.Argument(0) Properties config) {
enhanceConfig(config);
}
}
}