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:
parent
c4c2e6c9db
commit
1e073fcff2
|
|
@ -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 "
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
io.opentelemetry.sdk.autoconfigure.SpanExporterCustomizer
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue