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 8d7b7c46317..b13ed7a0a33 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
@@ -20,6 +20,7 @@
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener;
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
+import io.opentelemetry.sdk.builder.internal.OpenTelemetrySdkBuilderUtil;
import io.opentelemetry.sdk.logs.LogRecordProcessor;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder;
@@ -476,6 +477,10 @@ private AutoConfiguredOpenTelemetrySdk buildImpl() {
try {
OpenTelemetrySdkBuilder sdkBuilder = OpenTelemetrySdk.builder();
+ if (INCUBATOR_AVAILABLE) {
+ OpenTelemetrySdkBuilderUtil.setSdkConfigProvider(
+ sdkBuilder, IncubatingUtil.toSdkConfigProvider(config));
+ }
// The propagation system is part of the API and functions in the absence of an SDK.
ContextPropagators propagators =
diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java
index 85c22c49324..9cb86ce615b 100644
--- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java
+++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/IncubatingUtil.java
@@ -10,6 +10,7 @@
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.common.ComponentLoader;
import io.opentelemetry.sdk.OpenTelemetrySdk;
+import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.resources.Resource;
import java.io.FileInputStream;
@@ -139,6 +140,25 @@ static AutoConfiguredOpenTelemetrySdk createWithFactory(String name, Factory fac
}
}
+ public static Object toSdkConfigProvider(ConfigProperties configProperties) {
+ try {
+ Class> sdkConfigProviderClass =
+ Class.forName(
+ "io.opentelemetry.sdk.extension.incubator.fileconfig.ConfigPropertiesBackedDeclarativeConfigProperties");
+ Class> configPropertiesClass =
+ Class.forName("io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties");
+
+ Method createMethod =
+ sdkConfigProviderClass.getMethod("createInstrumentationConfig", configPropertiesClass);
+ return createMethod.invoke(null, configProperties);
+ } catch (ClassNotFoundException
+ | NoSuchMethodException
+ | IllegalAccessException
+ | InvocationTargetException e) {
+ throw new IllegalStateException("Error creating SdkConfigProvider from ConfigProperties", e);
+ }
+ }
+
private static ConfigurationException toConfigurationException(
DeclarativeConfigException exception) {
String message = requireNonNull(exception.getMessage());
diff --git a/sdk-extensions/autoconfigure/src/testDeclarativeConfigSpi/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationSpiTest.java b/sdk-extensions/autoconfigure/src/testDeclarativeConfigSpi/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationSpiTest.java
index 85e79634b61..f9fe92585ac 100644
--- a/sdk-extensions/autoconfigure/src/testDeclarativeConfigSpi/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationSpiTest.java
+++ b/sdk-extensions/autoconfigure/src/testDeclarativeConfigSpi/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationSpiTest.java
@@ -13,7 +13,7 @@
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.OpenTelemetrySdk;
-import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk;
+import io.opentelemetry.sdk.builder.internal.OpenTelemetrySdkBuilderUtil;
import io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import io.opentelemetry.sdk.resources.Resource;
@@ -28,17 +28,20 @@ class DeclarativeConfigurationSpiTest {
@Test
void configFromSpi() {
- ExtendedOpenTelemetrySdk expectedSdk =
- ExtendedOpenTelemetrySdk.create(
- OpenTelemetrySdk.builder()
- .setTracerProvider(
- SdkTracerProvider.builder()
- .setResource(
- Resource.getDefault().toBuilder().put("service.name", "test").build())
- .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create()))
- .build())
- .build(),
- SdkConfigProvider.create(new OpenTelemetryConfigurationModel()));
+ OpenTelemetrySdk expectedSdk =
+ OpenTelemetrySdkBuilderUtil.setSdkConfigProvider(
+ OpenTelemetrySdk.builder()
+ .setTracerProvider(
+ SdkTracerProvider.builder()
+ .setResource(
+ Resource.getDefault().toBuilder()
+ .put("service.name", "test")
+ .build())
+ .addSpanProcessor(
+ SimpleSpanProcessor.create(LoggingSpanExporter.create()))
+ .build()),
+ SdkConfigProvider.create(new OpenTelemetryConfigurationModel()))
+ .build();
cleanup.addCloseable(expectedSdk);
AutoConfiguredOpenTelemetrySdkBuilder builder = spy(AutoConfiguredOpenTelemetrySdk.builder());
Thread thread = new Thread();
diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java
index 6feacb1a889..ee313c33a61 100644
--- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java
+++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java
@@ -91,7 +91,7 @@ void globalOpenTelemetry_AutoConfigureEnabled() {
private static OpenTelemetry unobfuscate(OpenTelemetry openTelemetry) {
try {
Field delegateField =
- Class.forName("io.opentelemetry.api.GlobalOpenTelemetry$ObfuscatedOpenTelemetry")
+ Class.forName("io.opentelemetry.api.incubator.internal.ObfuscatedExtendedOpenTelemetry")
.getDeclaredField("delegate");
delegateField.setAccessible(true);
Object delegate = delegateField.get(openTelemetry);
diff --git a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java
index 88bdb322b26..23dfd78cc84 100644
--- a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java
+++ b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/DeclarativeConfigurationTest.java
@@ -29,6 +29,7 @@
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
+import io.opentelemetry.sdk.builder.internal.OpenTelemetrySdkBuilderUtil;
import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
@@ -122,16 +123,18 @@ void configFile_Valid() {
OpenTelemetrySdk openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk();
Resource resource = Resource.getDefault().toBuilder().put("service.name", "test").build();
- ExtendedOpenTelemetrySdk expectedSdk =
- ExtendedOpenTelemetrySdk.create(
- OpenTelemetrySdk.builder()
- .setTracerProvider(
- SdkTracerProvider.builder()
- .setResource(resource)
- .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create()))
- .build())
- .build(),
- ((ExtendedOpenTelemetrySdk) openTelemetrySdk).getSdkConfigProvider());
+ OpenTelemetrySdk expectedSdk =
+ OpenTelemetrySdkBuilderUtil.setSdkConfigProvider(
+ OpenTelemetrySdk.builder()
+ .setTracerProvider(
+ SdkTracerProvider.builder()
+ .setResource(resource)
+ .addSpanProcessor(
+ SimpleSpanProcessor.create(LoggingSpanExporter.create()))
+ .build()),
+ ((ExtendedOpenTelemetrySdk) openTelemetrySdk).getSdkConfigProvider())
+ .build();
+
cleanup.addCloseable(expectedSdk);
assertThat(openTelemetrySdk.toString()).hasToString(expectedSdk.toString());
// AutoConfiguredOpenTelemetrySdk#getResource() is set to a dummy value when configuring from
diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigPropertiesBackedDeclarativeConfigProperties.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigPropertiesBackedDeclarativeConfigProperties.java
new file mode 100644
index 00000000000..21080778172
--- /dev/null
+++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigPropertiesBackedDeclarativeConfigProperties.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.sdk.extension.incubator.fileconfig;
+
+import static java.util.Collections.emptySet;
+
+import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
+import io.opentelemetry.common.ComponentLoader;
+import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Nullable;
+
+/**
+ * Implementation of {@link DeclarativeConfigProperties} backed by {@link ConfigProperties}.
+ *
+ *
It tracks the navigation path and only resolves to system properties at the leaf node when a
+ * value is actually requested.
+ */
+public final class ConfigPropertiesBackedDeclarativeConfigProperties
+ implements DeclarativeConfigProperties {
+
+ private final ConfigProperties configProperties;
+ private final List path;
+
+ public static DeclarativeConfigProperties createInstrumentationConfig(
+ ConfigProperties configProperties) {
+ return new ConfigPropertiesBackedDeclarativeConfigProperties(
+ configProperties, Collections.emptyList());
+ }
+
+ private ConfigPropertiesBackedDeclarativeConfigProperties(
+ ConfigProperties configProperties, List path) {
+ this.configProperties = configProperties;
+ this.path = path;
+ }
+
+ @Nullable
+ @Override
+ public String getString(String name) {
+ return configProperties.getString(resolvePropertyKey(name));
+ }
+
+ @Nullable
+ @Override
+ public Boolean getBoolean(String name) {
+ return configProperties.getBoolean(resolvePropertyKey(name));
+ }
+
+ @Nullable
+ @Override
+ public Integer getInt(String name) {
+ return configProperties.getInt(resolvePropertyKey(name));
+ }
+
+ @Nullable
+ @Override
+ public Long getLong(String name) {
+ return configProperties.getLong(resolvePropertyKey(name));
+ }
+
+ @Nullable
+ @Override
+ public Double getDouble(String name) {
+ return configProperties.getDouble(resolvePropertyKey(name));
+ }
+
+ /**
+ * Important: this method should return null if there is no structured child with the given name,
+ * but unfortunately that is not implementable on top of ConfigProperties.
+ *
+ * This will be misleading if anyone is comparing the return value to null.
+ */
+ @Override
+ public DeclarativeConfigProperties getStructured(String name) {
+ List newPath = new ArrayList<>(path);
+ newPath.add(name);
+ return new ConfigPropertiesBackedDeclarativeConfigProperties(configProperties, newPath);
+ }
+
+ @Nullable
+ @Override
+ @SuppressWarnings("unchecked") // Safe because T is known to be String via scalarType check
+ public List getScalarList(String name, Class scalarType) {
+ if (scalarType != String.class) {
+ return null;
+ }
+ List list = configProperties.getList(resolvePropertyKey(name));
+ if (list.isEmpty()) {
+ return null;
+ }
+ return (List) list;
+ }
+
+ @Nullable
+ @Override
+ public List getStructuredList(String name) {
+ return null;
+ }
+
+ @Override
+ public Set getPropertyKeys() {
+ // this is not supported when using system properties based configuration
+ return emptySet();
+ }
+
+ @Override
+ public ComponentLoader getComponentLoader() {
+ return configProperties.getComponentLoader();
+ }
+
+ private String resolvePropertyKey(String name) {
+ String fullPath = pathWithName(name);
+
+ if (!fullPath.startsWith("java.")) {
+ return "";
+ }
+
+ // Remove "java." prefix and translate the remaining path
+ String[] segments = fullPath.substring(5).split("\\.");
+ StringBuilder translatedPath = new StringBuilder();
+
+ for (int i = 0; i < segments.length; i++) {
+ if (i > 0) {
+ translatedPath.append(".");
+ }
+ translatedPath.append(translateName(segments[i]));
+ }
+
+ return "otel.instrumentation." + translatedPath;
+ }
+
+ private String pathWithName(String name) {
+ if (path.isEmpty()) {
+ return name;
+ }
+ return String.join(".", path) + "." + name;
+ }
+
+ private static String translateName(String name) {
+ if (name.endsWith("/development")) {
+ name = name.substring(0, name.length() - "/development".length());
+ if (!name.contains("experimental")) {
+ name = "experimental." + name;
+ }
+ }
+ return name.replace('_', '-');
+ }
+}
diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java
index a7d0a015bfd..4b195210dc4 100644
--- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java
+++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java
@@ -10,6 +10,7 @@
import io.opentelemetry.sdk.OpenTelemetrySdkBuilder;
import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
+import io.opentelemetry.sdk.builder.internal.OpenTelemetrySdkBuilderUtil;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.resources.Resource;
import java.util.Objects;
@@ -34,7 +35,9 @@ public ExtendedOpenTelemetrySdk create(
OpenTelemetryConfigurationModel model, DeclarativeConfigContext context) {
SdkConfigProvider sdkConfigProvider =
SdkConfigProvider.create(model, context.getSpiHelper().getComponentLoader());
- OpenTelemetrySdkBuilder builder = OpenTelemetrySdk.builder();
+ OpenTelemetrySdkBuilder builder =
+ OpenTelemetrySdkBuilderUtil.setSdkConfigProvider(
+ OpenTelemetrySdk.builder(), sdkConfigProvider);
String fileFormat = model.getFileFormat();
if (fileFormat == null || !SUPPORTED_FILE_FORMATS.matcher(fileFormat).matches()) {
throw new DeclarativeConfigException(
@@ -44,7 +47,7 @@ public ExtendedOpenTelemetrySdk create(
// behavior for experimental properties.
if (Objects.equals(true, model.getDisabled())) {
- return ExtendedOpenTelemetrySdk.create(builder.build(), sdkConfigProvider);
+ return (ExtendedOpenTelemetrySdk) builder.build();
}
if (model.getPropagator() != null) {
@@ -92,7 +95,6 @@ public ExtendedOpenTelemetrySdk create(
.build()));
}
- OpenTelemetrySdk openTelemetrySdk = context.addCloseable(builder.build());
- return ExtendedOpenTelemetrySdk.create(openTelemetrySdk, sdkConfigProvider);
+ return (ExtendedOpenTelemetrySdk) context.addCloseable(builder.build());
}
}
diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java
index cc1b3c2f3c1..32f4e9e98e2 100644
--- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java
+++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SdkConfigProvider.java
@@ -19,10 +19,13 @@ public final class SdkConfigProvider implements ConfigProvider {
private SdkConfigProvider(
OpenTelemetryConfigurationModel model, ComponentLoader componentLoader) {
- DeclarativeConfigProperties configProperties =
- DeclarativeConfiguration.toConfigProperties(model, componentLoader);
- this.instrumentationConfig =
- configProperties.getStructured("instrumentation/development", empty());
+ this(
+ DeclarativeConfiguration.toConfigProperties(model, componentLoader)
+ .getStructured("instrumentation/development", empty()));
+ }
+
+ private SdkConfigProvider(DeclarativeConfigProperties instrumentationConfig) {
+ this.instrumentationConfig = instrumentationConfig;
}
/**
@@ -47,6 +50,15 @@ public static SdkConfigProvider create(
return new SdkConfigProvider(model, componentLoader);
}
+ /**
+ * Create a no-op {@link SdkConfigProvider}.
+ *
+ * @return the no-op {@link SdkConfigProvider}
+ */
+ public static SdkConfigProvider noop() {
+ return new SdkConfigProvider(DeclarativeConfigProperties.empty());
+ }
+
@Override
public DeclarativeConfigProperties getInstrumentationConfig() {
return instrumentationConfig;
diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java
index eefa575cc5e..def409cb452 100644
--- a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java
+++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactoryTest.java
@@ -24,6 +24,7 @@
import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
+import io.opentelemetry.sdk.builder.internal.OpenTelemetrySdkBuilderUtil;
import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel;
@@ -123,9 +124,10 @@ void create_Defaults() {
List closeables = new ArrayList<>();
OpenTelemetryConfigurationModel model =
new OpenTelemetryConfigurationModel().withFileFormat("1.0-rc.1");
- ExtendedOpenTelemetrySdk expectedSdk =
- ExtendedOpenTelemetrySdk.create(
- OpenTelemetrySdk.builder().build(), SdkConfigProvider.create(model));
+ OpenTelemetrySdk expectedSdk =
+ OpenTelemetrySdkBuilderUtil.setSdkConfigProvider(
+ OpenTelemetrySdk.builder(), SdkConfigProvider.create(model))
+ .build();
cleanup.addCloseable(expectedSdk);
ExtendedOpenTelemetrySdk sdk =
@@ -154,9 +156,10 @@ void create_Disabled() {
.withExporter(
new LogRecordExporterModel()
.withOtlpHttp(new OtlpHttpExporterModel()))))));
- ExtendedOpenTelemetrySdk expectedSdk =
- ExtendedOpenTelemetrySdk.create(
- OpenTelemetrySdk.builder().build(), SdkConfigProvider.create(model));
+ OpenTelemetrySdk expectedSdk =
+ OpenTelemetrySdkBuilderUtil.setSdkConfigProvider(
+ OpenTelemetrySdk.builder(), SdkConfigProvider.create(model))
+ .build();
cleanup.addCloseable(expectedSdk);
ExtendedOpenTelemetrySdk sdk =
@@ -257,63 +260,64 @@ void create_Configured() throws NoSuchFieldException, IllegalAccessException {
.withName("stream-name")
.withAttributeKeys(null)))));
- ExtendedOpenTelemetrySdk expectedSdk =
- ExtendedOpenTelemetrySdk.create(
- OpenTelemetrySdk.builder()
- .setPropagators(
- ContextPropagators.create(
- TextMapPropagator.composite(
- W3CTraceContextPropagator.getInstance(),
- W3CBaggagePropagator.getInstance(),
- OtTracePropagator.getInstance(),
- B3Propagator.injectingMultiHeaders(),
- B3Propagator.injectingSingleHeader(),
- JaegerPropagator.getInstance())))
- .setLoggerProvider(
- SdkLoggerProvider.builder()
- .setResource(expectedResource)
- .setLogLimits(
- () ->
- LogLimits.builder()
- .setMaxAttributeValueLength(1)
- .setMaxNumberOfAttributes(2)
+ OpenTelemetrySdk expectedSdk =
+ OpenTelemetrySdkBuilderUtil.setSdkConfigProvider(
+ OpenTelemetrySdk.builder()
+ .setPropagators(
+ ContextPropagators.create(
+ TextMapPropagator.composite(
+ W3CTraceContextPropagator.getInstance(),
+ W3CBaggagePropagator.getInstance(),
+ OtTracePropagator.getInstance(),
+ B3Propagator.injectingMultiHeaders(),
+ B3Propagator.injectingSingleHeader(),
+ JaegerPropagator.getInstance())))
+ .setLoggerProvider(
+ SdkLoggerProvider.builder()
+ .setResource(expectedResource)
+ .setLogLimits(
+ () ->
+ LogLimits.builder()
+ .setMaxAttributeValueLength(1)
+ .setMaxNumberOfAttributes(2)
+ .build())
+ .addLogRecordProcessor(
+ io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor.builder(
+ OtlpHttpLogRecordExporter.getDefault())
+ .build())
+ .build())
+ .setTracerProvider(
+ SdkTracerProvider.builder()
+ .setResource(expectedResource)
+ .setSpanLimits(
+ SpanLimits.builder()
+ .setMaxNumberOfAttributes(1)
+ .setMaxAttributeValueLength(2)
+ .setMaxNumberOfEvents(3)
+ .setMaxNumberOfLinks(4)
+ .setMaxNumberOfAttributesPerEvent(5)
+ .setMaxNumberOfAttributesPerLink(6)
+ .build())
+ .setSampler(alwaysOn())
+ .addSpanProcessor(
+ io.opentelemetry.sdk.trace.export.BatchSpanProcessor.builder(
+ OtlpHttpSpanExporter.getDefault())
.build())
- .addLogRecordProcessor(
- io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor.builder(
- OtlpHttpLogRecordExporter.getDefault())
- .build())
- .build())
- .setTracerProvider(
- SdkTracerProvider.builder()
- .setResource(expectedResource)
- .setSpanLimits(
- SpanLimits.builder()
- .setMaxNumberOfAttributes(1)
- .setMaxAttributeValueLength(2)
- .setMaxNumberOfEvents(3)
- .setMaxNumberOfLinks(4)
- .setMaxNumberOfAttributesPerEvent(5)
- .setMaxNumberOfAttributesPerLink(6)
- .build())
- .setSampler(alwaysOn())
- .addSpanProcessor(
- io.opentelemetry.sdk.trace.export.BatchSpanProcessor.builder(
- OtlpHttpSpanExporter.getDefault())
- .build())
- .build())
- .setMeterProvider(
- SdkMeterProvider.builder()
- .setResource(expectedResource)
- .registerMetricReader(
- io.opentelemetry.sdk.metrics.export.PeriodicMetricReader.builder(
- OtlpHttpMetricExporter.getDefault())
- .build())
- .registerView(
- InstrumentSelector.builder().setName("instrument-name").build(),
- View.builder().setName("stream-name").build())
- .build())
- .build(),
- SdkConfigProvider.create(model));
+ .build())
+ .setMeterProvider(
+ SdkMeterProvider.builder()
+ .setResource(expectedResource)
+ .registerMetricReader(
+ io.opentelemetry.sdk.metrics.export.PeriodicMetricReader.builder(
+ OtlpHttpMetricExporter.getDefault())
+ .build())
+ .registerView(
+ InstrumentSelector.builder().setName("instrument-name").build(),
+ View.builder().setName("stream-name").build())
+ .build()),
+ SdkConfigProvider.create(model))
+ .build();
+
cleanup.addCloseable(expectedSdk);
ExtendedOpenTelemetrySdk sdk =
diff --git a/sdk/all/src/main/java/io/opentelemetry/sdk/IncubatingUtil.java b/sdk/all/src/main/java/io/opentelemetry/sdk/IncubatingUtil.java
new file mode 100644
index 00000000000..8694b045d3f
--- /dev/null
+++ b/sdk/all/src/main/java/io/opentelemetry/sdk/IncubatingUtil.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.sdk;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Utilities for interacting with incubating components ({@code
+ * io.opentelemetry:opentelemetry-api-incubator} and {@code
+ * io.opentelemetry:opentelemetry-sdk-extension-incubator}), which are not guaranteed to be present
+ * on the classpath. For all methods, callers MUST first separately reflectively confirm that the
+ * incubator is available on the classpath.
+ */
+final class IncubatingUtil {
+
+ private IncubatingUtil() {}
+
+ static Object noopSdkConfigProvider() {
+ try {
+ Class> sdkConfigProviderClass =
+ Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider");
+ Method defaultProviderMethod = sdkConfigProviderClass.getMethod("noop");
+ return defaultProviderMethod.invoke(null);
+ } catch (ClassNotFoundException
+ | NoSuchMethodException
+ | IllegalAccessException
+ | InvocationTargetException e) {
+ throw new IllegalStateException(
+ "Failed to create default SdkConfigProvider from incubator", e);
+ }
+ }
+
+ static OpenTelemetrySdk createExtendedOpenTelemetrySdk(
+ OpenTelemetrySdk openTelemetrySdk, Object sdkConfigProvider) {
+ try {
+ Class> extendedSdkClass =
+ Class.forName("io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk");
+ Class> sdkConfigProviderClass =
+ Class.forName("io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider");
+ Method createMethod =
+ extendedSdkClass.getMethod("create", OpenTelemetrySdk.class, sdkConfigProviderClass);
+ return (OpenTelemetrySdk)
+ createMethod.invoke(
+ null, openTelemetrySdk, sdkConfigProviderClass.cast(sdkConfigProvider));
+ } catch (ClassNotFoundException
+ | NoSuchMethodException
+ | IllegalAccessException
+ | InvocationTargetException e) {
+ throw new IllegalStateException(
+ "Failed to create ExtendedOpenTelemetrySdk from incubator", e);
+ }
+ }
+}
diff --git a/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdkBuilder.java b/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdkBuilder.java
index f8f079acd6e..811d6097021 100644
--- a/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdkBuilder.java
+++ b/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdkBuilder.java
@@ -5,6 +5,8 @@
package io.opentelemetry.sdk;
+import static java.util.Objects.requireNonNull;
+
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
@@ -22,6 +24,26 @@ public final class OpenTelemetrySdkBuilder {
@Nullable private SdkMeterProvider meterProvider;
@Nullable private SdkLoggerProvider loggerProvider;
+ @Nullable
+ private Object sdkConfigProvider =
+ INCUBATOR_AVAILABLE ? IncubatingUtil.noopSdkConfigProvider() : null;
+
+ private static final boolean INCUBATOR_AVAILABLE;
+
+ static {
+ boolean incubatorAvailable = false;
+ try {
+ Class.forName(
+ "io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider",
+ false,
+ OpenTelemetrySdkBuilder.class.getClassLoader());
+ incubatorAvailable = true;
+ } catch (ClassNotFoundException e) {
+ // Not available
+ }
+ INCUBATOR_AVAILABLE = incubatorAvailable;
+ }
+
/**
* Package protected to disallow direct initialization.
*
@@ -66,7 +88,12 @@ public OpenTelemetrySdkBuilder setLoggerProvider(SdkLoggerProvider loggerProvide
/** Sets the {@link ContextPropagators} to use. */
public OpenTelemetrySdkBuilder setPropagators(ContextPropagators propagators) {
- this.propagators = propagators;
+ this.propagators = requireNonNull(propagators);
+ return this;
+ }
+
+ OpenTelemetrySdkBuilder setSdkConfigProvider(Object sdkConfigProvider) {
+ this.sdkConfigProvider = requireNonNull(sdkConfigProvider);
return this;
}
@@ -111,6 +138,11 @@ public OpenTelemetrySdk build() {
loggerProvider = SdkLoggerProvider.builder().build();
}
- return new OpenTelemetrySdk(tracerProvider, meterProvider, loggerProvider, propagators);
+ OpenTelemetrySdk openTelemetrySdk =
+ new OpenTelemetrySdk(tracerProvider, meterProvider, loggerProvider, propagators);
+ return INCUBATOR_AVAILABLE
+ ? IncubatingUtil.createExtendedOpenTelemetrySdk(
+ openTelemetrySdk, requireNonNull(sdkConfigProvider))
+ : openTelemetrySdk;
}
}
diff --git a/sdk/all/src/main/java/io/opentelemetry/sdk/builder/internal/OpenTelemetrySdkBuilderUtil.java b/sdk/all/src/main/java/io/opentelemetry/sdk/builder/internal/OpenTelemetrySdkBuilderUtil.java
new file mode 100644
index 00000000000..e8b402f48b2
--- /dev/null
+++ b/sdk/all/src/main/java/io/opentelemetry/sdk/builder/internal/OpenTelemetrySdkBuilderUtil.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.sdk.builder.internal;
+
+import io.opentelemetry.sdk.OpenTelemetrySdkBuilder;
+import java.lang.reflect.Method;
+
+/**
+ * This class is internal and is hence not for public use. Its APIs are unstable and can change at
+ * any time.
+ */
+public final class OpenTelemetrySdkBuilderUtil {
+
+ private OpenTelemetrySdkBuilderUtil() {}
+
+ public static OpenTelemetrySdkBuilder setSdkConfigProvider(
+ OpenTelemetrySdkBuilder builder, Object sdkConfigProvider) {
+ try {
+ Method method =
+ OpenTelemetrySdkBuilder.class.getDeclaredMethod("setSdkConfigProvider", Object.class);
+ method.setAccessible(true);
+ method.invoke(builder, sdkConfigProvider);
+ return builder;
+ } catch (NoSuchMethodException
+ | IllegalAccessException
+ | java.lang.reflect.InvocationTargetException e) {
+ throw new IllegalStateException(
+ "Error calling setSdkConfigProvider on OpenTelemetrySdkBuilder", e);
+ }
+ }
+}