Skip to content

Commit

Permalink
Add experimental option to disable autoconfigured opentelemetry SDK (#…
Browse files Browse the repository at this point in the history
…4489)

* Add experimental option to disable autoconfigured opentelemetry SDK

* Add AutoConfiguredOpenTelemetrySdk#isSdkEnabled()

* Remove isSdkEnabled()
  • Loading branch information
jack-berg committed Jun 6, 2022
1 parent d9c8e70 commit 7d80a99
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 53 deletions.
8 changes: 8 additions & 0 deletions sdk-extensions/autoconfigure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ and not something we can control. If you require logging during shutdown hooks,
that might shut itself down in a shutdown hook, thus suppressing your log messages. See this [JDK bug](https://bugs.openjdk.java.net/browse/JDK-8161253)
for more details.

## Disabling OpenTelemetrySdk

The OpenTelemetry SDK can be disabled entirely. If disabled, `AutoConfiguredOpenTelemetrySdk#isSdkEnabled()` will return `false`, and `GlobalOpenTelemetry` will be set to `OpenTelemetrySdk.builder().build()`.

| System property | Environment variable | Purpose |
|-------------------------------|-------------------------------|----------------------------------------------------------------|
| otel.experimental.sdk.enabled | OTEL_EXPERIMENTAL_SDK_ENABLED | If `false`, disable the OpenTelemetry SDK. Defaults to `true`. |

## Exporters

The following configuration properties are common to all exporters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package io.opentelemetry.sdk.autoconfigure;

import com.google.auto.value.AutoValue;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.resources.Resource;
Expand All @@ -24,8 +25,7 @@ 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.
* <p>This will automatically set the resulting SDK as the {@link GlobalOpenTelemetry} instance.
*/
public static AutoConfiguredOpenTelemetrySdk initialize() {
return builder().build();
Expand All @@ -44,7 +44,10 @@ static AutoConfiguredOpenTelemetrySdk create(
return new AutoValue_AutoConfiguredOpenTelemetrySdk(sdk, resource, config);
}

/** Returns the {@link OpenTelemetrySdk} that was auto-configured. */
/**
* Returns the {@link OpenTelemetrySdk} that was auto-configured, or {@code null} if the SDK has
* been disabled.
*/
public abstract OpenTelemetrySdk getOpenTelemetrySdk();

/** Returns the {@link Resource} that was auto-configured. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
Expand Down Expand Up @@ -307,63 +308,68 @@ public AutoConfiguredOpenTelemetrySdk build() {
Resource resource =
ResourceConfiguration.configureResource(config, serviceClassLoader, resourceCustomizer);

SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder();
meterProviderBuilder.setResource(resource);
MeterProviderConfiguration.configureMeterProvider(
meterProviderBuilder, config, serviceClassLoader, metricExporterCustomizer);
meterProviderBuilder = meterProviderCustomizer.apply(meterProviderBuilder, config);
SdkMeterProvider meterProvider = meterProviderBuilder.build();

SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder();
tracerProviderBuilder.setResource(resource);
TracerProviderConfiguration.configureTracerProvider(
tracerProviderBuilder,
config,
serviceClassLoader,
meterProvider,
spanExporterCustomizer,
samplerCustomizer);
tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config);
SdkTracerProvider tracerProvider = tracerProviderBuilder.build();

SdkLogEmitterProviderBuilder logEmitterProviderBuilder = SdkLogEmitterProvider.builder();
logEmitterProviderBuilder.setResource(resource);
LogEmitterProviderConfiguration.configureLogEmitterProvider(
logEmitterProviderBuilder, config, meterProvider, logExporterCustomizer);
logEmitterProviderBuilder =
logEmitterProviderCustomizer.apply(logEmitterProviderBuilder, config);
SdkLogEmitterProvider logEmitterProvider = logEmitterProviderBuilder.build();

if (registerShutdownHook) {
Runtime.getRuntime()
.addShutdownHook(
new Thread(
() -> {
List<CompletableResultCode> shutdown = new ArrayList<>();
shutdown.add(tracerProvider.shutdown());
shutdown.add(meterProvider.shutdown());
shutdown.add(logEmitterProvider.shutdown());
CompletableResultCode.ofAll(shutdown).join(10, TimeUnit.SECONDS);
}));
}
OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder().build();
boolean sdkEnabled =
Optional.ofNullable(config.getBoolean("otel.experimental.sdk.enabled")).orElse(true);
if (sdkEnabled) {
SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder();
meterProviderBuilder.setResource(resource);
MeterProviderConfiguration.configureMeterProvider(
meterProviderBuilder, config, serviceClassLoader, metricExporterCustomizer);
meterProviderBuilder = meterProviderCustomizer.apply(meterProviderBuilder, config);
SdkMeterProvider meterProvider = meterProviderBuilder.build();

SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder();
tracerProviderBuilder.setResource(resource);
TracerProviderConfiguration.configureTracerProvider(
tracerProviderBuilder,
config,
serviceClassLoader,
meterProvider,
spanExporterCustomizer,
samplerCustomizer);
tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config);
SdkTracerProvider tracerProvider = tracerProviderBuilder.build();

SdkLogEmitterProviderBuilder logEmitterProviderBuilder = SdkLogEmitterProvider.builder();
logEmitterProviderBuilder.setResource(resource);
LogEmitterProviderConfiguration.configureLogEmitterProvider(
logEmitterProviderBuilder, config, meterProvider, logExporterCustomizer);
logEmitterProviderBuilder =
logEmitterProviderCustomizer.apply(logEmitterProviderBuilder, config);
SdkLogEmitterProvider logEmitterProvider = logEmitterProviderBuilder.build();

if (registerShutdownHook) {
Runtime.getRuntime()
.addShutdownHook(
new Thread(
() -> {
List<CompletableResultCode> shutdown = new ArrayList<>();
shutdown.add(tracerProvider.shutdown());
shutdown.add(meterProvider.shutdown());
shutdown.add(logEmitterProvider.shutdown());
CompletableResultCode.ofAll(shutdown).join(10, TimeUnit.SECONDS);
}));
}

ContextPropagators propagators =
PropagatorConfiguration.configurePropagators(
config, serviceClassLoader, propagatorCustomizer);
ContextPropagators propagators =
PropagatorConfiguration.configurePropagators(
config, serviceClassLoader, propagatorCustomizer);

OpenTelemetrySdkBuilder sdkBuilder =
OpenTelemetrySdk.builder()
.setTracerProvider(tracerProvider)
.setLogEmitterProvider(logEmitterProvider)
.setMeterProvider(meterProvider)
.setPropagators(propagators);
OpenTelemetrySdkBuilder sdkBuilder =
OpenTelemetrySdk.builder()
.setTracerProvider(tracerProvider)
.setLogEmitterProvider(logEmitterProvider)
.setMeterProvider(meterProvider)
.setPropagators(propagators);

OpenTelemetrySdk openTelemetrySdk = sdkBuilder.build();
openTelemetrySdk = sdkBuilder.build();
}

if (setResultAsGlobal) {
GlobalOpenTelemetry.set(openTelemetrySdk);
logger.log(
Level.FINE, "Global OpenTelemetrySdk set to {0} by autoconfiguration", openTelemetrySdk);
Level.FINE, "Global OpenTelemetry set to {0} by autoconfiguration", openTelemetrySdk);
}

return AutoConfiguredOpenTelemetrySdk.create(openTelemetrySdk, resource, config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
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.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

Expand All @@ -22,15 +24,19 @@
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.logs.LogProcessor;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import io.opentelemetry.sdk.logs.SdkLogEmitterProviderBuilder;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
import io.opentelemetry.sdk.metrics.export.MetricReader;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
import io.opentelemetry.sdk.trace.IdGenerator;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
import io.opentelemetry.sdk.trace.export.SpanExporter;
Expand All @@ -41,6 +47,7 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -273,6 +280,61 @@ private static Supplier<Map<String, String>> disableExportPropertySupplier() {
return () -> props;
}

@Test
void disableSdk() {
BiFunction<SdkTracerProviderBuilder, ConfigProperties, SdkTracerProviderBuilder>
traceCustomizer =
spy(
new BiFunction<
SdkTracerProviderBuilder, ConfigProperties, SdkTracerProviderBuilder>() {
@Override
public SdkTracerProviderBuilder apply(
SdkTracerProviderBuilder builder, ConfigProperties config) {
return builder;
}
});
BiFunction<SdkMeterProviderBuilder, ConfigProperties, SdkMeterProviderBuilder>
metricCustomizer =
spy(
new BiFunction<
SdkMeterProviderBuilder, ConfigProperties, SdkMeterProviderBuilder>() {
@Override
public SdkMeterProviderBuilder apply(
SdkMeterProviderBuilder builder, ConfigProperties config) {
return builder;
}
});
BiFunction<SdkLogEmitterProviderBuilder, ConfigProperties, SdkLogEmitterProviderBuilder>
logCustomizer =
spy(
new BiFunction<
SdkLogEmitterProviderBuilder,
ConfigProperties,
SdkLogEmitterProviderBuilder>() {
@Override
public SdkLogEmitterProviderBuilder apply(
SdkLogEmitterProviderBuilder builder, ConfigProperties config) {
return builder;
}
});

AutoConfiguredOpenTelemetrySdk autoConfiguredSdk =
AutoConfiguredOpenTelemetrySdk.builder()
.addPropertiesSupplier(
() -> Collections.singletonMap("otel.experimental.sdk.enabled", "false"))
.addTracerProviderCustomizer(traceCustomizer)
.addMeterProviderCustomizer(metricCustomizer)
.addLogEmitterProviderCustomizer(logCustomizer)
.build();

assertThat(autoConfiguredSdk.getOpenTelemetrySdk()).isInstanceOf(OpenTelemetrySdk.class);

// When the SDK is disabled, configuration is skipped and none of the customizers are called
verify(traceCustomizer, never()).apply(any(), any());
verify(metricCustomizer, never()).apply(any(), any());
verify(logCustomizer, never()).apply(any(), any());
}

@Test
void tracerProviderCustomizer() {
InMemorySpanExporter spanExporter = InMemorySpanExporter.create();
Expand Down

0 comments on commit 7d80a99

Please sign in to comment.