diff --git a/sdk-autoconfigure-support/build.gradle.kts b/sdk-autoconfigure-support/build.gradle.kts index c2948406f7e1..d82b1b6c2182 100644 --- a/sdk-autoconfigure-support/build.gradle.kts +++ b/sdk-autoconfigure-support/build.gradle.kts @@ -7,6 +7,8 @@ group = "io.opentelemetry.instrumentation" dependencies { api("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") + compileOnly("io.opentelemetry:opentelemetry-sdk-extension-incubator") + testImplementation("io.opentelemetry:opentelemetry-sdk-extension-incubator") compileOnly("com.google.code.findbugs:annotations") testCompileOnly("com.google.code.findbugs:annotations") diff --git a/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/thread/internal/ThreadDetailsComponentProvider.java b/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/thread/internal/ThreadDetailsComponentProvider.java new file mode 100644 index 000000000000..9f63ef6326a5 --- /dev/null +++ b/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/thread/internal/ThreadDetailsComponentProvider.java @@ -0,0 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.thread.internal; + +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.trace.SpanProcessor; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class ThreadDetailsComponentProvider implements ComponentProvider { + @Override + public String getName() { + return "thread_details"; + } + + @Override + public SpanProcessor create(DeclarativeConfigProperties config) { + return new AddThreadDetailsSpanProcessor(); + } + + @Override + public Class getType() { + return SpanProcessor.class; + } +} diff --git a/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/thread/internal/ThreadDetailsCustomizerProvider.java b/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/thread/internal/ThreadDetailsCustomizerProvider.java new file mode 100644 index 000000000000..853780e04554 --- /dev/null +++ b/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/thread/internal/ThreadDetailsCustomizerProvider.java @@ -0,0 +1,48 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.thread.internal; + +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizer; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class ThreadDetailsCustomizerProvider implements DeclarativeConfigurationCustomizerProvider { + @Override + public void customize(DeclarativeConfigurationCustomizer customizer) { + customizer.addModelCustomizer( + model -> { + TracerProviderModel tracerProvider = model.getTracerProvider(); + if (tracerProvider != null && isEnabled(model)) { + tracerProvider + .getProcessors() + .add(new SpanProcessorModel().withAdditionalProperty("thread_details", null)); + } + + return model; + }); + } + + private static boolean isEnabled(OpenTelemetryConfigurationModel model) { + DeclarativeConfigProperties properties = + SdkConfigProvider.create(model).getInstrumentationConfig(); + if (properties == null) { + return false; + } + DeclarativeConfigProperties java = + properties.getStructured("java", DeclarativeConfigProperties.empty()); + + return java.getStructured("thread_details", DeclarativeConfigProperties.empty()) + .getBoolean("enabled", false); + } +} diff --git a/sdk-autoconfigure-support/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider b/sdk-autoconfigure-support/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider new file mode 100644 index 000000000000..ff5788b43774 --- /dev/null +++ b/sdk-autoconfigure-support/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider @@ -0,0 +1 @@ +io.opentelemetry.instrumentation.thread.internal.ThreadDetailsComponentProvider diff --git a/sdk-autoconfigure-support/src/main/resources/META-INF/services/io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider b/sdk-autoconfigure-support/src/main/resources/META-INF/services/io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider new file mode 100644 index 000000000000..5f285454fb4f --- /dev/null +++ b/sdk-autoconfigure-support/src/main/resources/META-INF/services/io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider @@ -0,0 +1 @@ +io.opentelemetry.instrumentation.thread.internal.ThreadDetailsCustomizerProvider diff --git a/sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/thread/internal/ThreadDetailsConfigurationCustomizerProviderTest.java b/sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/thread/internal/ThreadDetailsConfigurationCustomizerProviderTest.java new file mode 100644 index 000000000000..bf63869e2dfa --- /dev/null +++ b/sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/thread/internal/ThreadDetailsConfigurationCustomizerProviderTest.java @@ -0,0 +1,56 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.thread.internal; + +import static java.util.Collections.singletonMap; +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationBuilder; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.InstrumentationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; +import org.junit.jupiter.api.Test; + +class ThreadDetailsConfigurationCustomizerProviderTest { + + static final String PROCESSOR = "AddThreadDetailsSpanProcessor"; + + @Test + void disabledByDefault() { + OpenTelemetryConfigurationModel model = modelWithTracer(); + + try (OpenTelemetrySdk sdk = DeclarativeConfiguration.create(model)) { + assertThat(sdk.toString()).doesNotContain(PROCESSOR); + } + } + + @Test + void enabled() { + OpenTelemetryConfigurationModel model = + modelWithTracer() + .withInstrumentationDevelopment( + new InstrumentationModel() + .withJava( + new ExperimentalLanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "thread_details", singletonMap("enabled", true)))); + + try (OpenTelemetrySdk sdk = DeclarativeConfiguration.create(model)) { + assertThat(sdk.toString()).containsOnlyOnce(PROCESSOR); + } + } + + private static OpenTelemetryConfigurationModel modelWithTracer() { + return new DeclarativeConfigurationBuilder() + .customizeModel( + new OpenTelemetryConfigurationModel() + .withFileFormat("1.0-rc.1") + .withTracerProvider(new TracerProviderModel())); + } +}