From 166a48472ebb7caa942451f15d4c48f0a92a9bba Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Wed, 3 Dec 2025 18:38:58 +0200 Subject: [PATCH 1/2] Exclude otel micrometer instruments from reading values --- ...AbstractCompositeMeterInstrumentation.java | 101 ++++++++++++++++++ .../v1_5/MicrometerInstrumentationModule.java | 4 +- .../micrometer/v1_5/MicrometerSingletons.java | 44 ++++++++ .../micrometer/v1_5/CompositeCounterTest.java | 75 +++++++++++++ .../micrometer/v1_5/OpenTelemetryCounter.java | 3 +- .../OpenTelemetryDistributionSummary.java | 2 +- .../v1_5/OpenTelemetryFunctionCounter.java | 2 +- .../v1_5/OpenTelemetryFunctionTimer.java | 2 +- .../micrometer/v1_5/OpenTelemetryGauge.java | 3 +- .../v1_5/OpenTelemetryInstrument.java | 9 ++ .../v1_5/OpenTelemetryLongTaskTimer.java | 3 +- .../micrometer/v1_5/OpenTelemetryMeter.java | 3 +- .../micrometer/v1_5/OpenTelemetryTimer.java | 3 +- 13 files changed, 244 insertions(+), 10 deletions(-) create mode 100644 instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/AbstractCompositeMeterInstrumentation.java create mode 100644 instrumentation/micrometer/micrometer-1.5/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/CompositeCounterTest.java create mode 100644 instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryInstrument.java diff --git a/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/AbstractCompositeMeterInstrumentation.java b/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/AbstractCompositeMeterInstrumentation.java new file mode 100644 index 000000000000..3061f225fb4c --- /dev/null +++ b/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/AbstractCompositeMeterInstrumentation.java @@ -0,0 +1,101 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.micrometer.v1_5; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AsmApi; +import java.util.Collection; +import net.bytebuddy.asm.AsmVisitorWrapper; +import net.bytebuddy.description.field.FieldDescription; +import net.bytebuddy.description.field.FieldList; +import net.bytebuddy.description.method.MethodList; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.implementation.Implementation; +import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.pool.TypePool; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; + +public class AbstractCompositeMeterInstrumentation implements TypeInstrumentation { + + @Override + public ElementMatcher typeMatcher() { + return named("io.micrometer.core.instrument.composite.AbstractCompositeMeter"); + } + + @Override + public void transform(TypeTransformer transformer) { + transformer.applyTransformer( + (builder, typeDescription, classLoader, javaModule, protectionDomain) -> + builder.visit( + new AsmVisitorWrapper() { + @Override + public int mergeWriter(int flags) { + return flags; + } + + @Override + public int mergeReader(int flags) { + return flags; + } + + @Override + public ClassVisitor wrap( + TypeDescription instrumentedType, + ClassVisitor classVisitor, + Implementation.Context implementationContext, + TypePool typePool, + FieldList fields, + MethodList methods, + int writerFlags, + int readerFlags) { + return new ClassVisitor(AsmApi.VERSION, classVisitor) { + @Override + public MethodVisitor visitMethod( + int access, + String name, + String descriptor, + String signature, + String[] exceptions) { + MethodVisitor mv = + super.visitMethod(access, name, descriptor, signature, exceptions); + if ("firstChild".equals(name)) { + return new MethodVisitor(api, mv) { + @Override + public void visitMethodInsn( + int opcode, + String owner, + String name, + String descriptor, + boolean isInterface) { + super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); + if (Opcodes.INVOKEINTERFACE == opcode + && Type.getInternalName(Collection.class).equals(owner) + && "iterator".equals(name) + && "()Ljava/util/Iterator;".equals(descriptor)) { + // wrap the returned iterator to filter out our MeterRegistry + super.visitMethodInsn( + Opcodes.INVOKESTATIC, + Type.getInternalName(MicrometerSingletons.class), + "wrapIterator", + "(Ljava/util/Iterator;)Ljava/util/Iterator;", + false); + } + } + }; + } + return mv; + } + }; + } + })); + } +} diff --git a/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerInstrumentationModule.java b/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerInstrumentationModule.java index ec72937bc8c5..6ef75f8c5c20 100644 --- a/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerInstrumentationModule.java +++ b/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerInstrumentationModule.java @@ -6,12 +6,12 @@ package io.opentelemetry.javaagent.instrumentation.micrometer.v1_5; import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; +import static java.util.Arrays.asList; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import java.util.Collections; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @@ -36,6 +36,6 @@ public ElementMatcher.Junction classLoaderMatcher() { @Override public List typeInstrumentations() { - return Collections.singletonList(new MetricsInstrumentation()); + return asList(new MetricsInstrumentation(), new AbstractCompositeMeterInstrumentation()); } } diff --git a/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerSingletons.java b/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerSingletons.java index 5c08575d0659..ad0334201688 100644 --- a/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerSingletons.java +++ b/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerSingletons.java @@ -8,8 +8,10 @@ import io.micrometer.core.instrument.MeterRegistry; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.micrometer.v1_5.OpenTelemetryInstrument; import io.opentelemetry.instrumentation.micrometer.v1_5.OpenTelemetryMeterRegistry; import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig; +import java.util.Iterator; public final class MicrometerSingletons { @@ -34,5 +36,47 @@ public static MeterRegistry meterRegistry() { return METER_REGISTRY; } + // called from code generate in AbstractCompositeMeterInstrumentation + public static Iterator wrapIterator(Iterator iterator) { + if (!iterator.hasNext()) { + return iterator; + } + + class FilteringIterator implements Iterator { + private final Iterator delegate; + private T next; + + FilteringIterator(Iterator delegate) { + this.delegate = delegate; + advance(); + } + + private void advance() { + while (delegate.hasNext()) { + T candidate = delegate.next(); + if (!(candidate instanceof OpenTelemetryInstrument)) { + next = candidate; + return; + } + } + next = null; + } + + @Override + public boolean hasNext() { + return next != null; + } + + @Override + public T next() { + T result = next; + advance(); + return result; + } + } + + return new FilteringIterator(iterator); + } + private MicrometerSingletons() {} } diff --git a/instrumentation/micrometer/micrometer-1.5/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/CompositeCounterTest.java b/instrumentation/micrometer/micrometer-1.5/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/CompositeCounterTest.java new file mode 100644 index 000000000000..aeae9d4dfbd3 --- /dev/null +++ b/instrumentation/micrometer/micrometer-1.5/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/CompositeCounterTest.java @@ -0,0 +1,75 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.micrometer.v1_5; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.Metrics; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +class CompositeCounterTest { + + static final String INSTRUMENTATION_NAME = "io.opentelemetry.micrometer-1.5"; + + @RegisterExtension + static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + @AfterEach + @BeforeEach + public void cleanup() { + Metrics.globalRegistry.forEachMeter(Metrics.globalRegistry::remove); + } + + @Test + void testCounter() { + // given + Counter counter = + Counter.builder("testCounter") + .description("This is a test counter") + .tags("tag", "value") + .baseUnit("items") + .register(Metrics.globalRegistry); + assertThat(counter.getClass().getName()).contains("CompositeCounter"); + + // when + counter.increment(); + + // then + // OpenTelemetryCounter returns NaN for count(), but NoopCounter returns 0 + // Here we verify that OpenTelemetryCounter is filtered out when count() is called and the + // result is produced form NoopCounter. If there were multiple meter registries, the result + // would be produced from an instrument that is not from our registry. We don't test with + // multiple registries because the behavior of count() depends on the order of elements in a + // map, so instead we test that our instrument is ignored and the result comes from a fallback + // to NoopCounter. + assertThat(counter.count()).isEqualTo(0); + + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, + "testCounter", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasDescription("This is a test counter") + .hasUnit("items") + .hasDoubleSumSatisfying( + sum -> + sum.isMonotonic() + .hasPointsSatisfying( + point -> + point + .hasValue(1) + .hasAttributes(attributeEntry("tag", "value")))))); + } +} diff --git a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryCounter.java b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryCounter.java index a21ab4b6a9f4..fb3d050911b8 100644 --- a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryCounter.java +++ b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryCounter.java @@ -18,7 +18,8 @@ import io.opentelemetry.api.metrics.Meter; import java.util.Collections; -final class OpenTelemetryCounter extends AbstractMeter implements Counter, RemovableMeter { +final class OpenTelemetryCounter extends AbstractMeter + implements Counter, RemovableMeter, OpenTelemetryInstrument { // TODO: use bound instruments when they're available private final DoubleCounter otelCounter; diff --git a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryDistributionSummary.java b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryDistributionSummary.java index 8d86a8ec1b85..c8f4ec713e40 100644 --- a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryDistributionSummary.java +++ b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryDistributionSummary.java @@ -27,7 +27,7 @@ import java.util.concurrent.atomic.LongAdder; final class OpenTelemetryDistributionSummary extends AbstractDistributionSummary - implements RemovableMeter { + implements RemovableMeter, OpenTelemetryInstrument { private final Measurements measurements; private final TimeWindowMax max; diff --git a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryFunctionCounter.java b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryFunctionCounter.java index 352009c3a5b3..a10e48d3612f 100644 --- a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryFunctionCounter.java +++ b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryFunctionCounter.java @@ -19,7 +19,7 @@ import java.util.function.ToDoubleFunction; final class OpenTelemetryFunctionCounter extends AbstractMeter - implements FunctionCounter, RemovableMeter { + implements FunctionCounter, RemovableMeter, OpenTelemetryInstrument { private final ObservableDoubleCounter observableCount; diff --git a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryFunctionTimer.java b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryFunctionTimer.java index fb238fb23a8e..1506c0946a13 100644 --- a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryFunctionTimer.java +++ b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryFunctionTimer.java @@ -20,7 +20,7 @@ import java.util.function.ToLongFunction; final class OpenTelemetryFunctionTimer extends AbstractMeter - implements FunctionTimer, RemovableMeter { + implements FunctionTimer, RemovableMeter, OpenTelemetryInstrument { private final TimeUnit baseTimeUnit; private final ObservableLongCounter observableCount; private final ObservableDoubleCounter observableTotalTime; diff --git a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryGauge.java b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryGauge.java index ce9efa803aca..8de8baf678bb 100644 --- a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryGauge.java +++ b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryGauge.java @@ -19,7 +19,8 @@ import java.util.function.ToDoubleFunction; import javax.annotation.Nullable; -final class OpenTelemetryGauge extends AbstractMeter implements Gauge, RemovableMeter { +final class OpenTelemetryGauge extends AbstractMeter + implements Gauge, RemovableMeter, OpenTelemetryInstrument { private final ObservableDoubleGauge observableGauge; diff --git a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryInstrument.java b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryInstrument.java new file mode 100644 index 000000000000..51314b3e84ee --- /dev/null +++ b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryInstrument.java @@ -0,0 +1,9 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.micrometer.v1_5; + +/** Marker interface for micrometer instruments that delegate to Open Telemetry instruments. */ +public interface OpenTelemetryInstrument {} diff --git a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryLongTaskTimer.java b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryLongTaskTimer.java index ed4d1e1dec16..3b0eb2134366 100644 --- a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryLongTaskTimer.java +++ b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryLongTaskTimer.java @@ -20,7 +20,8 @@ import java.util.Collections; import java.util.concurrent.TimeUnit; -final class OpenTelemetryLongTaskTimer extends DefaultLongTaskTimer implements RemovableMeter { +final class OpenTelemetryLongTaskTimer extends DefaultLongTaskTimer + implements RemovableMeter, OpenTelemetryInstrument { private final DistributionStatisticConfig distributionStatisticConfig; private final ObservableLongUpDownCounter observableActiveTasks; diff --git a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryMeter.java b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryMeter.java index 8644ef6155be..411e0e72b2f3 100644 --- a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryMeter.java +++ b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryMeter.java @@ -18,7 +18,8 @@ import java.util.Collections; import java.util.List; -final class OpenTelemetryMeter extends AbstractMeter implements Meter, RemovableMeter { +final class OpenTelemetryMeter extends AbstractMeter + implements Meter, RemovableMeter, OpenTelemetryInstrument { private final List observableInstruments; diff --git a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryTimer.java b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryTimer.java index 95310517e715..1038f3cacf37 100644 --- a/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryTimer.java +++ b/instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryTimer.java @@ -28,7 +28,8 @@ import java.util.concurrent.atomic.DoubleAdder; import java.util.concurrent.atomic.LongAdder; -final class OpenTelemetryTimer extends AbstractTimer implements RemovableMeter { +final class OpenTelemetryTimer extends AbstractTimer + implements RemovableMeter, OpenTelemetryInstrument { private final Measurements measurements; private final TimeWindowMax max; From 7a6f3173b45fe10a8587a2407639c086f92bc8d2 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Wed, 3 Dec 2025 19:14:48 +0200 Subject: [PATCH 2/2] fix indy test --- .../v1_5/MicrometerInstrumentationModule.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerInstrumentationModule.java b/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerInstrumentationModule.java index 6ef75f8c5c20..138bf7f5b315 100644 --- a/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerInstrumentationModule.java +++ b/instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerInstrumentationModule.java @@ -11,12 +11,16 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; +import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.ClassInjector; +import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.InjectionMode; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class MicrometerInstrumentationModule extends InstrumentationModule { +public class MicrometerInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public MicrometerInstrumentationModule() { super("micrometer", "micrometer-1.5"); @@ -38,4 +42,13 @@ public ElementMatcher.Junction classLoaderMatcher() { public List typeInstrumentations() { return asList(new MetricsInstrumentation(), new AbstractCompositeMeterInstrumentation()); } + + @Override + public void injectClasses(ClassInjector injector) { + // we use asm to call a method in MicrometerSingletons + injector + .proxyBuilder( + "io.opentelemetry.javaagent.instrumentation.micrometer.v1_5.MicrometerSingletons") + .inject(InjectionMode.CLASS_ONLY); + } }