Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added MetricReader customizer for AutoConfiguredOpenTelemetrySdkBuilder #6231

Merged
merged 7 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.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
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 AutoConfigurationCustomizer addMetricReaderCustomizer(
jack-berg marked this conversation as resolved.
Show resolved Hide resolved
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