Skip to content

Commit 1c89890

Browse files
committed
add ComponentLoader to support more auto configuration scenarios, e.g. spring boot
1 parent e9e1fee commit 1c89890

29 files changed

+257
-148
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,10 @@
11
Comparing source compatibility of against
2-
No changes.
2+
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder (not serializable)
3+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
4+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader(io.opentelemetry.sdk.autoconfigure.ComponentLoader)
5+
+++* NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.ComponentLoader (not serializable)
6+
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
7+
+++ NEW SUPERCLASS: java.lang.Object
8+
+++* NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.Iterable<T> load(java.lang.Class<T>)
9+
GENERIC TEMPLATES: +++ T:java.lang.Object
10+
+++ NEW ANNOTATION: java.lang.FunctionalInterface

sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigurablePropagatorProvider.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* #getPropagator(ConfigProperties)} will be enabled and available as part of {@link
1616
* OpenTelemetry#getPropagators()}.
1717
*/
18-
public interface ConfigurablePropagatorProvider {
18+
public interface ConfigurablePropagatorProvider extends ConfigurableProvider {
1919
/**
2020
* Returns a {@link TextMapPropagator} that can be registered to OpenTelemetry by providing the
2121
* property value specified by {@link #getName()}.
@@ -27,5 +27,6 @@ public interface ConfigurablePropagatorProvider {
2727
* property to enable it. If the name is the same as any other defined propagator name, it is
2828
* undefined which will be used.
2929
*/
30+
@Override
3031
String getName();
3132
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.sdk.autoconfigure.spi;
7+
8+
/**
9+
* A named configurable provider.
10+
*
11+
* <p>It can be used to generically determine if a provider should be replaced by another provider
12+
* with the same name.
13+
*/
14+
public interface ConfigurableProvider {
15+
/** Returns the name of this provider. */
16+
String getName();
17+
}

sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigurableMetricReaderProvider.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.sdk.autoconfigure.spi.internal;
77

88
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
9+
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
910
import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider;
1011
import io.opentelemetry.sdk.metrics.export.MetricExporter;
1112
import io.opentelemetry.sdk.metrics.export.MetricReader;
@@ -24,7 +25,7 @@
2425
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
2526
* at any time.
2627
*/
27-
public interface ConfigurableMetricReaderProvider {
28+
public interface ConfigurableMetricReaderProvider extends ConfigurableProvider {
2829

2930
/**
3031
* Returns a {@link MetricReader} that can be registered to OpenTelemetry by providing the
@@ -40,5 +41,6 @@ public interface ConfigurableMetricReaderProvider {
4041
* name, the resulting behavior is undefined and it is explicitly unspecified which reader /
4142
* exporter will actually be used.
4243
*/
44+
@Override
4345
String getName();
4446
}

sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/logs/ConfigurableLogRecordExporterProvider.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.sdk.autoconfigure.spi.logs;
77

88
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
9+
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
910
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
1011

1112
/**
@@ -16,7 +17,7 @@
1617
*
1718
* @since 1.19.0
1819
*/
19-
public interface ConfigurableLogRecordExporterProvider {
20+
public interface ConfigurableLogRecordExporterProvider extends ConfigurableProvider {
2021

2122
/**
2223
* Returns a {@link LogRecordExporter} that can be registered to OpenTelemetry by providing the
@@ -30,5 +31,6 @@ public interface ConfigurableLogRecordExporterProvider {
3031
* the name does conflict with another exporter name, the resulting behavior is undefined and it
3132
* is explicitly unspecified which exporter will actually be used.
3233
*/
34+
@Override
3335
String getName();
3436
}

sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/metrics/ConfigurableMetricExporterProvider.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.sdk.autoconfigure.spi.metrics;
77

88
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
9+
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
910
import io.opentelemetry.sdk.autoconfigure.spi.internal.ConfigurableMetricReaderProvider;
1011
import io.opentelemetry.sdk.metrics.export.MetricExporter;
1112
import io.opentelemetry.sdk.metrics.export.MetricReader;
@@ -22,7 +23,7 @@
2223
*
2324
* @since 1.15.0
2425
*/
25-
public interface ConfigurableMetricExporterProvider {
26+
public interface ConfigurableMetricExporterProvider extends ConfigurableProvider {
2627

2728
/**
2829
* Returns a {@link MetricExporter} that can be registered to OpenTelemetry by providing the
@@ -38,5 +39,6 @@ public interface ConfigurableMetricExporterProvider {
3839
* name, the resulting behavior is undefined and it is explicitly unspecified which exporter /
3940
* reader will actually be used.
4041
*/
42+
@Override
4143
String getName();
4244
}

sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/traces/ConfigurableSamplerProvider.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.sdk.autoconfigure.spi.traces;
77

88
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
9+
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
910
import io.opentelemetry.sdk.trace.samplers.Sampler;
1011

1112
/**
@@ -14,7 +15,7 @@
1415
* returned by {@link #getName()}, the sampler returned by {@link #createSampler(ConfigProperties)}
1516
* will be enabled and added to the SDK.
1617
*/
17-
public interface ConfigurableSamplerProvider {
18+
public interface ConfigurableSamplerProvider extends ConfigurableProvider {
1819

1920
/**
2021
* Returns a {@link Sampler} that can be registered to OpenTelemetry by providing the property
@@ -28,5 +29,6 @@ public interface ConfigurableSamplerProvider {
2829
* the name does conflict with another exporter name, the resulting behavior is undefined and it
2930
* is explicitly unspecified which exporter will actually be used.
3031
*/
32+
@Override
3133
String getName();
3234
}

sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/traces/ConfigurableSpanExporterProvider.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.sdk.autoconfigure.spi.traces;
77

88
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
9+
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
910
import io.opentelemetry.sdk.trace.export.SpanExporter;
1011

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

1920
/**
2021
* Returns a {@link SpanExporter} that can be registered to OpenTelemetry by providing the
@@ -28,5 +29,6 @@ public interface ConfigurableSpanExporterProvider {
2829
* the name does conflict with another exporter name, the resulting behavior is undefined and it
2930
* is explicitly unspecified which exporter will actually be used.
3031
*/
32+
@Override
3133
String getName();
3234
}

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java

+49-31
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,12 @@ public AutoConfiguredOpenTelemetrySdkBuilder setServiceClassLoader(
368368
return this;
369369
}
370370

371+
public AutoConfiguredOpenTelemetrySdkBuilder setComponentLoader(ComponentLoader componentLoader) {
372+
requireNonNull(componentLoader, "componentLoader");
373+
this.spiHelper = SpiHelper.create(componentLoader);
374+
return this;
375+
}
376+
371377
/**
372378
* Returns a new {@link AutoConfiguredOpenTelemetrySdk} holding components auto-configured using
373379
* the settings of this {@link AutoConfiguredOpenTelemetrySdkBuilder}.
@@ -403,41 +409,53 @@ public AutoConfiguredOpenTelemetrySdk build() {
403409
boolean sdkEnabled = !config.getBoolean("otel.sdk.disabled", false);
404410

405411
if (sdkEnabled) {
406-
SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder();
407-
meterProviderBuilder.setResource(resource);
408-
MeterProviderConfiguration.configureMeterProvider(
409-
meterProviderBuilder, config, spiHelper, metricExporterCustomizer, closeables);
410-
meterProviderBuilder = meterProviderCustomizer.apply(meterProviderBuilder, config);
411-
SdkMeterProvider meterProvider = meterProviderBuilder.build();
412+
SdkMeterProvider meterProvider =
413+
spiHelper.loadOptional(SdkMeterProvider.class).orElse(null);
414+
if (meterProvider == null) {
415+
SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder();
416+
meterProviderBuilder.setResource(resource);
417+
MeterProviderConfiguration.configureMeterProvider(
418+
meterProviderBuilder, config, spiHelper, metricExporterCustomizer, closeables);
419+
meterProviderBuilder = meterProviderCustomizer.apply(meterProviderBuilder, config);
420+
meterProvider = meterProviderBuilder.build();
421+
}
412422
closeables.add(meterProvider);
413423

414-
SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder();
415-
tracerProviderBuilder.setResource(resource);
416-
TracerProviderConfiguration.configureTracerProvider(
417-
tracerProviderBuilder,
418-
config,
419-
spiHelper,
420-
meterProvider,
421-
spanExporterCustomizer,
422-
spanProcessorCustomizer,
423-
samplerCustomizer,
424-
closeables);
425-
tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config);
426-
SdkTracerProvider tracerProvider = tracerProviderBuilder.build();
424+
SdkTracerProvider tracerProvider =
425+
spiHelper.loadOptional(SdkTracerProvider.class).orElse(null);
426+
if (tracerProvider == null) {
427+
SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder();
428+
tracerProviderBuilder.setResource(resource);
429+
TracerProviderConfiguration.configureTracerProvider(
430+
tracerProviderBuilder,
431+
config,
432+
spiHelper,
433+
meterProvider,
434+
spanExporterCustomizer,
435+
spanProcessorCustomizer,
436+
samplerCustomizer,
437+
closeables);
438+
tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config);
439+
tracerProvider = tracerProviderBuilder.build();
440+
}
427441
closeables.add(tracerProvider);
428442

429-
SdkLoggerProviderBuilder loggerProviderBuilder = SdkLoggerProvider.builder();
430-
loggerProviderBuilder.setResource(resource);
431-
LoggerProviderConfiguration.configureLoggerProvider(
432-
loggerProviderBuilder,
433-
config,
434-
spiHelper,
435-
meterProvider,
436-
logRecordExporterCustomizer,
437-
logRecordProcessorCustomizer,
438-
closeables);
439-
loggerProviderBuilder = loggerProviderCustomizer.apply(loggerProviderBuilder, config);
440-
SdkLoggerProvider loggerProvider = loggerProviderBuilder.build();
443+
SdkLoggerProvider loggerProvider =
444+
spiHelper.loadOptional(SdkLoggerProvider.class).orElse(null);
445+
if (loggerProvider == null) {
446+
SdkLoggerProviderBuilder loggerProviderBuilder = SdkLoggerProvider.builder();
447+
loggerProviderBuilder.setResource(resource);
448+
LoggerProviderConfiguration.configureLoggerProvider(
449+
loggerProviderBuilder,
450+
config,
451+
spiHelper,
452+
meterProvider,
453+
logRecordExporterCustomizer,
454+
logRecordProcessorCustomizer,
455+
closeables);
456+
loggerProviderBuilder = loggerProviderCustomizer.apply(loggerProviderBuilder, config);
457+
loggerProvider = loggerProviderBuilder.build();
458+
}
441459
closeables.add(loggerProvider);
442460

443461
ContextPropagators propagators =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.sdk.autoconfigure;
7+
8+
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
9+
import io.opentelemetry.sdk.autoconfigure.spi.Ordered;
10+
import java.util.Comparator;
11+
import java.util.HashMap;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.stream.Collectors;
15+
import java.util.stream.StreamSupport;
16+
17+
/** A loader for components that are discovered via SPI. */
18+
public interface ComponentLoader {
19+
<T> Iterable<T> load(Class<T> spiClass);
20+
21+
/**
22+
* Load implementations of an ordered SPI (i.e. implements {@link Ordered}).
23+
*
24+
* @param spiClass the SPI class
25+
* @param <T> the SPI type
26+
* @return list of SPI implementations, in order
27+
*/
28+
default <T extends Ordered> List<T> loadOrdered(Class<T> spiClass) {
29+
return StreamSupport.stream(load(spiClass).spliterator(), false)
30+
.sorted(Comparator.comparing(Ordered::order))
31+
.collect(Collectors.toList());
32+
}
33+
34+
default <T extends ConfigurableProvider> Map<String, T> loadConfigurableProviders(
35+
Class<T> spiClass) {
36+
Map<String, T> components = new HashMap<>();
37+
for (T component : load(spiClass)) {
38+
components.put(component.getName(), component);
39+
}
40+
return components;
41+
}
42+
}

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java

-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ static NamedSpiManager<LogRecordExporter> logRecordExporterSpiManager(
8080
ConfigProperties config, SpiHelper spiHelper) {
8181
return spiHelper.loadConfigurable(
8282
ConfigurableLogRecordExporterProvider.class,
83-
ConfigurableLogRecordExporterProvider::getName,
8483
ConfigurableLogRecordExporterProvider::createExporter,
8584
config);
8685
}

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MeterProviderConfiguration.java

+20-14
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Collections;
2020
import java.util.List;
2121
import java.util.Locale;
22+
import java.util.Optional;
2223
import java.util.Set;
2324
import java.util.function.BiFunction;
2425
import java.util.stream.Collectors;
@@ -33,20 +34,25 @@ static void configureMeterProvider(
3334
metricExporterCustomizer,
3435
List<Closeable> closeables) {
3536

36-
// Configure default exemplar filters.
37-
String exemplarFilter =
38-
config.getString("otel.metrics.exemplar.filter", "trace_based").toLowerCase(Locale.ROOT);
39-
switch (exemplarFilter) {
40-
case "always_off":
41-
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.alwaysOff());
42-
break;
43-
case "always_on":
44-
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.alwaysOn());
45-
break;
46-
case "trace_based":
47-
default:
48-
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.traceBased());
49-
break;
37+
Optional<ExemplarFilter> spiExemplarFilter = spiHelper.loadOptional(ExemplarFilter.class);
38+
if (spiExemplarFilter.isPresent()) {
39+
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, spiExemplarFilter.get());
40+
} else {
41+
// Configure default exemplar filters.
42+
String exemplarFilter =
43+
config.getString("otel.metrics.exemplar.filter", "trace_based").toLowerCase(Locale.ROOT);
44+
switch (exemplarFilter) {
45+
case "always_off":
46+
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.alwaysOff());
47+
break;
48+
case "always_on":
49+
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.alwaysOn());
50+
break;
51+
case "trace_based":
52+
default:
53+
SdkMeterProviderUtil.setExemplarFilter(meterProviderBuilder, ExemplarFilter.traceBased());
54+
break;
55+
}
5056
}
5157

5258
int cardinalityLimit =

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/MetricExporterConfiguration.java

-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ static NamedSpiManager<MetricReader> metricReadersSpiManager(
8282
ConfigProperties config, SpiHelper spiHelper) {
8383
return spiHelper.loadConfigurable(
8484
ConfigurableMetricReaderProvider.class,
85-
ConfigurableMetricReaderProvider::getName,
8685
ConfigurableMetricReaderProvider::createMetricReader,
8786
config);
8887
}
@@ -107,7 +106,6 @@ static NamedSpiManager<MetricExporter> metricExporterSpiManager(
107106
ConfigProperties config, SpiHelper spiHelper) {
108107
return spiHelper.loadConfigurable(
109108
ConfigurableMetricExporterProvider.class,
110-
ConfigurableMetricExporterProvider::getName,
111109
ConfigurableMetricExporterProvider::createExporter,
112110
config);
113111
}

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/PropagatorConfiguration.java

-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ static ContextPropagators configurePropagators(
3535
NamedSpiManager<TextMapPropagator> spiPropagatorsManager =
3636
spiHelper.loadConfigurable(
3737
ConfigurablePropagatorProvider.class,
38-
ConfigurablePropagatorProvider::getName,
3938
ConfigurablePropagatorProvider::getPropagator,
4039
config);
4140

sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java

-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ static NamedSpiManager<SpanExporter> spanExporterSpiManager(
8080
ConfigProperties config, SpiHelper spiHelper) {
8181
return spiHelper.loadConfigurable(
8282
ConfigurableSpanExporterProvider.class,
83-
ConfigurableSpanExporterProvider::getName,
8483
ConfigurableSpanExporterProvider::createExporter,
8584
config);
8685
}

0 commit comments

Comments
 (0)