From 18352ff913e57cc1abc3c31045a765e2a04174d8 Mon Sep 17 00:00:00 2001 From: Mateusz Rzeszutek Date: Mon, 16 May 2022 20:31:33 +0200 Subject: [PATCH] Fix a metrics API bridging issue (#6034) --- .../javaagent/build.gradle.kts | 2 +- .../ApplicationObservableDoubleCounter.java | 12 +- .../ApplicationObservableDoubleGauge.java | 12 +- ...licationObservableDoubleUpDownCounter.java | 12 +- .../ApplicationObservableLongCounter.java | 12 +- .../ApplicationObservableLongGauge.java | 12 +- ...pplicationObservableLongUpDownCounter.java | 12 +- .../v1_10/metrics/MeterTest.java | 241 ++++++++++++++++-- .../build.gradle.kts | 44 +++- 9 files changed, 328 insertions(+), 31 deletions(-) diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/build.gradle.kts b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/build.gradle.kts index 276f573b451e..de5df0b95397 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/build.gradle.kts +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/build.gradle.kts @@ -3,7 +3,7 @@ plugins { } dependencies { - compileOnly(project(":opentelemetry-api-shaded-for-instrumenting", configuration = "shadow")) + compileOnly(project(":opentelemetry-api-shaded-for-instrumenting", configuration = "v1_10")) implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent")) implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.4:javaagent")) } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleCounter.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleCounter.java index ad48bf5cc230..5e9df91ae422 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleCounter.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleCounter.java @@ -9,6 +9,16 @@ public final class ApplicationObservableDoubleCounter implements ObservableDoubleCounter { + private final io.opentelemetry.api.metrics.ObservableDoubleCounter agentCounter; + public ApplicationObservableDoubleCounter( - io.opentelemetry.api.metrics.ObservableDoubleCounter agentCounter) {} + io.opentelemetry.api.metrics.ObservableDoubleCounter agentCounter) { + this.agentCounter = agentCounter; + } + + // not adding @Override because this method was introduced in 1.12 + @SuppressWarnings("unused") + public void close() { + agentCounter.close(); + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleGauge.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleGauge.java index b654d0d9ab73..1aaf70e76e94 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleGauge.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleGauge.java @@ -9,6 +9,16 @@ public final class ApplicationObservableDoubleGauge implements ObservableDoubleGauge { + private final io.opentelemetry.api.metrics.ObservableDoubleGauge agentGauge; + public ApplicationObservableDoubleGauge( - io.opentelemetry.api.metrics.ObservableDoubleGauge agentGauge) {} + io.opentelemetry.api.metrics.ObservableDoubleGauge agentGauge) { + this.agentGauge = agentGauge; + } + + // not adding @Override because this method was introduced in 1.12 + @SuppressWarnings("unused") + public void close() { + agentGauge.close(); + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleUpDownCounter.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleUpDownCounter.java index 14afb94d45a3..7909a4d59d53 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleUpDownCounter.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableDoubleUpDownCounter.java @@ -10,6 +10,16 @@ public final class ApplicationObservableDoubleUpDownCounter implements ObservableDoubleUpDownCounter { + private final io.opentelemetry.api.metrics.ObservableDoubleUpDownCounter agentUpDownCounter; + public ApplicationObservableDoubleUpDownCounter( - io.opentelemetry.api.metrics.ObservableDoubleUpDownCounter agentUpDownCounter) {} + io.opentelemetry.api.metrics.ObservableDoubleUpDownCounter agentUpDownCounter) { + this.agentUpDownCounter = agentUpDownCounter; + } + + // not adding @Override because this method was introduced in 1.12 + @SuppressWarnings("unused") + public void close() { + agentUpDownCounter.close(); + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongCounter.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongCounter.java index a4a0e92afafd..f086e81a8eb1 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongCounter.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongCounter.java @@ -9,6 +9,16 @@ public final class ApplicationObservableLongCounter implements ObservableLongCounter { + private final io.opentelemetry.api.metrics.ObservableLongCounter agentCounter; + public ApplicationObservableLongCounter( - io.opentelemetry.api.metrics.ObservableLongCounter agentCounter) {} + io.opentelemetry.api.metrics.ObservableLongCounter agentCounter) { + this.agentCounter = agentCounter; + } + + // not adding @Override because this method was introduced in 1.12 + @SuppressWarnings("unused") + public void close() { + agentCounter.close(); + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongGauge.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongGauge.java index b3996e6c6d8f..b901ce8fbda0 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongGauge.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongGauge.java @@ -9,6 +9,16 @@ public final class ApplicationObservableLongGauge implements ObservableLongGauge { + private final io.opentelemetry.api.metrics.ObservableLongGauge agentGauge; + public ApplicationObservableLongGauge( - io.opentelemetry.api.metrics.ObservableLongGauge agentGauge) {} + io.opentelemetry.api.metrics.ObservableLongGauge agentGauge) { + this.agentGauge = agentGauge; + } + + // not adding @Override because this method was introduced in 1.12 + @SuppressWarnings("unused") + public void close() { + agentGauge.close(); + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongUpDownCounter.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongUpDownCounter.java index b65b5c8d97ee..e2be0640b8a1 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongUpDownCounter.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/ApplicationObservableLongUpDownCounter.java @@ -9,6 +9,16 @@ public final class ApplicationObservableLongUpDownCounter implements ObservableLongUpDownCounter { + private final io.opentelemetry.api.metrics.ObservableLongUpDownCounter agentUpDownCounter; + public ApplicationObservableLongUpDownCounter( - io.opentelemetry.api.metrics.ObservableLongUpDownCounter agentUpDownCounter) {} + io.opentelemetry.api.metrics.ObservableLongUpDownCounter agentUpDownCounter) { + this.agentUpDownCounter = agentUpDownCounter; + } + + // not adding @Override because this method was introduced in 1.12 + @SuppressWarnings("unused") + public void close() { + agentUpDownCounter.close(); + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/MeterTest.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/MeterTest.java index 7735d958875c..dee7f1ca696f 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/MeterTest.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/metrics/MeterTest.java @@ -17,8 +17,15 @@ import io.opentelemetry.api.metrics.LongHistogram; import io.opentelemetry.api.metrics.LongUpDownCounter; import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.ObservableDoubleCounter; +import io.opentelemetry.api.metrics.ObservableDoubleGauge; +import io.opentelemetry.api.metrics.ObservableDoubleUpDownCounter; +import io.opentelemetry.api.metrics.ObservableLongCounter; +import io.opentelemetry.api.metrics.ObservableLongGauge; +import io.opentelemetry.api.metrics.ObservableLongUpDownCounter; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import org.assertj.core.api.AbstractIterableAssert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; @@ -76,12 +83,14 @@ void longCounter() { } @Test - void longUpDownCounter() { - LongUpDownCounter instrument = - meter.upDownCounterBuilder("test").setDescription("d").setUnit("u").build(); - - instrument.add(5, Attributes.of(AttributeKey.stringKey("q"), "r")); - instrument.add(6, Attributes.of(AttributeKey.stringKey("q"), "r")); + void observableLongCounter() throws InterruptedException { + ObservableLongCounter observableCounter = + meter + .counterBuilder("test") + .setDescription("d") + .setUnit("u") + .buildWithCallback( + result -> result.record(11, Attributes.of(AttributeKey.stringKey("q"), "r"))); testing.waitAndAssertMetrics( instrumentationName, @@ -97,13 +106,22 @@ void longUpDownCounter() { instrumentationName, "1.2.3", /* schemaUrl= */ null)) .hasLongSumSatisfying( sum -> - sum.isNotMonotonic() + sum.isMonotonic() .hasPointsSatisfying( point -> point .hasValue(11) .hasAttributesSatisfying( equalTo(AttributeKey.stringKey("q"), "r")))))); + + observableCounter.close(); + + // sleep exporter interval + Thread.sleep(100); + testing.clearData(); + Thread.sleep(100); + + testing.waitAndAssertMetrics(instrumentationName, "test", AbstractIterableAssert::isEmpty); } @Test @@ -137,6 +155,122 @@ void doubleCounter() { equalTo(AttributeKey.stringKey("q"), "r")))))); } + @Test + void observableDoubleCounter() throws InterruptedException { + ObservableDoubleCounter observableCounter = + meter + .counterBuilder("test") + .ofDoubles() + .setDescription("d") + .setUnit("u") + .buildWithCallback( + result -> result.record(12.1, Attributes.of(AttributeKey.stringKey("q"), "r"))); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.create( + instrumentationName, "1.2.3", /* schemaUrl= */ null)) + .hasDoubleSumSatisfying( + sum -> + sum.isMonotonic() + .hasPointsSatisfying( + point -> + point + .hasValue(12.1) + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("q"), "r")))))); + + observableCounter.close(); + + // sleep exporter interval + Thread.sleep(100); + testing.clearData(); + Thread.sleep(100); + + testing.waitAndAssertMetrics(instrumentationName, "test", AbstractIterableAssert::isEmpty); + } + + @Test + void longUpDownCounter() { + LongUpDownCounter instrument = + meter.upDownCounterBuilder("test").setDescription("d").setUnit("u").build(); + + instrument.add(5, Attributes.of(AttributeKey.stringKey("q"), "r")); + instrument.add(6, Attributes.of(AttributeKey.stringKey("q"), "r")); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.create( + instrumentationName, "1.2.3", /* schemaUrl= */ null)) + .hasLongSumSatisfying( + sum -> + sum.isNotMonotonic() + .hasPointsSatisfying( + point -> + point + .hasValue(11) + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("q"), "r")))))); + } + + @Test + void observableLongUpDownCounter() throws InterruptedException { + ObservableLongUpDownCounter observableCounter = + meter + .upDownCounterBuilder("test") + .setDescription("d") + .setUnit("u") + .buildWithCallback( + result -> result.record(11, Attributes.of(AttributeKey.stringKey("q"), "r"))); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.create( + instrumentationName, "1.2.3", /* schemaUrl= */ null)) + .hasLongSumSatisfying( + sum -> + sum.isNotMonotonic() + .hasPointsSatisfying( + point -> + point + .hasValue(11) + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("q"), "r")))))); + + observableCounter.close(); + + // sleep exporter interval + Thread.sleep(100); + testing.clearData(); + Thread.sleep(100); + + testing.waitAndAssertMetrics(instrumentationName, "test", AbstractIterableAssert::isEmpty); + } + @Test void doubleUpDownCounter() { DoubleUpDownCounter instrument = @@ -168,6 +302,49 @@ void doubleUpDownCounter() { equalTo(AttributeKey.stringKey("q"), "r")))))); } + @Test + void observableDoubleUpDownCounter() throws InterruptedException { + ObservableDoubleUpDownCounter observableCounter = + meter + .upDownCounterBuilder("test") + .ofDoubles() + .setDescription("d") + .setUnit("u") + .buildWithCallback( + result -> result.record(12.1, Attributes.of(AttributeKey.stringKey("q"), "r"))); + + testing.waitAndAssertMetrics( + instrumentationName, + "test", + metrics -> + metrics.anySatisfy( + metric -> + assertThat(metric) + .hasDescription("d") + .hasUnit("u") + .hasInstrumentationScope( + InstrumentationScopeInfo.create( + instrumentationName, "1.2.3", /* schemaUrl= */ null)) + .hasDoubleSumSatisfying( + sum -> + sum.isNotMonotonic() + .hasPointsSatisfying( + point -> + point + .hasValue(12.1) + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("q"), "r")))))); + + observableCounter.close(); + + // sleep exporter interval + Thread.sleep(100); + testing.clearData(); + Thread.sleep(100); + + testing.waitAndAssertMetrics(instrumentationName, "test", AbstractIterableAssert::isEmpty); + } + @Test void longHistogram() { LongHistogram instrument = @@ -229,14 +406,15 @@ void doubleHistogram() { } @Test - void longGauge() { - meter - .gaugeBuilder("test") - .ofLongs() - .setDescription("d") - .setUnit("u") - .buildWithCallback( - result -> result.record(123, Attributes.of(AttributeKey.stringKey("q"), "r"))); + void longGauge() throws InterruptedException { + ObservableLongGauge observableGauge = + meter + .gaugeBuilder("test") + .ofLongs() + .setDescription("d") + .setUnit("u") + .buildWithCallback( + result -> result.record(123, Attributes.of(AttributeKey.stringKey("q"), "r"))); testing.waitAndAssertMetrics( instrumentationName, @@ -258,16 +436,26 @@ void longGauge() { .hasValue(123) .hasAttributesSatisfying( equalTo(AttributeKey.stringKey("q"), "r")))))); + + observableGauge.close(); + + // sleep exporter interval + Thread.sleep(100); + testing.clearData(); + Thread.sleep(100); + + testing.waitAndAssertMetrics(instrumentationName, "test", AbstractIterableAssert::isEmpty); } @Test - void doubleGauge() { - meter - .gaugeBuilder("test") - .setDescription("d") - .setUnit("u") - .buildWithCallback( - result -> result.record(1.23, Attributes.of(AttributeKey.stringKey("q"), "r"))); + void doubleGauge() throws InterruptedException { + ObservableDoubleGauge observableGauge = + meter + .gaugeBuilder("test") + .setDescription("d") + .setUnit("u") + .buildWithCallback( + result -> result.record(1.23, Attributes.of(AttributeKey.stringKey("q"), "r"))); testing.waitAndAssertMetrics( instrumentationName, @@ -289,5 +477,14 @@ void doubleGauge() { .hasValue(1.23) .hasAttributesSatisfying( equalTo(AttributeKey.stringKey("q"), "r")))))); + + observableGauge.close(); + + // sleep exporter interval + Thread.sleep(100); + testing.clearData(); + Thread.sleep(100); + + testing.waitAndAssertMetrics(instrumentationName, "test", AbstractIterableAssert::isEmpty); } } diff --git a/opentelemetry-api-shaded-for-instrumenting/build.gradle.kts b/opentelemetry-api-shaded-for-instrumenting/build.gradle.kts index c120eb03cea7..303b2a1e8b99 100644 --- a/opentelemetry-api-shaded-for-instrumenting/build.gradle.kts +++ b/opentelemetry-api-shaded-for-instrumenting/build.gradle.kts @@ -1,3 +1,5 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + plugins { id("com.github.johnrengelman.shadow") @@ -7,15 +9,53 @@ plugins { description = "opentelemetry-api shaded for internal javaagent usage" group = "io.opentelemetry.javaagent" +val latestDeps by configurations.creating { + isCanBeResolved = true + isCanBeConsumed = false +} +val v1_10Deps 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 { + isCanBeConsumed = true + isCanBeResolved = false +} + dependencies { - implementation("io.opentelemetry:opentelemetry-api") + latestDeps("io.opentelemetry:opentelemetry-api") + + listOf("opentelemetry-api", "opentelemetry-context").forEach { + v1_10Deps("io.opentelemetry:$it") { + version { + strictly("1.10.0") + } + } + } } // OpenTelemetry API shaded so that it can be used in instrumentation of OpenTelemetry API itself, // and then its usage can be unshaded after OpenTelemetry API is shaded // (see more explanation in opentelemetry-api-1.0.gradle) tasks { - shadowJar { + withType().configureEach { relocate("io.opentelemetry", "application.io.opentelemetry") } + + shadowJar { + configurations = listOf(latestDeps) + } + + val v1_10Shadow by registering(ShadowJar::class) { + configurations = listOf(v1_10Deps) + archiveClassifier.set("v1_10") + } + + artifacts { + add(v1_10.name, v1_10Shadow) + } }