Skip to content

Commit

Permalink
Added MetricReader customizer for AutoConfiguredOpenTelemetrySdkBuild…
Browse files Browse the repository at this point in the history
…er (#6231)
  • Loading branch information
asafm committed Feb 29, 2024
1 parent 6afb816 commit 62a4810
Show file tree
Hide file tree
Showing 13 changed files with 180 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Comparing source compatibility of against
No changes.
*** 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<? super io.opentelemetry.sdk.metrics.export.MetricReader,io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties,? extends io.opentelemetry.sdk.metrics.export.MetricReader>)
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
Comparing source compatibility of against
No changes.
*** 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.AutoConfiguredOpenTelemetrySdkBuilder addMetricReaderCustomizer(java.util.function.BiFunction<? super io.opentelemetry.sdk.metrics.export.MetricReader,io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties,? extends io.opentelemetry.sdk.metrics.export.MetricReader>)
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -150,12 +151,25 @@ default AutoConfigurationCustomizer addMeterProviderCustomizer(
*
* <p>Multiple calls will execute the customizers in order.
*/
@SuppressWarnings("UnusedReturnValue")
default AutoConfigurationCustomizer addMetricExporterCustomizer(
BiFunction<? super MetricExporter, ConfigProperties, ? extends MetricExporter>
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.
*
* <p>Multiple calls will execute the customizers in order.
*/
@SuppressWarnings("UnusedReturnValue")
default AutoConfigurationCustomizer addMetricReaderCustomizer(
BiFunction<? super MetricReader, ConfigProperties, ? extends MetricReader> 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.
Expand Down
1 change: 1 addition & 0 deletions sdk-extensions/autoconfigure/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,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"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -83,6 +84,8 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur
meterProviderCustomizer = (a, unused) -> a;
private BiFunction<? super MetricExporter, ConfigProperties, ? extends MetricExporter>
metricExporterCustomizer = (a, unused) -> a;
private BiFunction<? super MetricReader, ConfigProperties, ? extends MetricReader>
metricReaderCustomizer = (a, unused) -> a;

private BiFunction<SdkLoggerProviderBuilder, ConfigProperties, SdkLoggerProviderBuilder>
loggerProviderCustomizer = (a, unused) -> a;
Expand Down Expand Up @@ -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.
*
* <p>Multiple calls will execute the customizers in order.
*/
@Override
public AutoConfiguredOpenTelemetrySdkBuilder addMetricReaderCustomizer(
BiFunction<? super MetricReader, ConfigProperties, ? extends MetricReader> 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.
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ static void configureMeterProvider(
SdkMeterProviderBuilder meterProviderBuilder,
ConfigProperties config,
SpiHelper spiHelper,
BiFunction<? super MetricReader, ConfigProperties, ? extends MetricReader>
metricReaderCustomizer,
BiFunction<? super MetricExporter, ConfigProperties, ? extends MetricExporter>
metricExporterCustomizer,
List<Closeable> closeables) {
Expand Down Expand Up @@ -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(
Expand All @@ -66,6 +69,8 @@ static void configureMeterProvider(
static List<MetricReader> configureMetricReaders(
ConfigProperties config,
SpiHelper spiHelper,
BiFunction<? super MetricReader, ConfigProperties, ? extends MetricReader>
metricReaderCustomizer,
BiFunction<? super MetricExporter, ConfigProperties, ? extends MetricExporter>
metricExporterCustomizer,
List<Closeable> closeables) {
Expand All @@ -85,7 +90,12 @@ static List<MetricReader> configureMetricReaders(
.map(
exporterName ->
MetricExporterConfiguration.configureReader(
exporterName, config, spiHelper, metricExporterCustomizer, closeables))
exporterName,
config,
spiHelper,
metricReaderCustomizer,
metricExporterCustomizer,
closeables))
.collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ static MetricReader configureReader(
String name,
ConfigProperties config,
SpiHelper spiHelper,
BiFunction<? super MetricReader, ConfigProperties, ? extends MetricReader>
metricReaderCustomizer,
BiFunction<? super MetricExporter, ConfigProperties, ? extends MetricExporter>
metricExporterCustomizer,
List<Closeable> closeables) {
Expand All @@ -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);
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ private static ObjectAssert<ExemplarFilter> assertExemplarFilter(Map<String, Str
DefaultConfigProperties.createFromMap(configWithDefault),
SpiHelper.create(MeterProviderConfigurationTest.class.getClassLoader()),
(a, b) -> a,
(a, b) -> a,
new ArrayList<>());
return assertThat(builder)
.extracting("exemplarFilter", as(InstanceOfAssertFactories.type(ExemplarFilter.class)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,6 +35,25 @@ void setUp() {
GlobalEventEmitterProvider.resetForTest();
}

@SuppressWarnings("ResultOfMethodCallIgnored")
@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(port).build();
});

try (OpenTelemetrySdk ignored = builder.build().getOpenTelemetrySdk()) {
WebClient client = WebClient.builder("http://localhost:" + port).build();
assertThatCode(() -> client.get("/metrics")).doesNotThrowAnyException();
}
}

@Test
void initializeAndGet() {
try (OpenTelemetrySdk sdk = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -102,7 +102,11 @@ void configureMetricReaders_defaultExporter() {

List<MetricReader> metricReaders =
MeterProviderConfiguration.configureMetricReaders(
config, spiHelper, (metricExporter, unused) -> metricExporter, closeables);
config,
spiHelper,
(a, unused) -> a,
(metricExporter, unused) -> metricExporter,
closeables);
cleanup.addCloseables(closeables);

assertThat(metricReaders)
Expand All @@ -125,7 +129,11 @@ void configureMetricReaders_multipleExporters() {

List<MetricReader> 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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ void configureMeterProvider_InvalidCardinalityLimit() {
"0")),
spiHelper,
(a, b) -> a,
(a, b) -> a,
closeables);
})
.isInstanceOf(ConfigurationException.class)
Expand All @@ -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);
Expand All @@ -85,6 +87,7 @@ void configureMeterProvider_ConfiguresCardinalityLimit() {
"100")),
spiHelper,
(a, b) -> a,
(a, b) -> a,
closeables);
cleanup.addCloseables(closeables);
assertCardinalityLimit(builder, 100);
Expand Down
Loading

0 comments on commit 62a4810

Please sign in to comment.