)
+ GENERIC TEMPLATES: +++ T:io.opentelemetry.sdk.autoconfigure.spi.Ordered
diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigurablePropagatorProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigurablePropagatorProvider.java
index b5f693ed1f8..a2bfd57dcad 100644
--- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigurablePropagatorProvider.java
+++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigurablePropagatorProvider.java
@@ -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()}.
@@ -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();
}
diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigurableProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigurableProvider.java
new file mode 100644
index 00000000000..f41910c4768
--- /dev/null
+++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/ConfigurableProvider.java
@@ -0,0 +1,17 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.sdk.autoconfigure.spi;
+
+/**
+ * A named configurable provider.
+ *
+ * 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();
+}
diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigurableMetricReaderProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigurableMetricReaderProvider.java
index 1a9feb4acb8..6e8febd7237 100644
--- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigurableMetricReaderProvider.java
+++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ConfigurableMetricReaderProvider.java
@@ -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;
@@ -24,7 +25,7 @@
*
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
@@ -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();
}
diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/logs/ConfigurableLogRecordExporterProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/logs/ConfigurableLogRecordExporterProvider.java
index d4e3d2bc949..300b0c15aa8 100644
--- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/logs/ConfigurableLogRecordExporterProvider.java
+++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/logs/ConfigurableLogRecordExporterProvider.java
@@ -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;
/**
@@ -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
@@ -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();
}
diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/metrics/ConfigurableMetricExporterProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/metrics/ConfigurableMetricExporterProvider.java
index 465366c4e29..0d66a502fc2 100644
--- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/metrics/ConfigurableMetricExporterProvider.java
+++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/metrics/ConfigurableMetricExporterProvider.java
@@ -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;
@@ -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
@@ -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();
}
diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/traces/ConfigurableSamplerProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/traces/ConfigurableSamplerProvider.java
index b97d9eb4a43..5c20473bad0 100644
--- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/traces/ConfigurableSamplerProvider.java
+++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/traces/ConfigurableSamplerProvider.java
@@ -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;
/**
@@ -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
@@ -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();
}
diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/traces/ConfigurableSpanExporterProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/traces/ConfigurableSpanExporterProvider.java
index 94ac4cedafb..576785776a5 100644
--- a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/traces/ConfigurableSpanExporterProvider.java
+++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/traces/ConfigurableSpanExporterProvider.java
@@ -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;
/**
@@ -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
@@ -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();
}
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..0230acf37e4 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
@@ -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}.
@@ -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 =
diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ComponentLoader.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ComponentLoader.java
new file mode 100644
index 00000000000..6bbb92c2abf
--- /dev/null
+++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ComponentLoader.java
@@ -0,0 +1,48 @@
+/*
+ * 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.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+/** A loader for components that are discovered via SPI. */
+public interface ComponentLoader {
+ Iterable load(Class spiClass);
+
+ default Optional loadOptional(Class spiClass) {
+ Iterable iterable = load(spiClass);
+ return StreamSupport.stream(iterable.spliterator(), false).findFirst();
+ }
+
+ /**
+ * Load implementations of an ordered SPI (i.e. implements {@link Ordered}).
+ *
+ * @param spiClass the SPI class
+ * @param the SPI type
+ * @return list of SPI implementations, in order
+ */
+ default List loadOrdered(Class spiClass) {
+ return StreamSupport.stream(load(spiClass).spliterator(), false)
+ .sorted(Comparator.comparing(Ordered::order))
+ .collect(Collectors.toList());
+ }
+
+ default Map loadConfigurableProviders(
+ Class spiClass) {
+ Map components = new HashMap<>();
+ for (T component : load(spiClass)) {
+ components.put(component.getName(), component);
+ }
+ return components;
+ }
+}
diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java
index b0eeb2481c0..b576d8093bf 100644
--- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java
+++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/LogRecordExporterConfiguration.java
@@ -80,7 +80,6 @@ static NamedSpiManager logRecordExporterSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableLogRecordExporterProvider.class,
- ConfigurableLogRecordExporterProvider::getName,
ConfigurableLogRecordExporterProvider::createExporter,
config);
}
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..b269903030c 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
@@ -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;
@@ -33,20 +34,25 @@ static void configureMeterProvider(
metricExporterCustomizer,
List 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 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 =
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..028b3dacde5 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
@@ -82,7 +82,6 @@ static NamedSpiManager metricReadersSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableMetricReaderProvider.class,
- ConfigurableMetricReaderProvider::getName,
ConfigurableMetricReaderProvider::createMetricReader,
config);
}
@@ -107,7 +106,6 @@ static NamedSpiManager metricExporterSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableMetricExporterProvider.class,
- ConfigurableMetricExporterProvider::getName,
ConfigurableMetricExporterProvider::createExporter,
config);
}
diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/PropagatorConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/PropagatorConfiguration.java
index fea60b18f80..ca992bd5fc2 100644
--- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/PropagatorConfiguration.java
+++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/PropagatorConfiguration.java
@@ -35,7 +35,6 @@ static ContextPropagators configurePropagators(
NamedSpiManager spiPropagatorsManager =
spiHelper.loadConfigurable(
ConfigurablePropagatorProvider.class,
- ConfigurablePropagatorProvider::getName,
ConfigurablePropagatorProvider::getPropagator,
config);
diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java
index c5da0e0a045..68cec9f1ff6 100644
--- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java
+++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/SpanExporterConfiguration.java
@@ -80,7 +80,6 @@ static NamedSpiManager spanExporterSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableSpanExporterProvider.class,
- ConfigurableSpanExporterProvider::getName,
ConfigurableSpanExporterProvider::createExporter,
config);
}
diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java
index 1241acccc8d..7e61d16a41f 100644
--- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java
+++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/TracerProviderConfiguration.java
@@ -22,7 +22,6 @@
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.io.Closeable;
import java.time.Duration;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -56,7 +55,7 @@ static void configureTracerProvider(
config, spiHelper, spanExporterCustomizer, closeables);
List processors =
- configureSpanProcessors(config, exportersByName, meterProvider, closeables);
+ configureSpanProcessors(config, exportersByName, meterProvider, closeables, spiHelper);
for (SpanProcessor processor : processors) {
SpanProcessor wrapped = spanProcessorCustomizer.apply(processor, config);
if (wrapped != processor) {
@@ -70,9 +69,10 @@ static List configureSpanProcessors(
ConfigProperties config,
Map exportersByName,
MeterProvider meterProvider,
- List closeables) {
+ List closeables,
+ SpiHelper spiHelper) {
Map exportersByNameCopy = new HashMap<>(exportersByName);
- List spanProcessors = new ArrayList<>();
+ List spanProcessors = spiHelper.load(SpanProcessor.class);
SpanExporter exporter = exportersByNameCopy.remove("logging");
if (exporter != null) {
@@ -162,10 +162,7 @@ static SpanLimits configureSpanLimits(ConfigProperties config) {
static Sampler configureSampler(String sampler, ConfigProperties config, SpiHelper spiHelper) {
NamedSpiManager spiSamplersManager =
spiHelper.loadConfigurable(
- ConfigurableSamplerProvider.class,
- ConfigurableSamplerProvider::getName,
- ConfigurableSamplerProvider::createSampler,
- config);
+ ConfigurableSamplerProvider.class, ConfigurableSamplerProvider::createSampler, config);
switch (sampler) {
case "always_on":
@@ -173,21 +170,13 @@ static Sampler configureSampler(String sampler, ConfigProperties config, SpiHelp
case "always_off":
return Sampler.alwaysOff();
case "traceidratio":
- {
- double ratio =
- config.getDouble("otel.traces.sampler.arg", DEFAULT_TRACEIDRATIO_SAMPLE_RATIO);
- return Sampler.traceIdRatioBased(ratio);
- }
+ return ratioSampler(config);
case PARENTBASED_ALWAYS_ON:
return Sampler.parentBased(Sampler.alwaysOn());
case "parentbased_always_off":
return Sampler.parentBased(Sampler.alwaysOff());
case "parentbased_traceidratio":
- {
- double ratio =
- config.getDouble("otel.traces.sampler.arg", DEFAULT_TRACEIDRATIO_SAMPLE_RATIO);
- return Sampler.parentBased(Sampler.traceIdRatioBased(ratio));
- }
+ return Sampler.parentBased(ratioSampler(config));
case "parentbased_jaeger_remote":
Sampler jaegerRemote = spiSamplersManager.getByName("jaeger_remote");
if (jaegerRemote == null) {
@@ -205,5 +194,10 @@ static Sampler configureSampler(String sampler, ConfigProperties config, SpiHelp
}
}
+ private static Sampler ratioSampler(ConfigProperties config) {
+ double ratio = config.getDouble("otel.traces.sampler.arg", DEFAULT_TRACEIDRATIO_SAMPLE_RATIO);
+ return Sampler.traceIdRatioBased(ratio);
+ }
+
private TracerProviderConfiguration() {}
}
diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java
index 4002ce65329..9d28aba18cd 100644
--- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java
+++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelper.java
@@ -5,20 +5,21 @@
package io.opentelemetry.sdk.autoconfigure.internal;
+import io.opentelemetry.sdk.autoconfigure.ComponentLoader;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
+import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
import io.opentelemetry.sdk.autoconfigure.spi.Ordered;
import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.function.BiFunction;
-import java.util.function.Function;
import java.util.function.Supplier;
/**
@@ -27,49 +28,47 @@
*/
public final class SpiHelper {
- private final ClassLoader classLoader;
- private final SpiFinder spiFinder;
+ private final ComponentLoader componentLoader;
private final Set listeners =
Collections.newSetFromMap(new IdentityHashMap<>());
- // Visible for testing
- SpiHelper(ClassLoader classLoader, SpiFinder spiFinder) {
- this.classLoader = classLoader;
- this.spiFinder = spiFinder;
+ private SpiHelper(ComponentLoader componentLoader) {
+ this.componentLoader = componentLoader;
}
/** Create a {@link SpiHelper} which loads SPIs using the {@code classLoader}. */
public static SpiHelper create(ClassLoader classLoader) {
- return new SpiHelper(classLoader, ServiceLoader::load);
+ return new SpiHelper(new ServiceLoaderComponentLoader(classLoader));
+ }
+
+ public static SpiHelper create(ComponentLoader componentLoader) {
+ return new SpiHelper(componentLoader);
}
/**
* Load implementations of an SPI which are configurable (i.e. they accept {@link
* ConfigProperties}.
*
+ * @param the configurable type
+ * @param the SPI type
* @param spiClass the SPI class
- * @param getName function returning the name of an SPI implementation
* @param getConfigurable function returning a configured instance
* @param config the configuration to pass to invocations of {@code #getConfigurable}
- * @param the configurable type
- * @param the SPI type
* @return a {@link NamedSpiManager} used to access configured instances of the SPI by name
*/
- public NamedSpiManager loadConfigurable(
+ public NamedSpiManager loadConfigurable(
Class spiClass,
- Function getName,
BiFunction getConfigurable,
ConfigProperties config) {
Map> nameToProvider = new HashMap<>();
- for (S provider : load(spiClass)) {
- String name = getName.apply(provider);
- nameToProvider.put(
- name,
- () -> {
- T result = getConfigurable.apply(provider, config);
- maybeAddListener(result);
- return result;
- });
+ Map providers = componentLoader.loadConfigurableProviders(spiClass);
+ for (Map.Entry entry : providers.entrySet()) {
+ S provider = entry.getValue();
+ String name = entry.getKey();
+ // both the provider and the result may have a listener
+ maybeAddListener(provider);
+
+ nameToProvider.put(name, () -> maybeAddListener(getConfigurable.apply(provider, config)));
}
return NamedSpiManager.create(nameToProvider);
}
@@ -82,9 +81,7 @@ public NamedSpiManager loadConfigurable(
* @return list of SPI implementations, in order
*/
public List loadOrdered(Class spiClass) {
- List result = load(spiClass);
- result.sort(Comparator.comparing(Ordered::order));
- return result;
+ return init(componentLoader.loadOrdered(spiClass));
}
/**
@@ -95,18 +92,33 @@ public List loadOrdered(Class spiClass) {
* @return list of SPI implementations
*/
public List load(Class spiClass) {
+ return init(componentLoader.load(spiClass));
+ }
+
+ /**
+ * Load implementations of an SPI.
+ *
+ * @param components the SPI implementations
+ * @param the SPI type
+ * @return list of SPI implementations
+ */
+ private List init(Iterable components) {
List result = new ArrayList<>();
- for (T service : spiFinder.load(spiClass, classLoader)) {
- maybeAddListener(service);
- result.add(service);
+ for (T service : components) {
+ result.add(maybeAddListener(service));
}
return result;
}
- private void maybeAddListener(Object object) {
+ public Optional loadOptional(Class spiClass) {
+ return componentLoader.loadOptional(spiClass).map(this::maybeAddListener);
+ }
+
+ private T maybeAddListener(T object) {
if (object instanceof AutoConfigureListener) {
listeners.add((AutoConfigureListener) object);
}
+ return object;
}
/** Return the set of SPIs loaded which implement {@link AutoConfigureListener}. */
@@ -114,8 +126,16 @@ public Set getListeners() {
return Collections.unmodifiableSet(listeners);
}
- // Visible for testing
- interface SpiFinder {
- Iterable load(Class spiClass, ClassLoader classLoader);
+ private static class ServiceLoaderComponentLoader implements ComponentLoader {
+ private final ClassLoader classLoader;
+
+ private ServiceLoaderComponentLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ @Override
+ public Iterable load(Class spiClass) {
+ return ServiceLoader.load(spiClass, classLoader);
+ }
}
}
diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java
index a2d5c870d4b..7af00b18dda 100644
--- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java
+++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/internal/SpiHelperTest.java
@@ -11,10 +11,13 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import io.opentelemetry.sdk.autoconfigure.ComponentLoader;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
+import io.opentelemetry.sdk.autoconfigure.spi.ConfigurableProvider;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
import java.util.Collections;
@@ -28,18 +31,15 @@ public class SpiHelperTest {
@Test
public void canRetrieveByName() {
- SpiHelper.SpiFinder mockFinder = mock(SpiHelper.SpiFinder.class);
- when(mockFinder.load(any(), any()))
+ ComponentLoader mockLoader = spy(ComponentLoader.class);
+ when(mockLoader.load(any()))
.thenReturn(Collections.singletonList(new SpiExampleProviderImplementation()));
- SpiHelper spiHelper = new SpiHelper(SpiHelperTest.class.getClassLoader(), mockFinder);
+ SpiHelper spiHelper = SpiHelper.create(mockLoader);
NamedSpiManager spiProvider =
spiHelper.loadConfigurable(
- SpiExampleProvider.class,
- SpiExampleProvider::getName,
- SpiExampleProvider::createSpiExample,
- EMPTY);
+ SpiExampleProvider.class, SpiExampleProvider::createSpiExample, EMPTY);
assertThat(spiProvider.getByName(SpiExampleProviderImplementation.NAME)).isNotNull();
assertThat(spiProvider.getByName("invalid-provider")).isNull();
@@ -49,17 +49,14 @@ public void canRetrieveByName() {
public void instantiatesImplementationsLazily() {
SpiExampleProvider mockProvider = mock(SpiExampleProvider.class);
when(mockProvider.getName()).thenReturn("lazy-init-example");
- SpiHelper.SpiFinder mockFinder = mock(SpiHelper.SpiFinder.class);
- when(mockFinder.load(any(), any())).thenReturn(Collections.singletonList(mockProvider));
+ ComponentLoader mockLoader = spy(ComponentLoader.class);
+ when(mockLoader.load(any())).thenReturn(Collections.singletonList(mockProvider));
- SpiHelper spiHelper = new SpiHelper(SpiHelperTest.class.getClassLoader(), mockFinder);
+ SpiHelper spiHelper = SpiHelper.create(mockLoader);
NamedSpiManager spiProvider =
spiHelper.loadConfigurable(
- SpiExampleProvider.class,
- SpiExampleProvider::getName,
- SpiExampleProvider::createSpiExample,
- EMPTY);
+ SpiExampleProvider.class, SpiExampleProvider::createSpiExample, EMPTY);
verify(mockProvider, never()).createSpiExample(any()); // not requested yet
spiProvider.getByName("lazy-init-example");
@@ -68,18 +65,15 @@ public void instantiatesImplementationsLazily() {
@Test
public void onlyInstantiatesOnce() {
- SpiHelper.SpiFinder mockFinder = mock(SpiHelper.SpiFinder.class);
- when(mockFinder.load(any(), any()))
+ ComponentLoader mockLoader = mock(ComponentLoader.class);
+ when(mockLoader.load(any()))
.thenReturn(Collections.singletonList(new SpiExampleProviderImplementation()));
- SpiHelper spiHelper = new SpiHelper(SpiHelperTest.class.getClassLoader(), mockFinder);
+ SpiHelper spiHelper = SpiHelper.create(mockLoader);
NamedSpiManager spiProvider =
spiHelper.loadConfigurable(
- SpiExampleProvider.class,
- SpiExampleProvider::getName,
- SpiExampleProvider::createSpiExample,
- EMPTY);
+ SpiExampleProvider.class, SpiExampleProvider::createSpiExample, EMPTY);
SpiExample first = spiProvider.getByName(SpiExampleProviderImplementation.NAME);
SpiExample second = spiProvider.getByName(SpiExampleProviderImplementation.NAME);
@@ -93,17 +87,14 @@ public void failureToInitializeThrows() {
when(mockProvider.getName()).thenReturn("init-failure-example");
when(mockProvider.createSpiExample(any())).thenThrow(new RuntimeException());
- SpiHelper.SpiFinder mockFinder = mock(SpiHelper.SpiFinder.class);
- when(mockFinder.load(any(), any())).thenReturn(Collections.singletonList(mockProvider));
+ ComponentLoader mockLoader = spy(ComponentLoader.class);
+ when(mockLoader.load(any())).thenReturn(Collections.singletonList(mockProvider));
- SpiHelper spiHelper = new SpiHelper(SpiHelperTest.class.getClassLoader(), mockFinder);
+ SpiHelper spiHelper = SpiHelper.create(mockLoader);
NamedSpiManager spiProvider =
spiHelper.loadConfigurable(
- SpiExampleProvider.class,
- SpiExampleProvider::getName,
- SpiExampleProvider::createSpiExample,
- EMPTY);
+ SpiExampleProvider.class, SpiExampleProvider::createSpiExample, EMPTY);
assertThatThrownBy(() -> spiProvider.getByName("init-failure-example"))
.withFailMessage(exceptionMessage)
@@ -120,19 +111,19 @@ void loadsOrderedSpi() {
when(spi2.order()).thenReturn(0);
when(spi3.order()).thenReturn(1);
- SpiHelper.SpiFinder mockFinder = mock(SpiHelper.SpiFinder.class);
- when(mockFinder.load(ResourceProvider.class, SpiHelper.class.getClassLoader()))
- .thenReturn(asList(spi1, spi2, spi3));
+ ComponentLoader mockLoader = spy(ComponentLoader.class);
+ when(mockLoader.load(ResourceProvider.class)).thenReturn(asList(spi1, spi2, spi3));
- SpiHelper spiHelper = new SpiHelper(SpiHelperTest.class.getClassLoader(), mockFinder);
+ SpiHelper spiHelper = SpiHelper.create(mockLoader);
List loadedSpi = spiHelper.loadOrdered(ResourceProvider.class);
assertThat(loadedSpi).containsExactly(spi2, spi3, spi1);
}
- private interface SpiExampleProvider {
+ private interface SpiExampleProvider extends ConfigurableProvider {
+ @Override
String getName();
SpiExample createSpiExample(ConfigProperties config);
diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java
index ef533b82ac3..988a0ba22a8 100644
--- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java
+++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ConfigurableSpanExporterTest.java
@@ -146,7 +146,8 @@ void configureSpanProcessors_simpleSpanProcessor() {
Collections.singletonMap("otel.traces.exporter", exporterName)),
ImmutableMap.of(exporterName, LoggingSpanExporter.create()),
MeterProvider.noop(),
- closeables);
+ closeables,
+ spiHelper);
cleanup.addCloseables(closeables);
assertThat(spanProcessors).hasExactlyElementsOfTypes(SimpleSpanProcessor.class);
@@ -164,7 +165,8 @@ void configureSpanProcessors_batchSpanProcessor() {
Collections.singletonMap("otel.traces.exporter", exporterName)),
ImmutableMap.of(exporterName, ZipkinSpanExporter.builder().build()),
MeterProvider.noop(),
- closeables);
+ closeables,
+ spiHelper);
cleanup.addCloseables(closeables);
assertThat(spanProcessors).hasExactlyElementsOfTypes(BatchSpanProcessor.class);
@@ -185,7 +187,8 @@ void configureSpanProcessors_multipleExporters() {
"zipkin",
ZipkinSpanExporter.builder().build()),
MeterProvider.noop(),
- closeables);
+ closeables,
+ spiHelper);
cleanup.addCloseables(closeables);
assertThat(spanProcessors)
@@ -227,7 +230,8 @@ void configureSpanProcessors_multipleExportersWithLogging() {
"zipkin",
ZipkinSpanExporter.builder().build()),
MeterProvider.noop(),
- closeables);
+ closeables,
+ spiHelper);
cleanup.addCloseables(closeables);
assertThat(spanProcessors)
diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java
index 3469ec61e36..f8849992831 100644
--- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java
+++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactory.java
@@ -107,7 +107,6 @@ private static NamedSpiManager logRecordExporterSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableLogRecordExporterProvider.class,
- ConfigurableLogRecordExporterProvider::getName,
ConfigurableLogRecordExporterProvider::createExporter,
config);
}
diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java
index 7d187f8a057..5f3785543f3 100644
--- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java
+++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactory.java
@@ -134,7 +134,6 @@ private static NamedSpiManager metricExporterSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableMetricExporterProvider.class,
- ConfigurableMetricExporterProvider::getName,
ConfigurableMetricExporterProvider::createExporter,
config);
}
diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java
index bcaafd6c6e3..0f89ec49880 100644
--- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java
+++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactory.java
@@ -108,7 +108,6 @@ public MetricReader create(
metricReaderSpiManager(ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableMetricReaderProvider.class,
- ConfigurableMetricReaderProvider::getName,
ConfigurableMetricReaderProvider::createMetricReader,
config);
}
diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java
index 8d881c2d03e..767ba2604bd 100644
--- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java
+++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SamplerFactory.java
@@ -130,7 +130,6 @@ private static NamedSpiManager samplerSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableSamplerProvider.class,
- ConfigurableSamplerProvider::getName,
ConfigurableSamplerProvider::createSampler,
config);
}
diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java
index 8a3b8cc6dce..45214db8f96 100644
--- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java
+++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactory.java
@@ -141,7 +141,6 @@ private static NamedSpiManager spanExporterSpiManager(
ConfigProperties config, SpiHelper spiHelper) {
return spiHelper.loadConfigurable(
ConfigurableSpanExporterProvider.class,
- ConfigurableSpanExporterProvider::getName,
ConfigurableSpanExporterProvider::createExporter,
config);
}
diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java
index 4451ac98516..9616cc77cd4 100644
--- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java
+++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TextMapPropagatorFactory.java
@@ -49,7 +49,6 @@ public TextMapPropagator create(
NamedSpiManager spiPropagatorsManager =
spiHelper.loadConfigurable(
ConfigurablePropagatorProvider.class,
- ConfigurablePropagatorProvider::getName,
ConfigurablePropagatorProvider::getPropagator,
DefaultConfigProperties.createFromMap(Collections.emptyMap()));
Set propagators = new LinkedHashSet<>();
diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java
index 721421c8552..349b5dca15e 100644
--- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java
+++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordExporterFactoryTest.java
@@ -89,7 +89,7 @@ void create_OtlpDefaults() {
ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class);
verify(spiHelper)
.loadConfigurable(
- eq(ConfigurableLogRecordExporterProvider.class), any(), any(), configCaptor.capture());
+ eq(ConfigurableLogRecordExporterProvider.class), any(), configCaptor.capture());
ConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("otel.exporter.otlp.logs.protocol")).isNull();
assertThat(configProperties.getString("otel.exporter.otlp.endpoint")).isNull();
@@ -154,7 +154,7 @@ void create_OtlpConfigured(@TempDir Path tempDir)
ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class);
verify(spiHelper)
.loadConfigurable(
- eq(ConfigurableLogRecordExporterProvider.class), any(), any(), configCaptor.capture());
+ eq(ConfigurableLogRecordExporterProvider.class), any(), configCaptor.capture());
ConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("otel.exporter.otlp.logs.protocol"))
.isEqualTo("http/protobuf");
diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java
index 4b9b7520441..9f8344e2636 100644
--- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java
+++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricExporterFactoryTest.java
@@ -88,7 +88,7 @@ void create_OtlpDefaults() {
ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class);
verify(spiHelper)
.loadConfigurable(
- eq(ConfigurableMetricExporterProvider.class), any(), any(), configCaptor.capture());
+ eq(ConfigurableMetricExporterProvider.class), any(), configCaptor.capture());
ConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("otel.exporter.otlp.metrics.protocol")).isNull();
assertThat(configProperties.getString("otel.exporter.otlp.endpoint")).isNull();
@@ -162,7 +162,7 @@ void create_OtlpConfigured(@TempDir Path tempDir)
ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class);
verify(spiHelper)
.loadConfigurable(
- eq(ConfigurableMetricExporterProvider.class), any(), any(), configCaptor.capture());
+ eq(ConfigurableMetricExporterProvider.class), any(), configCaptor.capture());
ConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("otel.exporter.otlp.metrics.protocol"))
.isEqualTo("http/protobuf");
diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java
index 64da70549a1..dbc23f93730 100644
--- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java
+++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/MetricReaderFactoryTest.java
@@ -145,7 +145,7 @@ void create_PullPrometheusDefault() throws IOException {
ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class);
verify(spiHelper)
.loadConfigurable(
- eq(ConfigurableMetricReaderProvider.class), any(), any(), configCaptor.capture());
+ eq(ConfigurableMetricReaderProvider.class), any(), configCaptor.capture());
ConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("otel.exporter.prometheus.host")).isNull();
assertThat(configProperties.getInt("otel.exporter.prometheus.port")).isEqualTo(port);
@@ -182,7 +182,7 @@ void create_PullPrometheusConfigured() throws IOException {
ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class);
verify(spiHelper)
.loadConfigurable(
- eq(ConfigurableMetricReaderProvider.class), any(), any(), configCaptor.capture());
+ eq(ConfigurableMetricReaderProvider.class), any(), configCaptor.capture());
ConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("otel.exporter.prometheus.host")).isEqualTo("localhost");
assertThat(configProperties.getInt("otel.exporter.prometheus.port")).isEqualTo(port);
diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java
index 09c47433003..828cc2ab574 100644
--- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java
+++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanExporterFactoryTest.java
@@ -82,7 +82,7 @@ void create_OtlpDefaults() {
ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class);
verify(spiHelper)
.loadConfigurable(
- eq(ConfigurableSpanExporterProvider.class), any(), any(), configCaptor.capture());
+ eq(ConfigurableSpanExporterProvider.class), any(), configCaptor.capture());
ConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("otel.exporter.otlp.traces.protocol")).isNull();
assertThat(configProperties.getString("otel.exporter.otlp.endpoint")).isNull();
@@ -147,7 +147,7 @@ void create_OtlpConfigured(@TempDir Path tempDir)
ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class);
verify(spiHelper)
.loadConfigurable(
- eq(ConfigurableSpanExporterProvider.class), any(), any(), configCaptor.capture());
+ eq(ConfigurableSpanExporterProvider.class), any(), configCaptor.capture());
ConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("otel.exporter.otlp.traces.protocol"))
.isEqualTo("http/protobuf");
@@ -212,7 +212,7 @@ void create_ZipkinDefaults() {
ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class);
verify(spiHelper)
.loadConfigurable(
- eq(ConfigurableSpanExporterProvider.class), any(), any(), configCaptor.capture());
+ eq(ConfigurableSpanExporterProvider.class), any(), configCaptor.capture());
ConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("otel.exporter.zipkin.endpoint")).isNull();
assertThat(configProperties.getDuration("otel.exporter.zipkin.timeout")).isNull();
@@ -248,7 +248,7 @@ void create_ZipkinConfigured() {
ArgumentCaptor configCaptor = ArgumentCaptor.forClass(ConfigProperties.class);
verify(spiHelper)
.loadConfigurable(
- eq(ConfigurableSpanExporterProvider.class), any(), any(), configCaptor.capture());
+ eq(ConfigurableSpanExporterProvider.class), any(), configCaptor.capture());
ConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("otel.exporter.zipkin.endpoint"))
.isEqualTo("http://zipkin:9411/v1/v2/spans");
diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java
index 63de98ef5f3..6fba53e86cd 100644
--- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java
+++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/InstrumentGarbageCollectionBenchmarkTest.java
@@ -45,11 +45,12 @@ public class InstrumentGarbageCollectionBenchmarkTest {
@SuppressWarnings("rawtypes")
@Test
public void normalizedAllocationRateTest() throws RunnerException {
- // GitHub CI has an environment variable (CI=true). We can use it to skip
- // this test since it's a lengthy one (roughly 10 seconds) and have it running
- // only in GitHub CI
+ // OTel GitHub CI Workflow (see .github/) sets an environment variable
+ // (RUN_JMH_BASED_TESTS=true).
+ // We set it only there since it's a lengthy test (roughly 2.5min)
+ // and we want to run it only in CI.
Assumptions.assumeTrue(
- "true".equals(System.getenv("CI")),
+ "true".equals(System.getenv("RUN_JMH_BASED_TESTS")),
"This test should only run in GitHub CI since it's long");
// Runs InstrumentGarbageCollectionBenchmark
@@ -91,7 +92,7 @@ public void normalizedAllocationRateTest() throws RunnerException {
}
testInstrumentTypeResultsMap.forEach(
- (testInstrumentType, testInstrumentTypeResults) -> {
+ (testInstrumentTypeString, testInstrumentTypeResults) -> {
Map> resultMap =
testInstrumentTypeResults.aggregationTemporalityToMemoryModeResult;
assertThat(resultMap).hasSameSizeAs(AggregationTemporality.values());
@@ -108,9 +109,11 @@ public void normalizedAllocationRateTest() throws RunnerException {
assertThat(immutableDataAllocRate).isNotNull().isNotZero();
assertThat(reusableDataAllocRate).isNotNull().isNotZero();
+ TestInstrumentType testInstrumentType =
+ TestInstrumentType.valueOf(testInstrumentTypeString);
float dataAllocRateReductionPercentage =
- TestInstrumentType.valueOf(testInstrumentType)
- .getDataAllocRateReductionPercentage();
+ testInstrumentType.getDataAllocRateReductionPercentage();
+ double allowedOffset = testInstrumentType.getAllowedPercentOffset();
// If this test suddenly fails for you this means you have changed the code in a way
// that allocates more memory than before. You can find out where, by running
@@ -119,8 +122,8 @@ public void normalizedAllocationRateTest() throws RunnerException {
assertThat(100 - (reusableDataAllocRate / immutableDataAllocRate) * 100)
.describedAs(
"Aggregation temporality = %s, testInstrumentType = %s",
- aggregationTemporality, testInstrumentType)
- .isCloseTo(dataAllocRateReductionPercentage, Offset.offset(2.0));
+ aggregationTemporality, testInstrumentTypeString)
+ .isCloseTo(dataAllocRateReductionPercentage, Offset.offset(allowedOffset));
});
});
}
diff --git a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java
index 98cc39a6657..5a462fd94c8 100644
--- a/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java
+++ b/sdk/metrics/src/jmhBasedTest/java/io/opentelemetry/sdk/metrics/internal/state/TestInstrumentType.java
@@ -24,31 +24,52 @@ public enum TestInstrumentType {
ASYNC_COUNTER(AsyncCounterTester::new),
EXPONENTIAL_HISTOGRAM(ExponentialHistogramTester::new),
EXPLICIT_BUCKET(ExplicitBucketHistogramTester::new),
- LONG_SUM(LongSumTester::new, /* dataAllocRateReductionPercentage= */ 97.3f),
- DOUBLE_SUM(DoubleSumTester::new, /* dataAllocRateReductionPercentage= */ 97.3f),
- LONG_LAST_VALUE(LongLastValueTester::new, /* dataAllocRateReductionPercentage= */ 97.3f),
- DOUBLE_LAST_VALUE(DoubleLastValueTester::new, /* dataAllocRateReductionPercentage= */ 97.3f);
+ LONG_SUM(
+ LongSumTester::new,
+ /* dataAllocRateReductionPercentage= */ 97.3f,
+ /* allowedPercentOffset= */ 4.0f),
+ DOUBLE_SUM(
+ DoubleSumTester::new,
+ /* dataAllocRateReductionPercentage= */ 97.3f,
+ /* allowedPercentOffset= */ 2.0f),
+ LONG_LAST_VALUE(
+ LongLastValueTester::new,
+ /* dataAllocRateReductionPercentage= */ 97.3f,
+ /* allowedPercentOffset= */ 4.0f),
+ DOUBLE_LAST_VALUE(
+ DoubleLastValueTester::new,
+ /* dataAllocRateReductionPercentage= */ 97.3f,
+ /* allowedPercentOffset= */ 4.0f);
private final Supplier extends InstrumentTester> instrumentTesterInitializer;
private final float dataAllocRateReductionPercentage;
+ private final double allowedPercentOffset;
+ @SuppressWarnings("unused")
TestInstrumentType(Supplier extends InstrumentTester> instrumentTesterInitializer) {
this.dataAllocRateReductionPercentage = 99.8f; // default
this.instrumentTesterInitializer = instrumentTesterInitializer;
+ this.allowedPercentOffset = 2.0f;
}
// Some instruments have different reduction percentage.
TestInstrumentType(
Supplier extends InstrumentTester> instrumentTesterInitializer,
- float dataAllocRateReductionPercentage) {
+ float dataAllocRateReductionPercentage,
+ float allowedPercentOffset) {
this.instrumentTesterInitializer = instrumentTesterInitializer;
this.dataAllocRateReductionPercentage = dataAllocRateReductionPercentage;
+ this.allowedPercentOffset = allowedPercentOffset;
}
float getDataAllocRateReductionPercentage() {
return dataAllocRateReductionPercentage;
}
+ public double getAllowedPercentOffset() {
+ return allowedPercentOffset;
+ }
+
InstrumentTester createInstrumentTester() {
return instrumentTesterInitializer.get();
}
diff --git a/version.gradle.kts b/version.gradle.kts
index 7201568cbc2..2626983ff72 100644
--- a/version.gradle.kts
+++ b/version.gradle.kts
@@ -1,7 +1,7 @@
val snapshot = true
allprojects {
- var ver = "1.35.0"
+ var ver = "1.36.0"
val release = findProperty("otel.release")
if (release != null) {
ver += "-" + release