From d6f16f72d5638afe58bbd55bb360a975f5454e36 Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Thu, 15 Feb 2024 17:58:10 +0200 Subject: [PATCH 1/5] Added MetricReader customizer for AutoConfiguredOpenTelemetrySdkBuilder --- ...emetry-sdk-extension-autoconfigure-spi.txt | 4 +- ...ntelemetry-sdk-extension-autoconfigure.txt | 4 +- .../spi/AutoConfigurationCustomizer.java | 14 ++++++ sdk-extensions/autoconfigure/build.gradle.kts | 2 + ...AutoConfiguredOpenTelemetrySdkBuilder.java | 24 +++++++++- .../MeterProviderConfiguration.java | 14 +++++- .../MetricExporterConfiguration.java | 17 ++++++- .../MeterProviderConfigurationTest.java | 1 + .../AutoConfiguredOpenTelemetrySdkTest.java | 21 +++++++++ .../ConfigurableMetricExporterTest.java | 14 ++++-- .../MeterProviderConfigurationTest.java | 3 ++ .../MetricExporterConfigurationTest.java | 47 ++++++++++++++++++- 12 files changed, 154 insertions(+), 11 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt index df26146497b..c464bbdd2e2 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure-spi.txt @@ -1,2 +1,4 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addMetricReaderCustomizer(java.util.function.BiFunction) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index df26146497b..5f9234e1957 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,4 @@ Comparing source compatibility of against -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addMetricReaderCustomizer(java.util.function.BiFunction) diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java index 03edca120bc..d64ec24f49d 100644 --- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/AutoConfigurationCustomizer.java @@ -11,6 +11,7 @@ import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricExporter; +import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; import io.opentelemetry.sdk.trace.SpanProcessor; @@ -150,12 +151,25 @@ default AutoConfigurationCustomizer addMeterProviderCustomizer( * *

Multiple calls will execute the customizers in order. */ + @SuppressWarnings("UnusedReturnValue") default AutoConfigurationCustomizer addMetricExporterCustomizer( BiFunction exporterCustomizer) { return this; } + /** + * Adds a {@link BiFunction} to invoke with the autoconfigured {@link MetricReader} to allow + * customization. The return value of the {@link BiFunction} will replace the passed-in argument. + * + *

Multiple calls will execute the customizers in order. + */ + @SuppressWarnings("UnusedReturnValue") + default AutoConfigurationCustomizer addMetricReaderCustomizer( + BiFunction readerCustomizer) { + return this; + } + /** * Adds a {@link BiFunction} to invoke the with the {@link SdkLoggerProviderBuilder} to allow * customization. The return value of the {@link BiFunction} will replace the passed-in argument. diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index 62fcd639c79..e2ba9fc8948 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -19,6 +19,7 @@ dependencies { testImplementation("com.google.guava:guava") testImplementation("edu.berkeley.cs.jqf:jqf-fuzz") + testImplementation("com.linecorp.armeria:armeria") } testing { @@ -53,6 +54,7 @@ testing { implementation(project(":exporters:logging-otlp")) implementation(project(":exporters:otlp:all")) implementation(project(":exporters:prometheus")) + implementation("io.prometheus:prometheus-metrics-exporter-httpserver") implementation(project(":exporters:zipkin")) implementation(project(":sdk:testing")) implementation(project(":sdk:trace-shaded-deps")) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 8e332c2a2b7..8f8434d0079 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -28,6 +28,7 @@ import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricExporter; +import io.opentelemetry.sdk.metrics.export.MetricReader; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; @@ -83,6 +84,8 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur meterProviderCustomizer = (a, unused) -> a; private BiFunction metricExporterCustomizer = (a, unused) -> a; + private BiFunction + metricReaderCustomizer = (a, unused) -> a; private BiFunction loggerProviderCustomizer = (a, unused) -> a; @@ -283,6 +286,20 @@ public AutoConfiguredOpenTelemetrySdkBuilder addMetricExporterCustomizer( return this; } + /** + * Adds a {@link BiFunction} to invoke with the autoconfigured {@link MetricReader} to allow + * customization. The return value of the {@link BiFunction} will replace the passed-in argument. + * + *

Multiple calls will execute the customizers in order. + */ + @Override + public AutoConfigurationCustomizer addMetricReaderCustomizer( + BiFunction readerCustomizer) { + requireNonNull(readerCustomizer, "readerCustomizer"); + this.metricReaderCustomizer = mergeCustomizer(this.metricReaderCustomizer, readerCustomizer); + return this; + } + /** * Adds a {@link BiFunction} to invoke the with the {@link SdkLoggerProviderBuilder} to allow * customization. The return value of the {@link BiFunction} will replace the passed-in argument. @@ -406,7 +423,12 @@ public AutoConfiguredOpenTelemetrySdk build() { SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder(); meterProviderBuilder.setResource(resource); MeterProviderConfiguration.configureMeterProvider( - meterProviderBuilder, config, spiHelper, metricExporterCustomizer, closeables); + meterProviderBuilder, + config, + spiHelper, + metricReaderCustomizer, + metricExporterCustomizer, + closeables); meterProviderBuilder = meterProviderCustomizer.apply(meterProviderBuilder, config); SdkMeterProvider meterProvider = meterProviderBuilder.build(); closeables.add(meterProvider); diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java index 525dc54974a..3689161b906 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java @@ -29,6 +29,8 @@ static void configureMeterProvider( SdkMeterProviderBuilder meterProviderBuilder, ConfigProperties config, SpiHelper spiHelper, + BiFunction + metricReaderCustomizer, BiFunction metricExporterCustomizer, List closeables) { @@ -56,7 +58,8 @@ static void configureMeterProvider( throw new ConfigurationException("otel.experimental.metrics.cardinality.limit must be >= 1"); } - configureMetricReaders(config, spiHelper, metricExporterCustomizer, closeables) + configureMetricReaders( + config, spiHelper, metricReaderCustomizer, metricExporterCustomizer, closeables) .forEach( reader -> SdkMeterProviderUtil.registerMetricReaderWithCardinalitySelector( @@ -66,6 +69,8 @@ static void configureMeterProvider( static List configureMetricReaders( ConfigProperties config, SpiHelper spiHelper, + BiFunction + metricReaderCustomizer, BiFunction metricExporterCustomizer, List closeables) { @@ -85,7 +90,12 @@ static List configureMetricReaders( .map( exporterName -> MetricExporterConfiguration.configureReader( - exporterName, config, spiHelper, metricExporterCustomizer, closeables)) + exporterName, + config, + spiHelper, + metricReaderCustomizer, + metricExporterCustomizer, + closeables)) .collect(Collectors.toList()); } diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java index 2aa968a82bb..3b4a1da1658 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java @@ -42,6 +42,8 @@ static MetricReader configureReader( String name, ConfigProperties config, SpiHelper spiHelper, + BiFunction + metricReaderCustomizer, BiFunction metricExporterCustomizer, List closeables) { @@ -56,7 +58,14 @@ static MetricReader configureReader( MetricReader metricReader = configureMetricReader(name, spiMetricReadersManager); if (metricReader != null) { closeables.add(metricReader); - return metricReader; + + // Customize metric reader + MetricReader customizedMetricReader = metricReaderCustomizer.apply(metricReader, config); + if (customizedMetricReader != metricReader) { + closeables.add(customizedMetricReader); + } + + return customizedMetricReader; } // No exporter or reader with the name throw new ConfigurationException("Unrecognized value for otel.metrics.exporter: " + name); @@ -74,7 +83,11 @@ static MetricReader configureReader( .setInterval(config.getDuration("otel.metric.export.interval", DEFAULT_EXPORT_INTERVAL)) .build(); closeables.add(reader); - return reader; + MetricReader customizedMetricReader = metricReaderCustomizer.apply(reader, config); + if (customizedMetricReader != reader) { + closeables.add(customizedMetricReader); + } + return customizedMetricReader; } // Visible for testing diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java index c501d28e3cb..900ba509d71 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java @@ -54,6 +54,7 @@ private static ObjectAssert assertExemplarFilter(Map a, + (a, b) -> a, new ArrayList<>()); return assertThat(builder) .extracting("exemplarFilter", as(InstanceOfAssertFactories.type(ExemplarFilter.class))); diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index 6bf5c74ccc5..eec315a2360 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -5,12 +5,16 @@ package io.opentelemetry.sdk.autoconfigure; +import static java.util.Collections.singletonMap; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import com.linecorp.armeria.client.WebClient; import io.github.netmikey.logunit.api.LogCapturer; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.events.GlobalEventEmitterProvider; +import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; import io.opentelemetry.sdk.OpenTelemetrySdk; import java.lang.reflect.Field; import org.junit.jupiter.api.BeforeEach; @@ -31,6 +35,23 @@ void setUp() { GlobalEventEmitterProvider.resetForTest(); } + @SuppressWarnings("ResultOfMethodCallIgnored") + @Test + void build_addMetricReaderCustomizerPrometheus() { + AutoConfiguredOpenTelemetrySdkBuilder builder = AutoConfiguredOpenTelemetrySdk.builder(); + + builder.addPropertiesSupplier(() -> singletonMap("otel.metrics.exporter", "prometheus")); + builder.addMetricReaderCustomizer( + (reader, config) -> { + assertThat(reader).isInstanceOf(PrometheusHttpServer.class); + return PrometheusHttpServer.builder().setPort(1234).build(); + }); + builder.build(); + + WebClient client = WebClient.builder("http://localhost:1234").build(); + assertThatCode(() -> client.get("/metrics")).doesNotThrowAnyException(); + } + @Test void initializeAndGet() { try (OpenTelemetrySdk sdk = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk()) { diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java index 18797f0058b..bc32ebc84a4 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableMetricExporterTest.java @@ -87,7 +87,7 @@ void configureMetricReaders_multipleWithNone() { assertThatThrownBy( () -> MeterProviderConfiguration.configureMetricReaders( - config, spiHelper, (a, unused) -> a, closeables)) + config, spiHelper, (a, unused) -> a, (a, unused) -> a, closeables)) .isInstanceOf(ConfigurationException.class) .hasMessageContaining("otel.metrics.exporter contains none along with other exporters"); cleanup.addCloseables(closeables); @@ -102,7 +102,11 @@ void configureMetricReaders_defaultExporter() { List metricReaders = MeterProviderConfiguration.configureMetricReaders( - config, spiHelper, (metricExporter, unused) -> metricExporter, closeables); + config, + spiHelper, + (a, unused) -> a, + (metricExporter, unused) -> metricExporter, + closeables); cleanup.addCloseables(closeables); assertThat(metricReaders) @@ -125,7 +129,11 @@ void configureMetricReaders_multipleExporters() { List metricReaders = MeterProviderConfiguration.configureMetricReaders( - config, spiHelper, (metricExporter, unused) -> metricExporter, closeables); + config, + spiHelper, + (a, unused) -> a, + (metricExporter, unused) -> metricExporter, + closeables); cleanup.addCloseables(closeables); assertThat(metricReaders).hasSize(2).hasOnlyElementsOfType(PeriodicMetricReader.class); diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java index c5df15c73bb..b2062c20dd5 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfigurationTest.java @@ -50,6 +50,7 @@ void configureMeterProvider_InvalidCardinalityLimit() { "0")), spiHelper, (a, b) -> a, + (a, b) -> a, closeables); }) .isInstanceOf(ConfigurationException.class) @@ -69,6 +70,7 @@ void configureMeterProvider_ConfiguresCardinalityLimit() { Collections.singletonMap("otel.metrics.exporter", "logging")), spiHelper, (a, b) -> a, + (a, b) -> a, closeables); cleanup.addCloseables(closeables); assertCardinalityLimit(builder, 2000); @@ -85,6 +87,7 @@ void configureMeterProvider_ConfiguresCardinalityLimit() { "100")), spiHelper, (a, b) -> a, + (a, b) -> a, closeables); cleanup.addCloseables(closeables); assertCardinalityLimit(builder, 100); diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java index 6db4b23f82e..7c45c8226cd 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.autoconfigure; +import static org.assertj.core.api.Assertions.as; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -21,11 +22,16 @@ import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.metrics.export.MetricExporter; import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; +import io.prometheus.metrics.exporter.httpserver.HTTPServer; import java.io.Closeable; +import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.function.BiFunction; import java.util.stream.Stream; +import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.params.ParameterizedTest; @@ -49,13 +55,52 @@ void configureReader_PrometheusOnClasspath() { MetricReader reader = MetricExporterConfiguration.configureReader( - "prometheus", CONFIG_PROPERTIES, spiHelper, (a, b) -> a, closeables); + "prometheus", CONFIG_PROPERTIES, spiHelper, (a, b) -> a, (a, b) -> a, closeables); cleanup.addCloseables(closeables); assertThat(reader).isInstanceOf(PrometheusHttpServer.class); assertThat(closeables).hasSize(1); } + @Test + void configureReader_customizeReader() { + List closeables = new ArrayList<>(); + + BiFunction readerCustomizer = + (existingReader, config) -> PrometheusHttpServer.builder().setPort(7137).build(); + MetricReader reader = + MetricExporterConfiguration.configureReader( + "prometheus", CONFIG_PROPERTIES, spiHelper, readerCustomizer, (a, b) -> a, closeables); + cleanup.addCloseables(closeables); + + assertThat(reader).isInstanceOf(PrometheusHttpServer.class); + assertThat(closeables).hasSize(2); + PrometheusHttpServer prometheusHttpServer = (PrometheusHttpServer) reader; + assertThat(prometheusHttpServer) + .extracting("httpServer", as(InstanceOfAssertFactories.type(HTTPServer.class))) + .satisfies(httpServer -> assertThat(httpServer.getPort()).isEqualTo(7137)); + + List closeablesPart2 = new ArrayList<>(); + + readerCustomizer = + (existingReader, config) -> + PeriodicMetricReader.builder(OtlpGrpcMetricExporter.builder().build()) + .setInterval(Duration.ofSeconds(123)) + .build(); + + reader = + MetricExporterConfiguration.configureReader( + "otlp", CONFIG_PROPERTIES, spiHelper, readerCustomizer, (a, b) -> a, closeablesPart2); + cleanup.addCloseables(closeablesPart2); + + assertThat(reader).isInstanceOf(PeriodicMetricReader.class); + assertThat(closeablesPart2).hasSize(3); + PeriodicMetricReader periodicMetricReader = (PeriodicMetricReader) reader; + assertThat(periodicMetricReader) + .extracting("intervalNanos") + .isEqualTo(Duration.ofSeconds(123).toNanos()); + } + @ParameterizedTest @MethodSource("knownExporters") void configureExporter_KnownSpiExportersOnClasspath( From f45dc37dd4b26bf3b7bb89884f144d847c466985 Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Mon, 19 Feb 2024 16:44:09 +0200 Subject: [PATCH 2/5] PR fixes --- .../AutoConfiguredOpenTelemetrySdkTest.java | 12 ++++++---- .../sdk/autoconfigure/FreePortFinder.java | 22 ++++++++++++++++++ .../MetricExporterConfigurationTest.java | 23 +++++++++++-------- 3 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FreePortFinder.java diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index eec315a2360..f1f880441e6 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -39,17 +39,19 @@ void setUp() { @Test void build_addMetricReaderCustomizerPrometheus() { AutoConfiguredOpenTelemetrySdkBuilder builder = AutoConfiguredOpenTelemetrySdk.builder(); - builder.addPropertiesSupplier(() -> singletonMap("otel.metrics.exporter", "prometheus")); + + int port = FreePortFinder.getFreePort(); builder.addMetricReaderCustomizer( (reader, config) -> { assertThat(reader).isInstanceOf(PrometheusHttpServer.class); - return PrometheusHttpServer.builder().setPort(1234).build(); + return PrometheusHttpServer.builder().setPort(port).build(); }); - builder.build(); - WebClient client = WebClient.builder("http://localhost:1234").build(); - assertThatCode(() -> client.get("/metrics")).doesNotThrowAnyException(); + try (OpenTelemetrySdk ignored = builder.build().getOpenTelemetrySdk()) { + WebClient client = WebClient.builder("http://localhost:" + port).build(); + assertThatCode(() -> client.get("/metrics")).doesNotThrowAnyException(); + } } @Test diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FreePortFinder.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FreePortFinder.java new file mode 100644 index 00000000000..92c2b7640c7 --- /dev/null +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/FreePortFinder.java @@ -0,0 +1,22 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure; + +import java.io.IOException; +import java.net.ServerSocket; + +final class FreePortFinder { + + static int getFreePort() { + try (ServerSocket socket = new ServerSocket(0)) { + return socket.getLocalPort(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private FreePortFinder() {} +} diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java index 7c45c8226cd..c8bd0937e63 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfigurationTest.java @@ -63,11 +63,12 @@ void configureReader_PrometheusOnClasspath() { } @Test - void configureReader_customizeReader() { + void configureReader_customizeReader_prometheus() { List closeables = new ArrayList<>(); + int port = FreePortFinder.getFreePort(); BiFunction readerCustomizer = - (existingReader, config) -> PrometheusHttpServer.builder().setPort(7137).build(); + (existingReader, config) -> PrometheusHttpServer.builder().setPort(port).build(); MetricReader reader = MetricExporterConfiguration.configureReader( "prometheus", CONFIG_PROPERTIES, spiHelper, readerCustomizer, (a, b) -> a, closeables); @@ -78,23 +79,25 @@ void configureReader_customizeReader() { PrometheusHttpServer prometheusHttpServer = (PrometheusHttpServer) reader; assertThat(prometheusHttpServer) .extracting("httpServer", as(InstanceOfAssertFactories.type(HTTPServer.class))) - .satisfies(httpServer -> assertThat(httpServer.getPort()).isEqualTo(7137)); + .satisfies(httpServer -> assertThat(httpServer.getPort()).isEqualTo(port)); + } - List closeablesPart2 = new ArrayList<>(); + @Test + void configureReader_customizeReader_otlp() { + List closeables = new ArrayList<>(); - readerCustomizer = + BiFunction readerCustomizer = (existingReader, config) -> PeriodicMetricReader.builder(OtlpGrpcMetricExporter.builder().build()) .setInterval(Duration.ofSeconds(123)) .build(); - - reader = + MetricReader reader = MetricExporterConfiguration.configureReader( - "otlp", CONFIG_PROPERTIES, spiHelper, readerCustomizer, (a, b) -> a, closeablesPart2); - cleanup.addCloseables(closeablesPart2); + "otlp", CONFIG_PROPERTIES, spiHelper, readerCustomizer, (a, b) -> a, closeables); + cleanup.addCloseables(closeables); assertThat(reader).isInstanceOf(PeriodicMetricReader.class); - assertThat(closeablesPart2).hasSize(3); + assertThat(closeables).hasSize(3); PeriodicMetricReader periodicMetricReader = (PeriodicMetricReader) reader; assertThat(periodicMetricReader) .extracting("intervalNanos") From 51b8f1abdcda9cbe81d1174297acf0ee040df608 Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Wed, 21 Feb 2024 15:43:27 +0200 Subject: [PATCH 3/5] PR Fixes #2 --- sdk-extensions/autoconfigure/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index e2ba9fc8948..04fbde232fc 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -19,7 +19,6 @@ dependencies { testImplementation("com.google.guava:guava") testImplementation("edu.berkeley.cs.jqf:jqf-fuzz") - testImplementation("com.linecorp.armeria:armeria") } testing { From 8074807f4e7b2489327a5e0641d4d09d9a5fab6a Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Wed, 28 Feb 2024 22:43:29 +0200 Subject: [PATCH 4/5] PR fixes --- .../autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index 8f8434d0079..ac9d39a2a71 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -293,7 +293,7 @@ public AutoConfiguredOpenTelemetrySdkBuilder addMetricExporterCustomizer( *

Multiple calls will execute the customizers in order. */ @Override - public AutoConfigurationCustomizer addMetricReaderCustomizer( + public AutoConfiguredOpenTelemetrySdkBuilder addMetricReaderCustomizer( BiFunction readerCustomizer) { requireNonNull(readerCustomizer, "readerCustomizer"); this.metricReaderCustomizer = mergeCustomizer(this.metricReaderCustomizer, readerCustomizer); From c2c14879fff6c8820fed5050fb07a1d60af57ab3 Mon Sep 17 00:00:00 2001 From: Asaf Mesika Date: Thu, 29 Feb 2024 16:43:27 +0200 Subject: [PATCH 5/5] After merging from main --- .../opentelemetry-sdk-extension-autoconfigure.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 5f9234e1957..04f3e512be6 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,4 +1,4 @@ Comparing source compatibility of against *** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 - +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addMetricReaderCustomizer(java.util.function.BiFunction) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder addMetricReaderCustomizer(java.util.function.BiFunction)