From 7d80a998460154c93a5a2bcc5eb1fdc90318aab2 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Mon, 6 Jun 2022 11:23:14 -0500 Subject: [PATCH] Add experimental option to disable autoconfigured opentelemetry SDK (#4489) * Add experimental option to disable autoconfigured opentelemetry SDK * Add AutoConfiguredOpenTelemetrySdk#isSdkEnabled() * Remove isSdkEnabled() --- sdk-extensions/autoconfigure/README.md | 8 ++ .../AutoConfiguredOpenTelemetrySdk.java | 9 +- ...AutoConfiguredOpenTelemetrySdkBuilder.java | 106 +++++++++--------- .../AutoConfiguredOpenTelemetrySdkTest.java | 62 ++++++++++ 4 files changed, 132 insertions(+), 53 deletions(-) diff --git a/sdk-extensions/autoconfigure/README.md b/sdk-extensions/autoconfigure/README.md index 21b9fcee0d7..50dfe826236 100644 --- a/sdk-extensions/autoconfigure/README.md +++ b/sdk-extensions/autoconfigure/README.md @@ -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: diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java index 3576236a7bc..a1a8c58fe9b 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdk.java @@ -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; @@ -24,8 +25,7 @@ public abstract class AutoConfiguredOpenTelemetrySdk { * Returns an {@link AutoConfiguredOpenTelemetrySdk} automatically initialized through recognized * system properties and environment variables. * - *

This will automatically set the resulting SDK as the {@link - * io.opentelemetry.api.GlobalOpenTelemetry} instance. + *

This will automatically set the resulting SDK as the {@link GlobalOpenTelemetry} instance. */ public static AutoConfiguredOpenTelemetrySdk initialize() { return builder().build(); @@ -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. */ diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java index b95de992d2e..4f4b50a457b 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java @@ -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; @@ -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 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 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); diff --git a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java index 88d0777a84a..c0055190de7 100644 --- a/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java +++ b/sdk-extensions/autoconfigure/src/test/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkTest.java @@ -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; @@ -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; @@ -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; @@ -273,6 +280,61 @@ private static Supplier> disableExportPropertySupplier() { return () -> props; } + @Test + void disableSdk() { + BiFunction + traceCustomizer = + spy( + new BiFunction< + SdkTracerProviderBuilder, ConfigProperties, SdkTracerProviderBuilder>() { + @Override + public SdkTracerProviderBuilder apply( + SdkTracerProviderBuilder builder, ConfigProperties config) { + return builder; + } + }); + BiFunction + metricCustomizer = + spy( + new BiFunction< + SdkMeterProviderBuilder, ConfigProperties, SdkMeterProviderBuilder>() { + @Override + public SdkMeterProviderBuilder apply( + SdkMeterProviderBuilder builder, ConfigProperties config) { + return builder; + } + }); + BiFunction + 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();