Skip to content

Commit

Permalink
add ComponentLoader to support more auto configuration scenarios, e.g…
Browse files Browse the repository at this point in the history
…. spring boot
  • Loading branch information
zeitlinger committed Feb 9, 2024
1 parent e9e1fee commit 1c89890
Show file tree
Hide file tree
Showing 29 changed files with 257 additions and 148 deletions.
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
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 setComponentLoader(io.opentelemetry.sdk.autoconfigure.ComponentLoader)
+++* NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.ComponentLoader (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++* NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.Iterable<T> load(java.lang.Class<T>)
GENERIC TEMPLATES: +++ T:java.lang.Object
+++ NEW ANNOTATION: java.lang.FunctionalInterface
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* #getPropagator(ConfigProperties)} will be enabled and available as part of {@link
* OpenTelemetry#getPropagators()}.
*/
public interface ConfigurablePropagatorProvider {
public interface ConfigurablePropagatorProvider extends ConfigurableProvider {
/**
* Returns a {@link TextMapPropagator} that can be registered to OpenTelemetry by providing the
* property value specified by {@link #getName()}.
Expand All @@ -27,5 +27,6 @@ public interface ConfigurablePropagatorProvider {
* property to enable it. If the name is the same as any other defined propagator name, it is
* undefined which will be used.
*/
@Override
String getName();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.autoconfigure.spi;

/**
* A named configurable provider.
*
* <p>It can be used to generically determine if a provider should be replaced by another provider
* with the same name.
*/
public interface ConfigurableProvider {
/** Returns the name of this provider. */
String getName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package io.opentelemetry.sdk.autoconfigure.spi.internal;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import io.opentelemetry.sdk.metrics.export.MetricReader;
Expand All @@ -24,7 +25,7 @@
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public interface ConfigurableMetricReaderProvider {
public interface ConfigurableMetricReaderProvider extends ConfigurableProvider {

/**
* Returns a {@link MetricReader} that can be registered to OpenTelemetry by providing the
Expand All @@ -40,5 +41,6 @@ public interface ConfigurableMetricReaderProvider {
* name, the resulting behavior is undefined and it is explicitly unspecified which reader /
* exporter will actually be used.
*/
@Override
String getName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package io.opentelemetry.sdk.autoconfigure.spi.logs;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;

/**
Expand All @@ -16,7 +17,7 @@
*
* @since 1.19.0
*/
public interface ConfigurableLogRecordExporterProvider {
public interface ConfigurableLogRecordExporterProvider extends ConfigurableProvider {

/**
* Returns a {@link LogRecordExporter} that can be registered to OpenTelemetry by providing the
Expand All @@ -30,5 +31,6 @@ public interface ConfigurableLogRecordExporterProvider {
* the name does conflict with another exporter name, the resulting behavior is undefined and it
* is explicitly unspecified which exporter will actually be used.
*/
@Override
String getName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package io.opentelemetry.sdk.autoconfigure.spi.metrics;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ConfigurableMetricReaderProvider;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import io.opentelemetry.sdk.metrics.export.MetricReader;
Expand All @@ -22,7 +23,7 @@
*
* @since 1.15.0
*/
public interface ConfigurableMetricExporterProvider {
public interface ConfigurableMetricExporterProvider extends ConfigurableProvider {

/**
* Returns a {@link MetricExporter} that can be registered to OpenTelemetry by providing the
Expand All @@ -38,5 +39,6 @@ public interface ConfigurableMetricExporterProvider {
* name, the resulting behavior is undefined and it is explicitly unspecified which exporter /
* reader will actually be used.
*/
@Override
String getName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package io.opentelemetry.sdk.autoconfigure.spi.traces;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
import io.opentelemetry.sdk.trace.samplers.Sampler;

/**
Expand All @@ -14,7 +15,7 @@
* returned by {@link #getName()}, the sampler returned by {@link #createSampler(ConfigProperties)}
* will be enabled and added to the SDK.
*/
public interface ConfigurableSamplerProvider {
public interface ConfigurableSamplerProvider extends ConfigurableProvider {

/**
* Returns a {@link Sampler} that can be registered to OpenTelemetry by providing the property
Expand All @@ -28,5 +29,6 @@ public interface ConfigurableSamplerProvider {
* the name does conflict with another exporter name, the resulting behavior is undefined and it
* is explicitly unspecified which exporter will actually be used.
*/
@Override
String getName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package io.opentelemetry.sdk.autoconfigure.spi.traces;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
import io.opentelemetry.sdk.trace.export.SpanExporter;

/**
Expand All @@ -14,7 +15,7 @@
* is returned by {@link #getName()}, the exporter returned by {@link
* #createExporter(ConfigProperties)} will be enabled and added to the SDK.
*/
public interface ConfigurableSpanExporterProvider {
public interface ConfigurableSpanExporterProvider extends ConfigurableProvider {

/**
* Returns a {@link SpanExporter} that can be registered to OpenTelemetry by providing the
Expand All @@ -28,5 +29,6 @@ public interface ConfigurableSpanExporterProvider {
* the name does conflict with another exporter name, the resulting behavior is undefined and it
* is explicitly unspecified which exporter will actually be used.
*/
@Override
String getName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,12 @@ public AutoConfiguredOpenTelemetrySdkBuilder setServiceClassLoader(
return this;
}

public AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader(ComponentLoader componentLoader) {
requireNonNull(componentLoader, "componentLoader");
this.spiHelper = SpiHelper.create(componentLoader);
return this;
}

/**
* Returns a new {@link AutoConfiguredOpenTelemetrySdk} holding components auto-configured using
* the settings of this {@link AutoConfiguredOpenTelemetrySdkBuilder}.
Expand Down Expand Up @@ -403,41 +409,53 @@ public AutoConfiguredOpenTelemetrySdk build() {
boolean sdkEnabled = !config.getBoolean("otel.sdk.disabled", false);

if (sdkEnabled) {
SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder();
meterProviderBuilder.setResource(resource);
MeterProviderConfiguration.configureMeterProvider(
meterProviderBuilder, config, spiHelper, metricExporterCustomizer, closeables);
meterProviderBuilder = meterProviderCustomizer.apply(meterProviderBuilder, config);
SdkMeterProvider meterProvider = meterProviderBuilder.build();
SdkMeterProvider meterProvider =
spiHelper.loadOptional(SdkMeterProvider.class).orElse(null);
if (meterProvider == null) {
SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder();
meterProviderBuilder.setResource(resource);
MeterProviderConfiguration.configureMeterProvider(
meterProviderBuilder, config, spiHelper, metricExporterCustomizer, closeables);
meterProviderBuilder = meterProviderCustomizer.apply(meterProviderBuilder, config);
meterProvider = meterProviderBuilder.build();
}
closeables.add(meterProvider);

SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder();
tracerProviderBuilder.setResource(resource);
TracerProviderConfiguration.configureTracerProvider(
tracerProviderBuilder,
config,
spiHelper,
meterProvider,
spanExporterCustomizer,
spanProcessorCustomizer,
samplerCustomizer,
closeables);
tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config);
SdkTracerProvider tracerProvider = tracerProviderBuilder.build();
SdkTracerProvider tracerProvider =
spiHelper.loadOptional(SdkTracerProvider.class).orElse(null);
if (tracerProvider == null) {
SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder();
tracerProviderBuilder.setResource(resource);
TracerProviderConfiguration.configureTracerProvider(
tracerProviderBuilder,
config,
spiHelper,
meterProvider,
spanExporterCustomizer,
spanProcessorCustomizer,
samplerCustomizer,
closeables);
tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config);
tracerProvider = tracerProviderBuilder.build();
}
closeables.add(tracerProvider);

SdkLoggerProviderBuilder loggerProviderBuilder = SdkLoggerProvider.builder();
loggerProviderBuilder.setResource(resource);
LoggerProviderConfiguration.configureLoggerProvider(
loggerProviderBuilder,
config,
spiHelper,
meterProvider,
logRecordExporterCustomizer,
logRecordProcessorCustomizer,
closeables);
loggerProviderBuilder = loggerProviderCustomizer.apply(loggerProviderBuilder, config);
SdkLoggerProvider loggerProvider = loggerProviderBuilder.build();
SdkLoggerProvider loggerProvider =
spiHelper.loadOptional(SdkLoggerProvider.class).orElse(null);
if (loggerProvider == null) {
SdkLoggerProviderBuilder loggerProviderBuilder = SdkLoggerProvider.builder();
loggerProviderBuilder.setResource(resource);
LoggerProviderConfiguration.configureLoggerProvider(
loggerProviderBuilder,
config,
spiHelper,
meterProvider,
logRecordExporterCustomizer,
logRecordProcessorCustomizer,
closeables);
loggerProviderBuilder = loggerProviderCustomizer.apply(loggerProviderBuilder, config);
loggerProvider = loggerProviderBuilder.build();
}
closeables.add(loggerProvider);

ContextPropagators propagators =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.autoconfigure;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
import io.opentelemetry.sdk.autoconfigure.spi.Ordered;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

/** A loader for components that are discovered via SPI. */
public interface ComponentLoader {
<T> Iterable<T> load(Class<T> spiClass);

/**
* Load implementations of an ordered SPI (i.e. implements {@link Ordered}).
*
* @param spiClass the SPI class
* @param <T> the SPI type
* @return list of SPI implementations, in order
*/
default <T extends Ordered> List<T> loadOrdered(Class<T> spiClass) {
return StreamSupport.stream(load(spiClass).spliterator(), false)
.sorted(Comparator.comparing(Ordered::order))
.collect(Collectors.toList());
}

default <T extends ConfigurableProvider> Map<String, T> loadConfigurableProviders(
Class<T> spiClass) {
Map<String, T> components = new HashMap<>();
for (T component : load(spiClass)) {
components.put(component.getName(), component);
}
return components;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ static NamedSpiManager<LogRecordExporter> logRecordExporterSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableLogRecordExporterProvider.class,
ConfigurableLogRecordExporterProvider::getName,
ConfigurableLogRecordExporterProvider::createExporter,
config);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
Expand All @@ -33,20 +34,25 @@ static void configureMeterProvider(
metricExporterCustomizer,
List<Closeable> closeables) {

// Configure default exemplar filters.
String exemplarFilter =
config.getString("otel.metrics.exemplar.filter", "trace_based").toLowerCase(Locale.ROOT);
switch (exemplarFilter) {
case "always_off":
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.alwaysOff());
break;
case "always_on":
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.alwaysOn());
break;
case "trace_based":
default:
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.traceBased());
break;
Optional<ExemplarFilter> spiExemplarFilter = spiHelper.loadOptional(ExemplarFilter.class);
if (spiExemplarFilter.isPresent()) {
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, spiExemplarFilter.get());
} else {
// Configure default exemplar filters.
String exemplarFilter =
config.getString("otel.metrics.exemplar.filter", "trace_based").toLowerCase(Locale.ROOT);
switch (exemplarFilter) {
case "always_off":
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.alwaysOff());
break;
case "always_on":
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.alwaysOn());
break;
case "trace_based":
default:
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.traceBased());
break;
}
}

int cardinalityLimit =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ static NamedSpiManager<MetricReader> metricReadersSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableMetricReaderProvider.class,
ConfigurableMetricReaderProvider::getName,
ConfigurableMetricReaderProvider::createMetricReader,
config);
}
Expand All @@ -107,7 +106,6 @@ static NamedSpiManager<MetricExporter> metricExporterSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableMetricExporterProvider.class,
ConfigurableMetricExporterProvider::getName,
ConfigurableMetricExporterProvider::createExporter,
config);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ static ContextPropagators configurePropagators(
NamedSpiManager<TextMapPropagator> spiPropagatorsManager =
spiHelper.loadConfigurable(
ConfigurablePropagatorProvider.class,
ConfigurablePropagatorProvider::getName,
ConfigurablePropagatorProvider::getPropagator,
config);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ static NamedSpiManager<SpanExporter> spanExporterSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableSpanExporterProvider.class,
ConfigurableSpanExporterProvider::getName,
ConfigurableSpanExporterProvider::createExporter,
config);
}
Expand Down
Loading

0 comments on commit 1c89890

Please sign in to comment.