From 6b2f018b601ebd92c41879f8c1e8941a88ef0c25 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 8 Dec 2023 09:59:36 +0200 Subject: [PATCH] Bridge opentelemetry api 1.32 (#10026) Co-authored-by: Mateusz Rzeszutek --- .../v1_27/ApplicationOpenTelemetry127.java | 29 +- .../javaagent/build.gradle.kts | 9 + .../ApplicationDoubleHistogramBuilder131.java | 3 +- .../ApplicationLongHistogramBuilder131.java | 3 +- .../v1_31/metrics/ApplicationMeter131.java | 4 +- .../javaagent/build.gradle.kts | 31 ++ .../v1_32/incubator/metrics/MeterTest.java | 468 ++++++++++++++++++ ...OpenTelemetryApiInstrumentationModule.java | 42 ++ .../v1_32/OpenTelemetryInstrumentation.java | 40 ++ ...etryApiIncubatorInstrumentationModule.java | 40 ++ ...OpenTelemetryIncubatorInstrumentation.java | 40 ++ ...ionDoubleHistogramBuilder132Incubator.java | 44 ++ ...ationLongHistogramBuilder132Incubator.java | 38 ++ .../metrics/ApplicationMeter132Incubator.java | 24 + .../ApplicationMeterFactory132Incubator.java | 18 + .../ApplicationDoubleHistogramBuilder132.java | 10 +- .../ApplicationLongHistogramBuilder132.java | 4 +- .../v1_32/metrics/ApplicationMeter132.java | 24 + .../metrics/ApplicationMeterFactory132.java | 18 + .../v1_32/metrics/MeterTest.java | 116 +++++ .../build.gradle.kts | 25 + settings.gradle.kts | 1 + 22 files changed, 1019 insertions(+), 12 deletions(-) create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/build.gradle.kts create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/MeterTest.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryApiInstrumentationModule.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryInstrumentation.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryIncubatorInstrumentation.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationDoubleHistogramBuilder132Incubator.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationLongHistogramBuilder132Incubator.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationMeter132Incubator.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationMeterFactory132Incubator.java rename instrumentation/opentelemetry-api/{opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31 => opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32}/metrics/ApplicationDoubleHistogramBuilder132.java (79%) rename instrumentation/opentelemetry-api/{opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31 => opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32}/metrics/ApplicationLongHistogramBuilder132.java (92%) create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationMeter132.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationMeterFactory132.java create mode 100644 instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/MeterTest.java diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/ApplicationOpenTelemetry127.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/ApplicationOpenTelemetry127.java index 35ab4715541b..bb9663677b3b 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/ApplicationOpenTelemetry127.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/ApplicationOpenTelemetry127.java @@ -63,18 +63,39 @@ public ContextPropagators getPropagators() { } private static ApplicationMeterFactory getMeterFactory() { - try { + // this class is defined in opentelemetry-api-1.32 + ApplicationMeterFactory meterFactory = + getMeterFactory( + "io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.incubator.metrics.ApplicationMeterFactory132Incubator"); + if (meterFactory == null) { + // this class is defined in opentelemetry-api-1.32 + meterFactory = + getMeterFactory( + "io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.metrics.ApplicationMeterFactory132"); + } + if (meterFactory == null) { // this class is defined in opentelemetry-api-1.31 - Class clazz = - Class.forName( + meterFactory = + getMeterFactory( "io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_31.metrics.ApplicationMeterFactory131"); + } + if (meterFactory == null) { + meterFactory = new ApplicationMeterFactory115(); + } + + return meterFactory; + } + + private static ApplicationMeterFactory getMeterFactory(String className) { + try { + Class clazz = Class.forName(className); return (ApplicationMeterFactory) clazz.getConstructor().newInstance(); } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException exception) { - return new ApplicationMeterFactory115(); + return null; } } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/build.gradle.kts b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/build.gradle.kts index 149aa266e99b..6968e8bb3206 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/build.gradle.kts +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/build.gradle.kts @@ -14,3 +14,12 @@ dependencies { testImplementation("io.opentelemetry:opentelemetry-extension-incubator") } + +configurations.configureEach { + if (name == "testRuntimeClasspath" || name == "testCompileClasspath") { + resolutionStrategy { + force("io.opentelemetry:opentelemetry-api:1.31.0") + force("io.opentelemetry:opentelemetry-extension-incubator:1.31.0-alpha") + } + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationDoubleHistogramBuilder131.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationDoubleHistogramBuilder131.java index c26e92381f60..485ac714929b 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationDoubleHistogramBuilder131.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationDoubleHistogramBuilder131.java @@ -9,9 +9,10 @@ import application.io.opentelemetry.api.metrics.LongHistogramBuilder; import application.io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.Bridging; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationDoubleHistogramBuilder; import java.util.List; -final class ApplicationDoubleHistogramBuilder131 extends ApplicationDoubleHistogramBuilder132 +final class ApplicationDoubleHistogramBuilder131 extends ApplicationDoubleHistogramBuilder implements ExtendedDoubleHistogramBuilder { private final io.opentelemetry.api.metrics.DoubleHistogramBuilder agentBuilder; diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationLongHistogramBuilder131.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationLongHistogramBuilder131.java index 9b86334a88cc..d46fc99d08c1 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationLongHistogramBuilder131.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationLongHistogramBuilder131.java @@ -8,9 +8,10 @@ import application.io.opentelemetry.api.common.AttributeKey; import application.io.opentelemetry.extension.incubator.metrics.ExtendedLongHistogramBuilder; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.Bridging; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationLongHistogramBuilder; import java.util.List; -final class ApplicationLongHistogramBuilder131 extends ApplicationLongHistogramBuilder132 +final class ApplicationLongHistogramBuilder131 extends ApplicationLongHistogramBuilder implements ExtendedLongHistogramBuilder { private final io.opentelemetry.api.metrics.LongHistogramBuilder agentBuilder; diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationMeter131.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationMeter131.java index 66d159215c48..688568523fdc 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationMeter131.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationMeter131.java @@ -11,11 +11,11 @@ import application.io.opentelemetry.api.metrics.LongUpDownCounterBuilder; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_15.metrics.ApplicationMeter115; -class ApplicationMeter131 extends ApplicationMeter115 { +public class ApplicationMeter131 extends ApplicationMeter115 { private final io.opentelemetry.api.metrics.Meter agentMeter; - ApplicationMeter131(io.opentelemetry.api.metrics.Meter agentMeter) { + protected ApplicationMeter131(io.opentelemetry.api.metrics.Meter agentMeter) { super(agentMeter); this.agentMeter = agentMeter; } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/build.gradle.kts b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/build.gradle.kts new file mode 100644 index 000000000000..fc59c934fdc9 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/build.gradle.kts @@ -0,0 +1,31 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +dependencies { + compileOnly(project(":opentelemetry-api-shaded-for-instrumenting", configuration = "v1_32")) + compileOnly("io.opentelemetry:opentelemetry-extension-incubator") + + implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent")) + implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.4:javaagent")) + implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.10:javaagent")) + implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.15:javaagent")) + implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.27:javaagent")) + implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.31:javaagent")) +} + +testing { + suites { + val incubatorTest by registering(JvmTestSuite::class) { + dependencies { + implementation("io.opentelemetry:opentelemetry-extension-incubator") + } + } + } +} + +tasks { + check { + dependsOn(testing.suites) + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/MeterTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/MeterTest.java new file mode 100644 index 000000000000..2c8446897eb2 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/incubatorTest/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/MeterTest.java @@ -0,0 +1,468 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.incubator.metrics; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.DoubleCounterBuilder; +import io.opentelemetry.api.metrics.DoubleGaugeBuilder; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.api.metrics.DoubleHistogramBuilder; +import io.opentelemetry.api.metrics.DoubleUpDownCounter; +import io.opentelemetry.api.metrics.DoubleUpDownCounterBuilder; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.LongCounterBuilder; +import io.opentelemetry.api.metrics.LongGaugeBuilder; +import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.api.metrics.LongHistogramBuilder; +import io.opentelemetry.api.metrics.LongUpDownCounter; +import io.opentelemetry.api.metrics.LongUpDownCounterBuilder; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.ObservableDoubleGauge; +import io.opentelemetry.api.metrics.ObservableLongGauge; +import io.opentelemetry.extension.incubator.metrics.DoubleGauge; +import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleCounterBuilder; +import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleGaugeBuilder; +import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder; +import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleUpDownCounterBuilder; +import io.opentelemetry.extension.incubator.metrics.ExtendedLongCounterBuilder; +import io.opentelemetry.extension.incubator.metrics.ExtendedLongGaugeBuilder; +import io.opentelemetry.extension.incubator.metrics.ExtendedLongHistogramBuilder; +import io.opentelemetry.extension.incubator.metrics.ExtendedLongUpDownCounterBuilder; +import io.opentelemetry.extension.incubator.metrics.LongGauge; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions; +import org.assertj.core.api.AbstractIterableAssert; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.extension.RegisterExtension; + +class MeterTest { + + @RegisterExtension + static final AgentInstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private String instrumentationName; + private Meter meter; + + @BeforeEach + void setupMeter(TestInfo test) { + instrumentationName = "test-" + test.getDisplayName(); + meter = + testing + .getOpenTelemetry() + .getMeterProvider() + .meterBuilder(instrumentationName) + .setInstrumentationVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build(); + } + + @Test + void longCounter() { + LongCounterBuilder builder = meter.counterBuilder("test").setDescription("d").setUnit("u"); + assertThat(builder).isInstanceOf(ExtendedLongCounterBuilder.class); + ExtendedLongCounterBuilder extendedBuilder = (ExtendedLongCounterBuilder) builder; + extendedBuilder.setAttributesAdvice(singletonList(stringKey("test"))); + + LongCounter instrument = builder.build(); + + instrument.add(5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + instrument.add(6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasLongSumSatisfying( + sum -> + sum.isMonotonic() + .hasPointsSatisfying( + point -> + point + .hasValue(11) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + } + + @Test + void doubleCounter() { + DoubleCounterBuilder builder = + meter.counterBuilder("test").ofDoubles().setDescription("d").setUnit("u"); + assertThat(builder).isInstanceOf(ExtendedDoubleCounterBuilder.class); + ExtendedDoubleCounterBuilder extendedBuilder = (ExtendedDoubleCounterBuilder) builder; + extendedBuilder.setAttributesAdvice(singletonList(stringKey("test"))); + + DoubleCounter instrument = builder.build(); + + instrument.add(5.5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + instrument.add(6.6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasDoubleSumSatisfying( + sum -> + sum.isMonotonic() + .hasPointsSatisfying( + point -> + point + .hasValue(12.1) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + } + + @Test + void longUpDownCounter() { + LongUpDownCounterBuilder builder = + meter.upDownCounterBuilder("test").setDescription("d").setUnit("u"); + assertThat(builder).isInstanceOf(ExtendedLongUpDownCounterBuilder.class); + ExtendedLongUpDownCounterBuilder extendedBuilder = (ExtendedLongUpDownCounterBuilder) builder; + extendedBuilder.setAttributesAdvice(singletonList(stringKey("test"))); + + LongUpDownCounter instrument = builder.build(); + + instrument.add(5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + instrument.add(6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasLongSumSatisfying( + sum -> + sum.isNotMonotonic() + .hasPointsSatisfying( + point -> + point + .hasValue(11) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + } + + @Test + void doubleUpDownCounter() { + DoubleUpDownCounterBuilder builder = + meter.upDownCounterBuilder("test").ofDoubles().setDescription("d").setUnit("u"); + assertThat(builder).isInstanceOf(ExtendedDoubleUpDownCounterBuilder.class); + ExtendedDoubleUpDownCounterBuilder extendedBuilder = + (ExtendedDoubleUpDownCounterBuilder) builder; + extendedBuilder.setAttributesAdvice(singletonList(stringKey("test"))); + + DoubleUpDownCounter instrument = builder.build(); + + instrument.add(5.5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + instrument.add(6.6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasDoubleSumSatisfying( + sum -> + sum.isNotMonotonic() + .hasPointsSatisfying( + point -> + point + .hasValue(12.1) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + } + + @Test + void longHistogram() { + LongHistogramBuilder builder = + meter.histogramBuilder("test").ofLongs().setDescription("d").setUnit("u"); + builder.setExplicitBucketBoundariesAdvice(singletonList(10L)); + assertThat(builder).isInstanceOf(ExtendedLongHistogramBuilder.class); + ExtendedLongHistogramBuilder extendedBuilder = (ExtendedLongHistogramBuilder) builder; + extendedBuilder.setAttributesAdvice(singletonList(stringKey("test"))); + + LongHistogram instrument = builder.build(); + + instrument.record(5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + instrument.record(6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point + .hasSum(11.0) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + } + + @Test + void doubleHistogram() { + DoubleHistogramBuilder builder = + meter.histogramBuilder("test").setDescription("d").setUnit("u"); + builder.setExplicitBucketBoundariesAdvice(singletonList(10.0)); + assertThat(builder).isInstanceOf(ExtendedDoubleHistogramBuilder.class); + ExtendedDoubleHistogramBuilder extendedBuilder = (ExtendedDoubleHistogramBuilder) builder; + extendedBuilder.setAttributesAdvice(singletonList(stringKey("test"))); + + DoubleHistogram instrument = builder.build(); + + instrument.record(5.5, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + instrument.record(6.6, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point + .hasSum(12.1) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + } + + @Test + void longGauge() throws InterruptedException { + LongGaugeBuilder builder = + meter.gaugeBuilder("test").ofLongs().setDescription("d").setUnit("u"); + assertThat(builder).isInstanceOf(ExtendedLongGaugeBuilder.class); + ExtendedLongGaugeBuilder extendedBuilder = (ExtendedLongGaugeBuilder) builder; + extendedBuilder.setAttributesAdvice(singletonList(stringKey("test"))); + + ObservableLongGauge observableGauge = + builder.buildWithCallback( + result -> + result.record(123, Attributes.of(stringKey("test"), "test", stringKey("q"), "r"))); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasLongGaugeSatisfying( + gauge -> + gauge.hasPointsSatisfying( + point -> + point + .hasValue(123) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + + observableGauge.close(); + + // sleep exporter interval + Thread.sleep(100); + testing.clearData(); + Thread.sleep(100); + + testing.waitAndAssertMetrics(instrumentationName, "test", AbstractIterableAssert::isEmpty); + } + + @Test + void syncLongGauge() throws InterruptedException { + LongGaugeBuilder builder = + meter.gaugeBuilder("test").ofLongs().setDescription("d").setUnit("u"); + assertThat(builder).isInstanceOf(ExtendedLongGaugeBuilder.class); + ExtendedLongGaugeBuilder extendedBuilder = (ExtendedLongGaugeBuilder) builder; + extendedBuilder.setAttributesAdvice(singletonList(stringKey("test"))); + + LongGauge longGauge = extendedBuilder.build(); + longGauge.set(321); + longGauge.set(123, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasLongGaugeSatisfying( + gauge -> + gauge.hasPointsSatisfying( + point -> point.hasValue(321).hasAttributes(Attributes.empty()), + point -> + point + .hasValue(123) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + + // sleep exporter interval + Thread.sleep(100); + testing.clearData(); + Thread.sleep(100); + + testing.waitAndAssertMetrics(instrumentationName, "test", AbstractIterableAssert::isEmpty); + } + + @Test + void doubleGauge() throws InterruptedException { + DoubleGaugeBuilder builder = meter.gaugeBuilder("test").setDescription("d").setUnit("u"); + assertThat(builder).isInstanceOf(ExtendedDoubleGaugeBuilder.class); + ExtendedDoubleGaugeBuilder extendedBuilder = (ExtendedDoubleGaugeBuilder) builder; + extendedBuilder.setAttributesAdvice(singletonList(stringKey("test"))); + + ObservableDoubleGauge observableGauge = + builder.buildWithCallback( + result -> + result.record(1.23, Attributes.of(stringKey("test"), "test", stringKey("q"), "r"))); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasDoubleGaugeSatisfying( + gauge -> + gauge.hasPointsSatisfying( + point -> + point + .hasValue(1.23) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + + observableGauge.close(); + + // sleep exporter interval + Thread.sleep(100); + testing.clearData(); + Thread.sleep(100); + + testing.waitAndAssertMetrics(instrumentationName, "test", AbstractIterableAssert::isEmpty); + } + + @Test + void syncDoubleGauge() throws InterruptedException { + DoubleGaugeBuilder builder = meter.gaugeBuilder("test").setDescription("d").setUnit("u"); + assertThat(builder).isInstanceOf(ExtendedDoubleGaugeBuilder.class); + ExtendedDoubleGaugeBuilder extendedBuilder = (ExtendedDoubleGaugeBuilder) builder; + extendedBuilder.setAttributesAdvice(singletonList(stringKey("test"))); + + DoubleGauge doubleGauge = extendedBuilder.build(); + doubleGauge.set(3.21); + doubleGauge.set(1.23, Attributes.of(stringKey("test"), "test", stringKey("q"), "r")); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasDoubleGaugeSatisfying( + gauge -> + gauge.hasPointsSatisfying( + point -> point.hasValue(3.21).hasAttributes(Attributes.empty()), + point -> + point + .hasValue(1.23) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + + // sleep exporter interval + Thread.sleep(100); + testing.clearData(); + Thread.sleep(100); + + testing.waitAndAssertMetrics(instrumentationName, "test", AbstractIterableAssert::isEmpty); + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryApiInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryApiInstrumentationModule.java new file mode 100644 index 000000000000..893718fc8e6f --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryApiInstrumentationModule.java @@ -0,0 +1,42 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32; + +import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; +import static java.util.Collections.singletonList; +import static net.bytebuddy.matcher.ElementMatchers.not; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import java.util.List; +import net.bytebuddy.matcher.ElementMatcher; + +@AutoService(InstrumentationModule.class) +public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule { + public OpenTelemetryApiInstrumentationModule() { + super("opentelemetry-api", "opentelemetry-api-1.32"); + } + + @Override + public ElementMatcher.Junction classLoaderMatcher() { + // skip instrumentation when opentelemetry-extension-incubator is present, instrumentation is + // handled by OpenTelemetryApiIncubatorInstrumentationModule + return not( + hasClassesNamed( + "application.io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder")); + } + + @Override + public boolean isIndyModule() { + return false; + } + + @Override + public List typeInstrumentations() { + return singletonList(new OpenTelemetryInstrumentation()); + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryInstrumentation.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryInstrumentation.java new file mode 100644 index 000000000000..147c18b51b33 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryInstrumentation.java @@ -0,0 +1,40 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.none; + +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.metrics.ApplicationMeterFactory132; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +public class OpenTelemetryInstrumentation implements TypeInstrumentation { + + @Override + public ElementMatcher typeMatcher() { + return named("application.io.opentelemetry.api.GlobalOpenTelemetry"); + } + + @Override + public void transform(TypeTransformer transformer) { + transformer.applyAdviceToMethod( + none(), OpenTelemetryInstrumentation.class.getName() + "$InitAdvice"); + } + + @SuppressWarnings({"ReturnValueIgnored", "unused"}) + public static class InitAdvice { + @Advice.OnMethodEnter + public static void init() { + // the sole purpose of this advice is to ensure that ApplicationMeterFactory132 is recognized + // as helper class and injected into class loader + ApplicationMeterFactory132.class.getName(); + } + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java new file mode 100644 index 000000000000..dc20c2596ea6 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java @@ -0,0 +1,40 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.incubator; + +import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; +import static java.util.Collections.singletonList; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import java.util.List; +import net.bytebuddy.matcher.ElementMatcher; + +@AutoService(InstrumentationModule.class) +public class OpenTelemetryApiIncubatorInstrumentationModule extends InstrumentationModule { + public OpenTelemetryApiIncubatorInstrumentationModule() { + super("opentelemetry-api", "opentelemetry-api-1.32", "opentelemetry-api-incubator-1.32"); + } + + @Override + public ElementMatcher.Junction classLoaderMatcher() { + // skip instrumentation when opentelemetry-extension-incubator is not present, instrumentation + // is handled by OpenTelemetryApiInstrumentationModule + return hasClassesNamed( + "application.io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder"); + } + + @Override + public boolean isIndyModule() { + return false; + } + + @Override + public List typeInstrumentations() { + return singletonList(new OpenTelemetryIncubatorInstrumentation()); + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryIncubatorInstrumentation.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryIncubatorInstrumentation.java new file mode 100644 index 000000000000..76c1469c3a0d --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryIncubatorInstrumentation.java @@ -0,0 +1,40 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.incubator; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.none; + +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.incubator.metrics.ApplicationMeterFactory132Incubator; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +public class OpenTelemetryIncubatorInstrumentation implements TypeInstrumentation { + + @Override + public ElementMatcher typeMatcher() { + return named("application.io.opentelemetry.api.GlobalOpenTelemetry"); + } + + @Override + public void transform(TypeTransformer transformer) { + transformer.applyAdviceToMethod( + none(), OpenTelemetryIncubatorInstrumentation.class.getName() + "$InitAdvice"); + } + + @SuppressWarnings({"ReturnValueIgnored", "unused"}) + public static class InitAdvice { + @Advice.OnMethodEnter + public static void init() { + // the sole purpose of this advice is to ensure that ApplicationMeterFactory132Incubator + // is recognized as helper class and injected into class loader + ApplicationMeterFactory132Incubator.class.getName(); + } + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationDoubleHistogramBuilder132Incubator.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationDoubleHistogramBuilder132Incubator.java new file mode 100644 index 000000000000..c4d6ee6df52f --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationDoubleHistogramBuilder132Incubator.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.incubator.metrics; + +import application.io.opentelemetry.api.common.AttributeKey; +import application.io.opentelemetry.api.metrics.LongHistogramBuilder; +import application.io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.Bridging; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationDoubleHistogramBuilder; +import java.util.List; + +class ApplicationDoubleHistogramBuilder132Incubator extends ApplicationDoubleHistogramBuilder + implements ExtendedDoubleHistogramBuilder { + + private final io.opentelemetry.api.metrics.DoubleHistogramBuilder agentBuilder; + + ApplicationDoubleHistogramBuilder132Incubator( + io.opentelemetry.api.metrics.DoubleHistogramBuilder agentBuilder) { + super(agentBuilder); + this.agentBuilder = agentBuilder; + } + + @Override + public LongHistogramBuilder ofLongs() { + return new ApplicationLongHistogramBuilder132Incubator(agentBuilder.ofLongs()); + } + + @Override + public ExtendedDoubleHistogramBuilder setExplicitBucketBoundariesAdvice( + List bucketBoundaries) { + agentBuilder.setExplicitBucketBoundariesAdvice(bucketBoundaries); + return this; + } + + @Override + public ExtendedDoubleHistogramBuilder setAttributesAdvice(List> attributes) { + ((io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder) agentBuilder) + .setAttributesAdvice(Bridging.toAgent(attributes)); + return this; + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationLongHistogramBuilder132Incubator.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationLongHistogramBuilder132Incubator.java new file mode 100644 index 000000000000..4f6882cf6670 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationLongHistogramBuilder132Incubator.java @@ -0,0 +1,38 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.incubator.metrics; + +import application.io.opentelemetry.api.common.AttributeKey; +import application.io.opentelemetry.extension.incubator.metrics.ExtendedLongHistogramBuilder; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.Bridging; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationLongHistogramBuilder; +import java.util.List; + +class ApplicationLongHistogramBuilder132Incubator extends ApplicationLongHistogramBuilder + implements ExtendedLongHistogramBuilder { + + private final io.opentelemetry.api.metrics.LongHistogramBuilder agentBuilder; + + ApplicationLongHistogramBuilder132Incubator( + io.opentelemetry.api.metrics.LongHistogramBuilder agentBuilder) { + super(agentBuilder); + this.agentBuilder = agentBuilder; + } + + @Override + public ExtendedLongHistogramBuilder setExplicitBucketBoundariesAdvice( + List bucketBoundaries) { + agentBuilder.setExplicitBucketBoundariesAdvice(bucketBoundaries); + return this; + } + + @Override + public ExtendedLongHistogramBuilder setAttributesAdvice(List> attributes) { + ((io.opentelemetry.extension.incubator.metrics.ExtendedLongHistogramBuilder) agentBuilder) + .setAttributesAdvice(Bridging.toAgent(attributes)); + return this; + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationMeter132Incubator.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationMeter132Incubator.java new file mode 100644 index 000000000000..5af68b1815f4 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationMeter132Incubator.java @@ -0,0 +1,24 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.incubator.metrics; + +import application.io.opentelemetry.api.metrics.DoubleHistogramBuilder; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_31.metrics.ApplicationMeter131; + +class ApplicationMeter132Incubator extends ApplicationMeter131 { + + private final io.opentelemetry.api.metrics.Meter agentMeter; + + ApplicationMeter132Incubator(io.opentelemetry.api.metrics.Meter agentMeter) { + super(agentMeter); + this.agentMeter = agentMeter; + } + + @Override + public DoubleHistogramBuilder histogramBuilder(String name) { + return new ApplicationDoubleHistogramBuilder132Incubator(agentMeter.histogramBuilder(name)); + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationMeterFactory132Incubator.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationMeterFactory132Incubator.java new file mode 100644 index 000000000000..75ac0773c7a4 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/metrics/ApplicationMeterFactory132Incubator.java @@ -0,0 +1,18 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.incubator.metrics; + +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationMeter; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationMeterFactory; + +// this class is used from opentelemetry-api-1.27 via reflection +public final class ApplicationMeterFactory132Incubator implements ApplicationMeterFactory { + @Override + public ApplicationMeter newMeter(Meter agentMeter) { + return new ApplicationMeter132Incubator(agentMeter); + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationDoubleHistogramBuilder132.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationDoubleHistogramBuilder132.java similarity index 79% rename from instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationDoubleHistogramBuilder132.java rename to instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationDoubleHistogramBuilder132.java index 58a1e4c6e3c8..8b116a7b01fb 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationDoubleHistogramBuilder132.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationDoubleHistogramBuilder132.java @@ -3,9 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_31.metrics; +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.metrics; import application.io.opentelemetry.api.metrics.DoubleHistogramBuilder; +import application.io.opentelemetry.api.metrics.LongHistogramBuilder; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationDoubleHistogramBuilder; import java.util.List; @@ -19,7 +20,12 @@ class ApplicationDoubleHistogramBuilder132 extends ApplicationDoubleHistogramBui this.agentBuilder = agentBuilder; } - // return type is different from what 1.31 uses + @Override + public LongHistogramBuilder ofLongs() { + return new ApplicationLongHistogramBuilder132(agentBuilder.ofLongs()); + } + + @Override public DoubleHistogramBuilder setExplicitBucketBoundariesAdvice(List bucketBoundaries) { agentBuilder.setExplicitBucketBoundariesAdvice(bucketBoundaries); return this; diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationLongHistogramBuilder132.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationLongHistogramBuilder132.java similarity index 92% rename from instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationLongHistogramBuilder132.java rename to instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationLongHistogramBuilder132.java index ebeb9f4a72b7..fa494e250ef9 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/metrics/ApplicationLongHistogramBuilder132.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationLongHistogramBuilder132.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_31.metrics; +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.metrics; import application.io.opentelemetry.api.metrics.LongHistogramBuilder; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationLongHistogramBuilder; @@ -19,7 +19,7 @@ class ApplicationLongHistogramBuilder132 extends ApplicationLongHistogramBuilder this.agentBuilder = agentBuilder; } - // return type is different from what 1.31 uses + @Override public LongHistogramBuilder setExplicitBucketBoundariesAdvice(List bucketBoundaries) { agentBuilder.setExplicitBucketBoundariesAdvice(bucketBoundaries); return this; diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationMeter132.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationMeter132.java new file mode 100644 index 000000000000..ec880d3959f9 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationMeter132.java @@ -0,0 +1,24 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.metrics; + +import application.io.opentelemetry.api.metrics.DoubleHistogramBuilder; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_15.metrics.ApplicationMeter115; + +class ApplicationMeter132 extends ApplicationMeter115 { + + private final io.opentelemetry.api.metrics.Meter agentMeter; + + ApplicationMeter132(io.opentelemetry.api.metrics.Meter agentMeter) { + super(agentMeter); + this.agentMeter = agentMeter; + } + + @Override + public DoubleHistogramBuilder histogramBuilder(String name) { + return new ApplicationDoubleHistogramBuilder132(agentMeter.histogramBuilder(name)); + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationMeterFactory132.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationMeterFactory132.java new file mode 100644 index 000000000000..4adde3791bba --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/ApplicationMeterFactory132.java @@ -0,0 +1,18 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.metrics; + +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationMeter; +import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_10.metrics.ApplicationMeterFactory; + +// this class is used from opentelemetry-api-1.27 via reflection +public final class ApplicationMeterFactory132 implements ApplicationMeterFactory { + @Override + public ApplicationMeter newMeter(Meter agentMeter) { + return new ApplicationMeter132(agentMeter); + } +} diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/MeterTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/MeterTest.java new file mode 100644 index 000000000000..982e47d4e651 --- /dev/null +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/metrics/MeterTest.java @@ -0,0 +1,116 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_32.metrics; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static java.util.Collections.singletonList; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.api.metrics.DoubleHistogramBuilder; +import io.opentelemetry.api.metrics.LongHistogram; +import io.opentelemetry.api.metrics.LongHistogramBuilder; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.extension.RegisterExtension; + +class MeterTest { + + @RegisterExtension + static final AgentInstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private String instrumentationName; + private Meter meter; + + @BeforeEach + void setupMeter(TestInfo test) { + instrumentationName = "test-" + test.getDisplayName(); + meter = + testing + .getOpenTelemetry() + .getMeterProvider() + .meterBuilder(instrumentationName) + .setInstrumentationVersion("1.2.3") + .setSchemaUrl("http://schema.org") + .build(); + } + + @Test + void longHistogram() { + LongHistogramBuilder builder = + meter.histogramBuilder("test").ofLongs().setDescription("d").setUnit("u"); + builder.setExplicitBucketBoundariesAdvice(singletonList(10L)); + + LongHistogram instrument = builder.build(); + + instrument.record(5, Attributes.of(stringKey("test"), "test")); + instrument.record(6, Attributes.of(stringKey("test"), "test")); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point + .hasSum(11.0) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + } + + @Test + void doubleHistogram() { + DoubleHistogramBuilder builder = + meter.histogramBuilder("test").setDescription("d").setUnit("u"); + builder.setExplicitBucketBoundariesAdvice(singletonList(10.0)); + + DoubleHistogram instrument = builder.build(); + + instrument.record(5.5, Attributes.of(stringKey("test"), "test")); + instrument.record(6.6, Attributes.of(stringKey("test"), "test")); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + OpenTelemetryAssertions.assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.builder(instrumentationName) + .setVersion("1.2.3") + .build()) + .hasHistogramSatisfying( + histogram -> + histogram.hasPointsSatisfying( + point -> + point + .hasSum(12.1) + .hasBucketBoundaries(10.0) + .hasAttributesSatisfying( + equalTo(stringKey("test"), "test")))))); + } +} diff --git a/opentelemetry-api-shaded-for-instrumenting/build.gradle.kts b/opentelemetry-api-shaded-for-instrumenting/build.gradle.kts index b1d2785296af..60cd936f3a39 100644 --- a/opentelemetry-api-shaded-for-instrumenting/build.gradle.kts +++ b/opentelemetry-api-shaded-for-instrumenting/build.gradle.kts @@ -38,6 +38,12 @@ val v1_31Deps by configurations.creating { exclude("io.opentelemetry", "opentelemetry-bom") exclude("io.opentelemetry", "opentelemetry-bom-alpha") } +val v1_32Deps by configurations.creating { + isCanBeResolved = true + isCanBeConsumed = false + // exclude the bom added by dependencyManagement + exclude("io.opentelemetry", "opentelemetry-bom") +} // configuration for publishing the shadowed artifact val v1_10 by configurations.creating { @@ -56,6 +62,10 @@ val v1_31 by configurations.creating { isCanBeConsumed = true isCanBeResolved = false } +val v1_32 by configurations.creating { + isCanBeConsumed = true + isCanBeResolved = false +} dependencies { latestDeps("io.opentelemetry:opentelemetry-api") @@ -81,6 +91,11 @@ dependencies { strictly("1.31.0") } } + v1_32Deps("io.opentelemetry:$it") { + version { + strictly("1.32.0") + } + } } listOf("opentelemetry-extension-incubator").forEach { @@ -89,6 +104,11 @@ dependencies { strictly("1.31.0-alpha") } } + v1_32Deps("io.opentelemetry:$it") { + version { + strictly("1.32.0-alpha") + } + } } } @@ -120,11 +140,16 @@ tasks { configurations = listOf(v1_31Deps) archiveClassifier.set("v1_31") } + val v1_32Shadow by registering(ShadowJar::class) { + configurations = listOf(v1_32Deps) + archiveClassifier.set("v1_32") + } artifacts { add(v1_10.name, v1_10Shadow) add(v1_15.name, v1_15Shadow) add(v1_27.name, v1_27Shadow) add(v1_31.name, v1_31Shadow) + add(v1_32.name, v1_32Shadow) } } diff --git a/settings.gradle.kts b/settings.gradle.kts index efaa6f403001..9e4e25511ed7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -402,6 +402,7 @@ include(":instrumentation:opentelemetry-api:opentelemetry-api-1.10:javaagent") include(":instrumentation:opentelemetry-api:opentelemetry-api-1.15:javaagent") include(":instrumentation:opentelemetry-api:opentelemetry-api-1.27:javaagent") include(":instrumentation:opentelemetry-api:opentelemetry-api-1.31:javaagent") +include(":instrumentation:opentelemetry-api:opentelemetry-api-1.32:javaagent") include(":instrumentation:opentelemetry-extension-annotations-1.0:javaagent") include(":instrumentation:opentelemetry-extension-kotlin-1.0:javaagent") include(":instrumentation:opentelemetry-instrumentation-annotations-1.16:javaagent")