Add an auto-configuration builder. (#3753)

* Add an auto-configuration builder.

* Test

* Builder

* More

* Revamp

* Customizer only customizes

* Pass config to customizers

* More specific name

* Cleanup

* Cleanup

* SPI test

* Clean

* Clean

* Clean

* Shutdown once instead of flush and shutdown for simple

* Clean

* Cleanups

* Cleanup
This commit is contained in:
Anuraag Agrawal 2021-10-28 08:41:14 +09:00 committed by GitHub
parent c4c2e6c9db
commit 1e073fcff2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 699 additions and 96 deletions

View File

@ -161,14 +161,17 @@ public final class GlobalOpenTelemetry {
final Class<?> openTelemetrySdkAutoConfiguration;
try {
openTelemetrySdkAutoConfiguration =
Class.forName("io.opentelemetry.sdk.autoconfigure.OpenTelemetrySdkAutoConfiguration");
Class.forName("io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk");
} catch (ClassNotFoundException e) {
return null;
}
try {
Method initialize = openTelemetrySdkAutoConfiguration.getMethod("initialize");
return (OpenTelemetry) initialize.invoke(null);
Object autoConfiguredSdk = initialize.invoke(null);
Method getOpenTelemetrySdk =
openTelemetrySdkAutoConfiguration.getMethod("getOpenTelemetrySdk");
return (OpenTelemetry) getOpenTelemetrySdk.invoke(autoConfiguredSdk);
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new IllegalStateException(
"OpenTelemetrySdkAutoConfiguration detected on classpath "

View File

@ -1,2 +1,13 @@
Comparing source compatibility of against
No changes.
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addPropagatorCustomizer(java.util.function.BiFunction)
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addPropertiesSupplier(java.util.function.Supplier)
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addResourceCustomizer(java.util.function.BiFunction)
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addSamplerCustomizer(java.util.function.BiFunction)
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addSpanExporterCustomizer(java.util.function.BiFunction)
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) void customize(io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer)

View File

@ -0,0 +1,69 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.autoconfigure.spi;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Supplier;
/** A builder for customizing OpenTelemetry auto-configuration. */
public interface AutoConfigurationCustomizer {
/**
* Adds a {@link BiFunction} to invoke with the default autoconfigured {@link TextMapPropagator}
* to allow customization. The return value of the {@link BiFunction} will replace the passed-in
* argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
AutoConfigurationCustomizer addPropagatorCustomizer(
BiFunction<? super TextMapPropagator, ConfigProperties, ? extends TextMapPropagator>
propagatorCustomizer);
/**
* Adds a {@link BiFunction} to invoke with the default autoconfigured {@link Resource} to allow
* customization. The return value of the {@link BiFunction} will replace the passed-in argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
AutoConfigurationCustomizer addResourceCustomizer(
BiFunction<? super Resource, ConfigProperties, ? extends Resource> resourceCustomizer);
/**
* Adds a {@link BiFunction} to invoke with the default autoconfigured {@link Sampler} to allow
* customization. The return value of the {@link BiFunction} will replace the passed-in argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
AutoConfigurationCustomizer addSamplerCustomizer(
BiFunction<? super Sampler, ConfigProperties, ? extends Sampler> samplerCustomizer);
/**
* Adds a {@link BiFunction} to invoke with the default autoconfigured {@link SpanExporter} to
* allow customization. The return value of the {@link BiFunction} will replace the passed-in
* argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
AutoConfigurationCustomizer addSpanExporterCustomizer(
BiFunction<? super SpanExporter, ConfigProperties, ? extends SpanExporter>
exporterCustomizer);
/**
* Adds a {@link Supplier} of a map of property names and values to use as defaults for the {@link
* ConfigProperties} used during auto-configuration. The order of precedence of properties is
* system properties > environment variables > the suppliers registered with this method.
*
* <p>Multiple calls will cause properties to be merged in order, with later ones overwriting
* duplicate keys in earlier ones.
*/
AutoConfigurationCustomizer addPropertiesSupplier(
Supplier<Map<String, String>> propertiesSupplier);
}

View File

@ -0,0 +1,16 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.autoconfigure.spi;
/** A service provider interface (SPI) for customizing auto-configuration. */
public interface AutoConfigurationCustomizerProvider {
/**
* Method invoked when auto-configuring the SDK to allow further customization of
* auto-configuration.
*/
void customize(AutoConfigurationCustomizer autoConfiguration);
}

View File

@ -37,6 +37,8 @@ dependencies {
compileOnly(project(":exporters:prometheus"))
compileOnly(project(":exporters:zipkin"))
annotationProcessor("com.google.auto.value:auto-value")
testImplementation(project(path = ":sdk:trace-shaded-deps"))
testImplementation(project(":sdk:testing"))
@ -98,6 +100,7 @@ tasks {
environment("OTEL_EXPORTER_OTLP_TIMEOUT", "5000")
environment("OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT", "2")
environment("OTEL_TEST_CONFIGURED", "true")
environment("OTEL_TEST_WRAPPED", "1")
}
val testInitializeRegistersGlobal by existing(Test::class) {

View File

@ -0,0 +1,55 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.autoconfigure;
import com.google.auto.value.AutoValue;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
/**
* An auto-configured OpenTelemetry SDK. As an alternative to programmatically configuring the SDK
* using {@link OpenTelemetrySdk#builder()}, this package can be used to automatically configure the
* SDK using environment properties specified by OpenTelemetry.
*/
@AutoValue
public abstract class AutoConfiguredOpenTelemetrySdk {
/**
* Returns an {@link AutoConfiguredOpenTelemetrySdk} automatically initialized through recognized
* system properties and environment variables.
*
* <p>This will automatically set the resulting SDK as the {@link
* io.opentelemetry.api.GlobalOpenTelemetry} instance.
*/
public static AutoConfiguredOpenTelemetrySdk initialize() {
return builder().build();
}
/**
* Returns a new {@link AutoConfiguredOpenTelemetrySdkBuilder} which can be used to customize
* auto-configuration behavior.
*/
public static AutoConfiguredOpenTelemetrySdkBuilder builder() {
return new AutoConfiguredOpenTelemetrySdkBuilder();
}
static AutoConfiguredOpenTelemetrySdk create(
OpenTelemetrySdk sdk, Resource resource, ConfigProperties config) {
return new AutoValue_AutoConfiguredOpenTelemetrySdk(sdk, resource, config);
}
/** Returns the {@link OpenTelemetrySdk} that was auto-configured. */
public abstract OpenTelemetrySdk getOpenTelemetrySdk();
/** Returns the {@link Resource} that was auto-configured. */
public abstract Resource getResource();
/** Returns the {@link ConfigProperties} used for auto-configuration. */
public abstract ConfigProperties getConfig();
AutoConfiguredOpenTelemetrySdk() {}
}

View File

@ -0,0 +1,197 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.autoconfigure;
import static java.util.Objects.requireNonNull;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import javax.annotation.Nullable;
/**
* A builder for configuring auto-configuration of the OpenTelemetry SDK. Notably, auto-configured
* components can be customized, for example by delegating to them from a wrapper that tweaks
* behavior such as filtering out telemetry attributes.
*/
public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigurationCustomizer {
@Nullable private ConfigProperties config;
private BiFunction<? super TextMapPropagator, ConfigProperties, ? extends TextMapPropagator>
propagatorCustomizer = (a, unused) -> a;
private BiFunction<? super SpanExporter, ConfigProperties, ? extends SpanExporter>
spanExporterCustomizer = (a, unused) -> a;
private BiFunction<? super Resource, ConfigProperties, ? extends Resource> resourceCustomizer =
(a, unused) -> a;
private BiFunction<? super Sampler, ConfigProperties, ? extends Sampler> samplerCustomizer =
(a, unused) -> a;
private Supplier<Map<String, String>> propertiesSupplier = Collections::emptyMap;
private boolean setResultAsGlobal = true;
AutoConfiguredOpenTelemetrySdkBuilder() {
for (AutoConfigurationCustomizerProvider customizer :
ServiceLoader.load(AutoConfigurationCustomizerProvider.class)) {
customizer.customize(this);
}
}
/**
* Sets the {@link ConfigProperties} to use when resolving properties for auto-configuration.
* {@link #addPropertiesSupplier(Supplier)} will have no effect if this method is used.
*/
AutoConfiguredOpenTelemetrySdkBuilder setConfig(ConfigProperties config) {
requireNonNull(config, "config");
this.config = config;
return this;
}
/**
* Adds a {@link BiFunction} to invoke with the default autoconfigured {@link TextMapPropagator}
* to allow customization. The return value of the {@link BiFunction} will replace the passed-in
* argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
@Override
public AutoConfiguredOpenTelemetrySdkBuilder addPropagatorCustomizer(
BiFunction<? super TextMapPropagator, ConfigProperties, ? extends TextMapPropagator>
propagatorCustomizer) {
requireNonNull(propagatorCustomizer, "propagatorCustomizer");
this.propagatorCustomizer = mergeCustomizer(this.propagatorCustomizer, propagatorCustomizer);
return this;
}
/**
* Adds a {@link BiFunction} to invoke with the default autoconfigured {@link Resource} to allow
* customization. The return value of the {@link BiFunction} will replace the passed-in argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
@Override
public AutoConfiguredOpenTelemetrySdkBuilder addResourceCustomizer(
BiFunction<? super Resource, ConfigProperties, ? extends Resource> resourceCustomizer) {
requireNonNull(resourceCustomizer, "resourceCustomizer");
this.resourceCustomizer = mergeCustomizer(this.resourceCustomizer, resourceCustomizer);
return this;
}
/**
* Adds a {@link BiFunction} to invoke with the default autoconfigured {@link Sampler} to allow
* customization. The return value of the {@link BiFunction} will replace the passed-in argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
@Override
public AutoConfiguredOpenTelemetrySdkBuilder addSamplerCustomizer(
BiFunction<? super Sampler, ConfigProperties, ? extends Sampler> samplerCustomizer) {
requireNonNull(samplerCustomizer, "samplerCustomizer");
this.samplerCustomizer = mergeCustomizer(this.samplerCustomizer, samplerCustomizer);
return this;
}
/**
* Adds a {@link BiFunction} to invoke with the default autoconfigured {@link SpanExporter} to
* allow customization. The return value of the {@link BiFunction} will replace the passed-in
* argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
@Override
public AutoConfiguredOpenTelemetrySdkBuilder addSpanExporterCustomizer(
BiFunction<? super SpanExporter, ConfigProperties, ? extends SpanExporter>
spanExporterCustomizer) {
requireNonNull(spanExporterCustomizer, "spanExporterCustomizer");
this.spanExporterCustomizer =
mergeCustomizer(this.spanExporterCustomizer, spanExporterCustomizer);
return this;
}
/**
* Adds a {@link Supplier} of a map of property names and values to use as defaults for the {@link
* ConfigProperties} used during auto-configuration. The order of precedence of properties is
* system properties > environment variables > the suppliers registered with this method.
*
* <p>Multiple calls will cause properties to be merged in order, with later ones overwriting
* duplicate keys in earlier ones.
*/
@Override
public AutoConfiguredOpenTelemetrySdkBuilder addPropertiesSupplier(
Supplier<Map<String, String>> propertiesSupplier) {
requireNonNull(propertiesSupplier, "propertiesSupplier");
this.propertiesSupplier = mergeProperties(this.propertiesSupplier, propertiesSupplier);
return this;
}
/**
* Sets whether the configured {@link OpenTelemetrySdk} should be set as the application's
* {@linkplain io.opentelemetry.api.GlobalOpenTelemetry global} instance.
*/
public AutoConfiguredOpenTelemetrySdkBuilder setResultAsGlobal(boolean setResultAsGlobal) {
this.setResultAsGlobal = setResultAsGlobal;
return this;
}
/**
* Returns a new {@link AutoConfiguredOpenTelemetrySdk} holding components auto-configured using
* the settings of this {@link AutoConfiguredOpenTelemetrySdkBuilder}.
*/
@SuppressWarnings("deprecation") // Using classes which will be made package-private later.
public AutoConfiguredOpenTelemetrySdk build() {
ConfigProperties config = getConfig();
Resource resource =
OpenTelemetryResourceAutoConfiguration.configureResource(config, resourceCustomizer);
OpenTelemetrySdk sdk =
OpenTelemetrySdkAutoConfiguration.newOpenTelemetrySdk(
config,
resource,
propagatorCustomizer,
spanExporterCustomizer,
samplerCustomizer,
setResultAsGlobal);
return AutoConfiguredOpenTelemetrySdk.create(sdk, resource, config);
}
private ConfigProperties getConfig() {
ConfigProperties config = this.config;
if (config == null) {
config = DefaultConfigProperties.get(propertiesSupplier.get());
}
return config;
}
private static <I, O1, O2> BiFunction<I, ConfigProperties, O2> mergeCustomizer(
BiFunction<? super I, ConfigProperties, ? extends O1> first,
BiFunction<? super O1, ConfigProperties, ? extends O2> second) {
return (I configured, ConfigProperties config) -> {
O1 firstResult = first.apply(configured, config);
return second.apply(firstResult, config);
};
}
private static Supplier<Map<String, String>> mergeProperties(
Supplier<Map<String, String>> first, Supplier<Map<String, String>> second) {
return () -> {
Map<String, String> merged = new HashMap<>();
merged.putAll(first.get());
merged.putAll(second.get());
return merged;
};
}
}

View File

@ -30,18 +30,22 @@ final class DefaultConfigProperties implements ConfigProperties {
private final Map<String, String> config;
static ConfigProperties get() {
return new DefaultConfigProperties(System.getProperties(), System.getenv());
static ConfigProperties get(Map<String, String> defaultProperties) {
return new DefaultConfigProperties(System.getProperties(), System.getenv(), defaultProperties);
}
// Visible for testing
static ConfigProperties createForTest(Map<String, String> properties) {
return new DefaultConfigProperties(properties, Collections.emptyMap());
return new DefaultConfigProperties(properties, Collections.emptyMap(), Collections.emptyMap());
}
private DefaultConfigProperties(
Map<?, ?> systemProperties, Map<String, String> environmentVariables) {
Map<?, ?> systemProperties,
Map<String, String> environmentVariables,
Map<String, String> defaultProperties) {
Map<String, String> config = new HashMap<>();
defaultProperties.forEach(
(name, value) -> config.put(name.toLowerCase(Locale.ROOT).replace('-', '.'), value));
environmentVariables.forEach(
(name, value) -> config.put(name.toLowerCase(Locale.ROOT).replace('_', '.'), value));
systemProperties.forEach(

View File

@ -10,12 +10,16 @@ import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.util.Collections;
/**
* Factory for a {@link Resource} which parses the standard "otel.resource.attributes" system
* property or OTEL_RESOURCE_ATTRIBUTES environment variable. Will also use
* OTEL_SERVICE_NAME/otel.service.name to specifically set the service name.
*
* @deprecated Use {@link AutoConfiguredOpenTelemetrySdk#getResource()}.
*/
@Deprecated
public final class EnvironmentResource {
// Visible for testing
@ -26,9 +30,13 @@ public final class EnvironmentResource {
* Returns a {@link Resource} which contains information from the standard
* "otel.resource.attributes"/"otel.service.name" system properties or
* OTEL_RESOURCE_ATTRIBUTES/OTEL_SERVICE_NAME environment variables.
*
* @deprecated Use the information retrievable from {@link
* AutoConfiguredOpenTelemetrySdk#getResource()}.
*/
@Deprecated
public static Resource get() {
return create(DefaultConfigProperties.get());
return create(DefaultConfigProperties.get(Collections.emptyMap()));
}
static Resource create(ConfigProperties config) {

View File

@ -8,11 +8,18 @@ package io.opentelemetry.sdk.autoconfigure;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
import io.opentelemetry.sdk.resources.Resource;
import java.util.Collections;
import java.util.HashSet;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.function.BiFunction;
/** Auto-configuration for the OpenTelemetry {@link Resource}. */
/**
* Auto-configuration for the OpenTelemetry {@link Resource}.
*
* @deprecated Use {@link AutoConfiguredOpenTelemetrySdk#getResource()}.
*/
@Deprecated
public final class OpenTelemetryResourceAutoConfiguration {
/**
@ -20,16 +27,29 @@ public final class OpenTelemetryResourceAutoConfiguration {
*
* <p>This method will auto-configure the returned {@link Resource} using system properties and
* environment variables.
*
* @deprecated Use {@link AutoConfiguredOpenTelemetrySdk#getResource()}.
*/
@Deprecated
public static Resource configureResource() {
return configureResource(DefaultConfigProperties.get());
return configureResource(DefaultConfigProperties.get(Collections.emptyMap()));
}
/**
* Returns a {@link Resource} automatically initialized through recognized system properties and
* environment variables.
*
* @deprecated Use {@link AutoConfiguredOpenTelemetrySdk#getResource()}.
*/
@Deprecated
public static Resource configureResource(ConfigProperties config) {
return configureResource(config, (a, unused) -> a);
}
@SuppressWarnings("deprecation") // Uses class which will be made package private
static Resource configureResource(
ConfigProperties config,
BiFunction<? super Resource, ConfigProperties, ? extends Resource> resourceCustomizer) {
Resource result = Resource.getDefault();
// TODO(anuraaga): We use a hyphen only once in this artifact, for
@ -46,7 +66,7 @@ public final class OpenTelemetryResourceAutoConfiguration {
result = result.merge(EnvironmentResource.create(config));
return result;
return resourceCustomizer.apply(result, config);
}
private OpenTelemetryResourceAutoConfiguration() {}

View File

@ -9,6 +9,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.GlobalMeterProvider;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.metrics.SdkMeterProviderConfigurer;
@ -17,13 +18,19 @@ import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
import io.opentelemetry.sdk.metrics.exemplar.ExemplarFilter;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.util.ServiceLoader;
import java.util.function.BiFunction;
/**
* Auto-configuration for the OpenTelemetry SDK. As an alternative to programmatically configuring
* the SDK using {@link OpenTelemetrySdk#builder()}, this package can be used to automatically
* configure the SDK using environment properties specified by OpenTelemetry.
*
* @deprecated Use {@link AutoConfiguredOpenTelemetrySdk}.
*/
@Deprecated
public final class OpenTelemetrySdkAutoConfiguration {
/**
@ -32,9 +39,12 @@ public final class OpenTelemetrySdkAutoConfiguration {
*
* <p>This will automatically set the resulting SDK as the {@link
* io.opentelemetry.api.GlobalOpenTelemetry} instance.
*
* @deprecated Use {@link AutoConfiguredOpenTelemetrySdk#initialize()}.
*/
@Deprecated
public static OpenTelemetrySdk initialize() {
return initialize(true);
return AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk();
}
/**
@ -43,9 +53,15 @@ public final class OpenTelemetrySdkAutoConfiguration {
*
* @param setResultAsGlobal Whether to automatically set the configured SDK as the {@link
* io.opentelemetry.api.GlobalOpenTelemetry} instance.
* @deprecated Use {@code
* AutoConfiguredSdk.builder().setResultAsGlobal(setResultAsGlobal).build().getOpenTelemetrySdk()}.
*/
@Deprecated
public static OpenTelemetrySdk initialize(boolean setResultAsGlobal) {
return initialize(setResultAsGlobal, DefaultConfigProperties.get());
return AutoConfiguredOpenTelemetrySdk.builder()
.setResultAsGlobal(setResultAsGlobal)
.build()
.getOpenTelemetrySdk();
}
/**
@ -56,16 +72,35 @@ public final class OpenTelemetrySdkAutoConfiguration {
* GlobalOpenTelemetry} instance.
* @param config A {@link ConfigProperties} instance that contains properties that are to be used
* to auto-configure the returned {@link OpenTelemetrySdk}.
* @deprecated Use {@code
* AutoConfiguredSdk.builder().setResultAsGlobal(setResultAsGlobal).setConfig(config).build().getOpenTelemetrySdk()}.
*/
@Deprecated
public static OpenTelemetrySdk initialize(boolean setResultAsGlobal, ConfigProperties config) {
ContextPropagators propagators = PropagatorConfiguration.configurePropagators(config);
return AutoConfiguredOpenTelemetrySdk.builder()
.setResultAsGlobal(setResultAsGlobal)
.setConfig(config)
.build()
.getOpenTelemetrySdk();
}
Resource resource = OpenTelemetryResourceAutoConfiguration.configureResource(config);
static OpenTelemetrySdk newOpenTelemetrySdk(
ConfigProperties config,
Resource resource,
BiFunction<? super TextMapPropagator, ConfigProperties, ? extends TextMapPropagator>
propagatorCustomizer,
BiFunction<? super SpanExporter, ConfigProperties, ? extends SpanExporter>
spanExporterCustomizer,
BiFunction<? super Sampler, ConfigProperties, ? extends Sampler> samplerCustomizer,
boolean setResultAsGlobal) {
ContextPropagators propagators =
PropagatorConfiguration.configurePropagators(config, propagatorCustomizer);
configureMeterProvider(resource, config);
SdkTracerProvider tracerProvider =
TracerProviderConfiguration.configureTracerProvider(resource, config);
TracerProviderConfiguration.configureTracerProvider(
resource, config, spanExporterCustomizer, samplerCustomizer);
OpenTelemetrySdk openTelemetrySdk =
OpenTelemetrySdk.builder()

View File

@ -17,10 +17,14 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
final class PropagatorConfiguration {
static ContextPropagators configurePropagators(ConfigProperties config) {
static ContextPropagators configurePropagators(
ConfigProperties config,
BiFunction<? super TextMapPropagator, ConfigProperties, ? extends TextMapPropagator>
propagatorCustomizer) {
Set<TextMapPropagator> propagators = new LinkedHashSet<>();
List<String> requestedPropagators = config.getList("otel.propagators");
if (requestedPropagators.isEmpty()) {
@ -36,7 +40,8 @@ final class PropagatorConfiguration {
config);
for (String propagatorName : requestedPropagators) {
propagators.add(getPropagator(propagatorName, spiPropagators));
propagators.add(
propagatorCustomizer.apply(getPropagator(propagatorName, spiPropagators), config));
}
return ContextPropagators.create(TextMapPropagator.composite(propagators));

View File

@ -32,6 +32,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
final class SpanExporterConfiguration {
@ -39,7 +40,10 @@ final class SpanExporterConfiguration {
private static final String EXPORTER_NONE = "none";
// Visible for testing
static Map<String, SpanExporter> configureSpanExporters(ConfigProperties config) {
static Map<String, SpanExporter> configureSpanExporters(
ConfigProperties config,
BiFunction<? super SpanExporter, ConfigProperties, ? extends SpanExporter>
spanExporterCustomizer) {
List<String> exporterNamesList = config.getList("otel.traces.exporter");
Set<String> exporterNames = new HashSet<>(exporterNamesList);
if (exporterNamesList.size() != exporterNames.size()) {
@ -58,7 +62,12 @@ final class SpanExporterConfiguration {
throw new ConfigurationException(
"otel.traces.exporter contains " + EXPORTER_NONE + " along with other exporters");
}
return Collections.emptyMap();
SpanExporter noop = SpanExporter.composite();
SpanExporter customized = spanExporterCustomizer.apply(noop, config);
if (customized == noop) {
return Collections.emptyMap();
}
return Collections.singletonMap("none", customized);
}
if (exporterNames.isEmpty()) {
@ -77,7 +86,9 @@ final class SpanExporterConfiguration {
.collect(
toMap(
Function.identity(),
exporterName -> configureExporter(exporterName, config, spiExporters)));
exporterName ->
spanExporterCustomizer.apply(
configureExporter(exporterName, config, spiExporters), config)));
}
// Visible for testing

View File

@ -27,19 +27,27 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.function.BiFunction;
final class TracerProviderConfiguration {
static SdkTracerProvider configureTracerProvider(Resource resource, ConfigProperties config) {
static SdkTracerProvider configureTracerProvider(
Resource resource,
ConfigProperties config,
BiFunction<? super SpanExporter, ConfigProperties, ? extends SpanExporter>
spanExporterCustomizer,
BiFunction<? super Sampler, ConfigProperties, ? extends Sampler> samplerCustomizer) {
SdkTracerProviderBuilder tracerProviderBuilder =
SdkTracerProvider.builder()
.setResource(resource)
.setSpanLimits(configureSpanLimits(config));
String sampler = config.getString("otel.traces.sampler");
if (sampler != null) {
tracerProviderBuilder.setSampler(configureSampler(sampler, config));
if (sampler == null) {
sampler = "parentbased_always_on";
}
tracerProviderBuilder.setSampler(
samplerCustomizer.apply(configureSampler(sampler, config), config));
// Run user configuration before setting exporters from environment to allow user span
// processors to effect export.
@ -49,7 +57,7 @@ final class TracerProviderConfiguration {
}
Map<String, SpanExporter> exportersByName =
SpanExporterConfiguration.configureSpanExporters(config);
SpanExporterConfiguration.configureSpanExporters(config, spanExporterCustomizer);
configureSpanProcessors(config, exportersByName)
.forEach(tracerProviderBuilder::addSpanProcessor);

View File

@ -14,6 +14,7 @@ import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import org.junit.jupiter.api.Test;
@SuppressWarnings("deprecation") // Tests class which will be made package private
class EnvironmentResourceTest {
@Test

View File

@ -130,7 +130,8 @@ class NotOnClasspathTest {
() ->
PropagatorConfiguration.configurePropagators(
DefaultConfigProperties.createForTest(
Collections.singletonMap("otel.propagators", "b3"))))
Collections.singletonMap("otel.propagators", "b3")),
(a, config) -> a))
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining("Unrecognized value for otel.propagators: b3");
}

View File

@ -0,0 +1,136 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.autoconfigure;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.opentelemetry.sdk.trace.samplers.SamplingResult;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class OpenTelemetrySdkAutoConfigurationTest {
private static final ContextKey<String> CONTEXT_KEY = ContextKey.named("animal");
@Mock private TextMapPropagator propagator1;
@Mock private TextMapPropagator propagator2;
@Mock private TextMapGetter<Map<String, String>> getter;
@Mock private Sampler sampler1;
@Mock private Sampler sampler2;
@Mock private SpanExporter spanExporter1;
@Mock private SpanExporter spanExporter2;
@BeforeEach
void resetGlobal() {
GlobalOpenTelemetry.resetForTest();
}
@Test
void customize() {
Context extracted = Context.root().with(CONTEXT_KEY, "bear");
when(propagator2.extract(any(), any(), any())).thenReturn(extracted);
when(sampler2.shouldSample(any(), any(), any(), any(), any(), any()))
.thenReturn(SamplingResult.recordAndSample());
when(spanExporter2.export(any())).thenReturn(CompletableResultCode.ofSuccess());
when(spanExporter2.shutdown()).thenReturn(CompletableResultCode.ofSuccess());
AutoConfiguredOpenTelemetrySdkBuilder autoConfiguration =
AutoConfiguredOpenTelemetrySdk.builder()
.addPropagatorCustomizer(
(previous, config) -> {
assertThat(previous).isSameAs(W3CTraceContextPropagator.getInstance());
return propagator1;
})
.addPropagatorCustomizer(
(previous, config) -> {
assertThat(previous).isSameAs(propagator1);
return propagator2;
})
.addResourceCustomizer(
(resource, config) ->
resource.merge(Resource.builder().put("key2", "value2").build()))
.addSamplerCustomizer(
(previous, config) -> {
assertThat(previous).isEqualTo(Sampler.parentBased(Sampler.alwaysOn()));
return sampler1;
})
.addSamplerCustomizer(
(previous, config) -> {
assertThat(previous).isSameAs(sampler1);
return sampler2;
})
.addSpanExporterCustomizer(
(previous, config) -> {
assertThat(previous).isSameAs(SpanExporter.composite());
return spanExporter1;
})
.addSpanExporterCustomizer(
(previous, config) -> {
assertThat(previous).isSameAs(spanExporter1);
return spanExporter2;
})
.addPropertiesSupplier(() -> Collections.singletonMap("key", "valueUnused"))
.addPropertiesSupplier(() -> Collections.singletonMap("key", "value"))
.addPropertiesSupplier(() -> Collections.singletonMap("otel-key", "otel-value"))
.addPropertiesSupplier(
() -> Collections.singletonMap("otel.propagators", "tracecontext"))
.addPropertiesSupplier(() -> Collections.singletonMap("otel.metrics.exporter", "none"))
.addPropertiesSupplier(() -> Collections.singletonMap("otel.traces.exporter", "none"))
.addPropertiesSupplier(
() -> Collections.singletonMap("otel.service.name", "test-service"))
.setResultAsGlobal(false);
GlobalOpenTelemetry.set(OpenTelemetry.noop());
AutoConfiguredOpenTelemetrySdk autoConfigured = autoConfiguration.build();
assertThat(autoConfigured.getResource().getAttribute(ResourceAttributes.SERVICE_NAME))
.isEqualTo("test-service");
assertThat(autoConfigured.getResource().getAttribute(stringKey("key2"))).isEqualTo("value2");
assertThat(autoConfigured.getConfig().getString("key")).isEqualTo("value");
assertThat(autoConfigured.getConfig().getString("otel.key")).isEqualTo("otel-value");
OpenTelemetrySdk sdk = autoConfigured.getOpenTelemetrySdk();
// Verify setResultAsGlobal respected
assertThat(sdk).isNotSameAs(GlobalOpenTelemetry.get());
assertThat(
sdk.getPropagators()
.getTextMapPropagator()
.extract(Context.root(), Collections.emptyMap(), getter))
.isEqualTo(extracted);
sdk.getTracerProvider().get("test").spanBuilder("test").startSpan().end();
// Ensures the export happened.
sdk.getSdkTracerProvider().shutdown().join(10, TimeUnit.SECONDS);
}
}

View File

@ -17,7 +17,7 @@ class PropagatorConfigurationTest {
void defaultPropagators() {
ContextPropagators contextPropagators =
PropagatorConfiguration.configurePropagators(
DefaultConfigProperties.createForTest(Collections.emptyMap()));
DefaultConfigProperties.createForTest(Collections.emptyMap()), (a, unused) -> a);
assertThat(contextPropagators.getTextMapPropagator().fields())
.containsExactlyInAnyOrder("traceparent", "tracestate", "baggage");

View File

@ -5,21 +5,19 @@
package io.opentelemetry.sdk.autoconfigure;
import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@SuppressWarnings("deprecation") // Testing class which will be made package-private
@ExtendWith(MockitoExtension.class)
class ResourceTest {
@Mock ConfigProperties config;
@Test
void noResourceProviders() {
@ -30,10 +28,13 @@ class ResourceTest {
@Test
void customConfigResource() {
when(config.getString("otel.service.name")).thenReturn("test-service");
when(config.getMap("otel.resource.attributes")).thenReturn(singletonMap("food", "cheesecake"));
Map<String, String> props = new HashMap<>();
props.put("otel.service.name", "test-service");
props.put("otel.resource.attributes", "food=cheesecake");
assertThat(OpenTelemetryResourceAutoConfiguration.configureResource(config))
assertThat(
OpenTelemetryResourceAutoConfiguration.configureResource(
DefaultConfigProperties.get(props)))
.isEqualTo(
Resource.getDefault().toBuilder()
.put(ResourceAttributes.SERVICE_NAME, "test-service")

View File

@ -62,7 +62,10 @@ class TracerProviderConfigurationTest {
// are verified in other test sets like testFullConfig.
SdkTracerProvider tracerProvider =
TracerProviderConfiguration.configureTracerProvider(
resource, DefaultConfigProperties.createForTest(properties));
resource,
DefaultConfigProperties.createForTest(properties),
(a, unused) -> a,
(a, unused) -> a);
try {
assertThat(tracerProvider.getSampler()).isEqualTo(Sampler.alwaysOff());

View File

@ -29,7 +29,7 @@ class ConfigErrorTest {
@Test
@SetSystemProperty(key = "otel.propagators", value = "cat")
void invalidPropagator() {
assertThatThrownBy(OpenTelemetrySdkAutoConfiguration::initialize)
assertThatThrownBy(AutoConfiguredOpenTelemetrySdk::initialize)
.isInstanceOf(ConfigurationException.class)
.hasMessage(
"Unrecognized value for otel.propagators: cat. Make sure the artifact "
@ -40,7 +40,7 @@ class ConfigErrorTest {
@SetSystemProperty(key = "otel.traces.sampler", value = "traceidratio")
@SetSystemProperty(key = "otel.traces.sampler.arg", value = "bar")
void invalidTraceIdRatio() {
assertThatThrownBy(OpenTelemetrySdkAutoConfiguration::initialize)
assertThatThrownBy(AutoConfiguredOpenTelemetrySdk::initialize)
.isInstanceOf(ConfigurationException.class)
.hasMessage("Invalid value for property otel.traces.sampler.arg=bar. Must be a double.");
}
@ -49,7 +49,7 @@ class ConfigErrorTest {
@SetSystemProperty(key = "otel.traces.sampler", value = "parentbased_traceidratio")
@SetSystemProperty(key = "otel.traces.sampler.arg", value = "bar")
void invalidTraceIdRatioWithParent() {
assertThatThrownBy(OpenTelemetrySdkAutoConfiguration::initialize)
assertThatThrownBy(AutoConfiguredOpenTelemetrySdk::initialize)
.isInstanceOf(ConfigurationException.class)
.hasMessage("Invalid value for property otel.traces.sampler.arg=bar. Must be a double.");
}
@ -57,7 +57,7 @@ class ConfigErrorTest {
@Test
@SetSystemProperty(key = "otel.traces.sampler", value = "cat")
void invalidSampler() {
assertThatThrownBy(OpenTelemetrySdkAutoConfiguration::initialize)
assertThatThrownBy(AutoConfiguredOpenTelemetrySdk::initialize)
.isInstanceOf(ConfigurationException.class)
.hasMessage("Unrecognized value for otel.traces.sampler: cat");
}

View File

@ -30,7 +30,7 @@ public class ConfigurableSpanExporterTest {
DefaultConfigProperties.createForTest(
ImmutableMap.of("test.option", "true", "otel.traces.exporter", "testExporter"));
Map<String, SpanExporter> exportersByName =
SpanExporterConfiguration.configureSpanExporters(config);
SpanExporterConfiguration.configureSpanExporters(config, (a, unused) -> a);
assertThat(exportersByName)
.hasSize(1)
@ -47,7 +47,8 @@ public class ConfigurableSpanExporterTest {
DefaultConfigProperties.createForTest(
ImmutableMap.of("otel.traces.exporter", "otlp,otlp,logging"));
assertThatThrownBy(() -> SpanExporterConfiguration.configureSpanExporters(config))
assertThatThrownBy(
() -> SpanExporterConfiguration.configureSpanExporters(config, (a, unused) -> a))
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining("otel.traces.exporter contains duplicates: [otlp]");
}
@ -57,7 +58,8 @@ public class ConfigurableSpanExporterTest {
ConfigProperties config =
DefaultConfigProperties.createForTest(ImmutableMap.of("otel.traces.exporter", "otlp,none"));
assertThatThrownBy(() -> SpanExporterConfiguration.configureSpanExporters(config))
assertThatThrownBy(
() -> SpanExporterConfiguration.configureSpanExporters(config, (a, unused) -> a))
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining("otel.traces.exporter contains none along with other exporters");
}

View File

@ -173,6 +173,10 @@ class FullConfigTest {
.setKey("configured")
.setValue(AnyValue.newBuilder().setBoolValue(true).build())
.build(),
KeyValue.newBuilder()
.setKey("wrapped")
.setValue(AnyValue.newBuilder().setIntValue(1).build())
.build(),
KeyValue.newBuilder()
.setKey("cat")
.setValue(AnyValue.newBuilder().setStringValue("meow").build())

View File

@ -11,6 +11,7 @@ import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import org.junit.jupiter.api.Test;
@SuppressWarnings("deprecation") // Testing class which will be made package-private
class ResourceTest {
@Test

View File

@ -0,0 +1,52 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.autoconfigure;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.trace.data.DelegatingSpanData;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.util.Collection;
import java.util.stream.Collectors;
public class SpanExporterCustomizer implements AutoConfigurationCustomizerProvider {
@Override
public void customize(AutoConfigurationCustomizer autoConfiguration) {
autoConfiguration.addSpanExporterCustomizer(
(delegate, config) ->
new SpanExporter() {
@Override
public CompletableResultCode export(Collection<SpanData> spans) {
return delegate.export(
spans.stream()
.map(
span ->
new DelegatingSpanData(span) {
@Override
public Attributes getAttributes() {
return span.getAttributes().toBuilder()
.put("wrapped", config.getInt("otel.test.wrapped"))
.build();
}
})
.collect(Collectors.toList()));
}
@Override
public CompletableResultCode flush() {
return delegate.flush();
}
@Override
public CompletableResultCode shutdown() {
return delegate.shutdown();
}
});
}
}

View File

@ -24,7 +24,7 @@ class OpenTelemetrySdkAutoConfigurationTest {
@Test
void initializeAndGet() {
OpenTelemetrySdk sdk = OpenTelemetrySdkAutoConfiguration.initialize();
OpenTelemetrySdk sdk = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk();
assertThat(GlobalOpenTelemetry.get())
// ObfuscatedOpenTelemetry
.extracting("delegate")
@ -33,7 +33,11 @@ class OpenTelemetrySdkAutoConfigurationTest {
@Test
void initializeAndGet_noGlobal() {
OpenTelemetrySdk sdk = OpenTelemetrySdkAutoConfiguration.initialize(false);
OpenTelemetrySdk sdk =
AutoConfiguredOpenTelemetrySdk.builder()
.setResultAsGlobal(false)
.build()
.getOpenTelemetrySdk();
// TODO: calling get() will call initialize() again and autoconfigure another instance of the
// SDK; in that case the get() method will return OpenTelemetrySdk and not
// ObfuscatedOpenTelemetry

View File

@ -61,7 +61,7 @@ class JaegerConfigTest {
System.setProperty("otel.exporter.jaeger.endpoint", endpoint);
OpenTelemetrySdkAutoConfiguration.initialize();
AutoConfiguredOpenTelemetrySdk.initialize();
GlobalOpenTelemetry.get().getTracer("test").spanBuilder("test").startSpan().end();

View File

@ -33,7 +33,7 @@ class PrometheusTest {
}
System.setProperty("otel.exporter.prometheus.host", "127.0.0.1");
System.setProperty("otel.exporter.prometheus.port", String.valueOf(port));
OpenTelemetrySdkAutoConfiguration.initialize();
AutoConfiguredOpenTelemetrySdk.initialize();
GlobalMeterProvider.get()
.get("test")

View File

@ -1,24 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.resources;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.sdk.autoconfigure.OpenTelemetryResourceAutoConfiguration;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import org.junit.jupiter.api.Test;
class ResourceDisabledByEnvTest {
@Test
void osAndProcessDisabled() {
Resource resource = OpenTelemetryResourceAutoConfiguration.configureResource();
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE)).isNull();
assertThat(resource.getAttribute(ResourceAttributes.PROCESS_PID)).isNull();
assertThat(resource.getAttribute(ResourceAttributes.PROCESS_RUNTIME_NAME)).isNotNull();
}
}

View File

@ -1,24 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.resources;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.sdk.autoconfigure.OpenTelemetryResourceAutoConfiguration;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import org.junit.jupiter.api.Test;
class ResourceDisabledByPropertyTest {
@Test
void osAndProcessDisabled() {
Resource resource = OpenTelemetryResourceAutoConfiguration.configureResource();
assertThat(resource.getAttribute(ResourceAttributes.OS_TYPE)).isNull();
assertThat(resource.getAttribute(ResourceAttributes.PROCESS_PID)).isNull();
assertThat(resource.getAttribute(ResourceAttributes.PROCESS_RUNTIME_NAME)).isNotNull();
}
}

View File

@ -54,7 +54,7 @@ class ZipkinConfigTest {
System.setProperty("otel.exporter.zipkin.endpoint", "http://" + endpoint + "/api/v2/spans");
System.setProperty("otel.exporter.zipkin.timeout", "5s");
OpenTelemetrySdkAutoConfiguration.initialize();
AutoConfiguredOpenTelemetrySdk.initialize();
GlobalOpenTelemetry.get().getTracer("test").spanBuilder("test").startSpan().end();