diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LoggingExporterAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LoggingExporterAutoConfiguration.java new file mode 100644 index 000000000000..2d35c4bba52f --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LoggingExporterAutoConfiguration.java @@ -0,0 +1,38 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.logging; + +import io.opentelemetry.exporter.logging.LoggingSpanExporter; +import io.opentelemetry.instrumentation.internal.logging.LoggingSpanExporterConfigurer; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; +import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +@Conditional(SdkEnabled.class) +// for backward compatibility with declarative configuration +@ConditionalOnProperty(name = "otel.debug", havingValue = "true") +@ConditionalOnClass(LoggingSpanExporter.class) +@Configuration +public class LoggingExporterAutoConfiguration { + + @Bean + public AutoConfigurationCustomizerProvider loggingOtelCustomizer() { + return p -> + p.addTracerProviderCustomizer( + (builder, config) -> { + LoggingSpanExporterConfigurer.enableLoggingExporter(builder, config); + return builder; + }); + } +} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/thread/ThreadDetailsAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/thread/ThreadDetailsAutoConfiguration.java new file mode 100644 index 000000000000..fa28977133c6 --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/thread/ThreadDetailsAutoConfiguration.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.thread; + +import io.opentelemetry.instrumentation.internal.thread.AddThreadDetailsSpanProcessor; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; +import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +@ConditionalOnEnabledInstrumentation(module = "common.thread-details", enabledByDefault = false) +@Configuration +@SuppressWarnings("OtelPrivateConstructorForUtilityClass") +public class ThreadDetailsAutoConfiguration { + + @Bean + public AutoConfigurationCustomizerProvider threadDetailOtelCustomizer() { + return p -> + p.addTracerProviderCustomizer( + (builder, config) -> { + builder.addSpanProcessor(new AddThreadDetailsSpanProcessor()); + return builder; + }); + } +} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigProperties.java index 05efa521d59a..5afa853ab080 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigProperties.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigProperties.java @@ -7,7 +7,7 @@ import io.opentelemetry.api.internal.ConfigUtil; import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; -import io.opentelemetry.instrumentation.resources.ResourceProviderPropertiesCustomizer; +import io.opentelemetry.instrumentation.internal.resources.ResourceProviderPropertiesCustomizer; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.time.Duration; diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index cb026785d354..aa3f1300ec31 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -13,7 +13,8 @@ io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.w io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.scheduling.SpringSchedulingInstrumentationAutoConfiguration,\ io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics.RuntimeMetricsAutoConfiguration,\ io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics.Java8RuntimeMetricsProvider,\ -io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics.Java17RuntimeMetricsProvider +io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics.Java17RuntimeMetricsProvider,\ +io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.thread.ThreadDetailsAutoConfiguration org.springframework.context.ApplicationListener=\ io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.logging.LogbackAppenderApplicationListener diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 2392e0c35592..e8c5e8a83d7a 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -14,3 +14,4 @@ io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.s io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics.RuntimeMetricsAutoConfiguration io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics.Java8RuntimeMetricsProvider io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics.Java17RuntimeMetricsProvider +io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.thread.ThreadDetailsAutoConfiguration diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java index b37f074c34ac..4f798b21ab77 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java @@ -100,7 +100,7 @@ void specialListProperties() { "io.opentelemetry.contrib.aws.resource.LambdaResourceProvider", "io.opentelemetry.contrib.gcp.resource.GCPResourceProvider", "io.opentelemetry.contrib.cloudfoundry.resources.CloudFoundryResourceProvider", - "io.opentelemetry.instrumentation.resources.ResourceProviderPropertiesCustomizerTest$Provider"); + "io.opentelemetry.instrumentation.internal.resources.ResourceProviderPropertiesCustomizerTest$Provider"); })); } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentTracerProviderConfigurer.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentTracerProviderConfigurer.java index 71223c79573c..8c1260fbc4dd 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentTracerProviderConfigurer.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentTracerProviderConfigurer.java @@ -5,18 +5,17 @@ package io.opentelemetry.javaagent.tooling; +import static io.opentelemetry.instrumentation.internal.logging.LoggingSpanExporterConfigurer.enableLoggingExporter; import static io.opentelemetry.javaagent.tooling.AgentInstaller.JAVAAGENT_ENABLED_CONFIG; -import static java.util.Collections.emptyList; import com.google.auto.service.AutoService; import com.google.errorprone.annotations.CanIgnoreReturnValue; -import io.opentelemetry.exporter.logging.LoggingSpanExporter; +import io.opentelemetry.instrumentation.internal.thread.AddThreadDetailsSpanProcessor; import io.opentelemetry.javaagent.tooling.config.AgentConfig; 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.trace.SdkTracerProviderBuilder; -import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; @AutoService(AutoConfigurationCustomizerProvider.class) public class AgentTracerProviderConfigurer implements AutoConfigurationCustomizerProvider { @@ -40,22 +39,10 @@ private static SdkTracerProviderBuilder configure( sdkTracerProviderBuilder.addSpanProcessor(new AddThreadDetailsSpanProcessor()); } - maybeEnableLoggingExporter(sdkTracerProviderBuilder, config); - - return sdkTracerProviderBuilder; - } - - private static void maybeEnableLoggingExporter( - SdkTracerProviderBuilder builder, ConfigProperties config) { if (AgentConfig.isDebugModeEnabled(config)) { - // don't install another instance if the user has already explicitly requested it. - if (loggingExporterIsNotAlreadyConfigured(config)) { - builder.addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())); - } + enableLoggingExporter(sdkTracerProviderBuilder, config); } - } - private static boolean loggingExporterIsNotAlreadyConfigured(ConfigProperties config) { - return !config.getList("otel.traces.exporter", emptyList()).contains("logging"); + return sdkTracerProviderBuilder; } } diff --git a/javaagent-tooling/src/test/groovy/io/opentelemetry/javaagent/tooling/AddThreadDetailsSpanProcessorTest.groovy b/javaagent-tooling/src/test/groovy/io/opentelemetry/javaagent/tooling/AddThreadDetailsSpanProcessorTest.groovy deleted file mode 100644 index d3a8a8c933db..000000000000 --- a/javaagent-tooling/src/test/groovy/io/opentelemetry/javaagent/tooling/AddThreadDetailsSpanProcessorTest.groovy +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.tooling - -import io.opentelemetry.context.Context -import io.opentelemetry.sdk.trace.ReadWriteSpan -import io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes -import spock.lang.Specification - -class AddThreadDetailsSpanProcessorTest extends Specification { - def span = Mock(ReadWriteSpan) - - def processor = new AddThreadDetailsSpanProcessor() - - def "should require onStart call"() { - expect: - processor.isStartRequired() - } - - def "should set thread attributes on span start"() { - given: - def currentThreadName = Thread.currentThread().name - def currentThreadId = Thread.currentThread().id - - when: - processor.onStart(Context.root(), span) - - then: - 1 * span.setAttribute(ThreadIncubatingAttributes.THREAD_ID, currentThreadId) - 1 * span.setAttribute(ThreadIncubatingAttributes.THREAD_NAME, currentThreadName) - } -} diff --git a/sdk-autoconfigure-support/build.gradle.kts b/sdk-autoconfigure-support/build.gradle.kts index 7a2e5e185912..afeb4e6274dc 100644 --- a/sdk-autoconfigure-support/build.gradle.kts +++ b/sdk-autoconfigure-support/build.gradle.kts @@ -6,8 +6,10 @@ plugins { group = "io.opentelemetry.instrumentation" dependencies { + compileOnly("io.opentelemetry:opentelemetry-exporter-logging") api("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") compileOnly("com.google.code.findbugs:annotations") testCompileOnly("com.google.code.findbugs:annotations") + testImplementation(project(":testing-common")) } diff --git a/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/internal/logging/LoggingSpanExporterConfigurer.java b/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/internal/logging/LoggingSpanExporterConfigurer.java new file mode 100644 index 000000000000..3c3d1cbe3eed --- /dev/null +++ b/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/internal/logging/LoggingSpanExporterConfigurer.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.internal.logging; + +import static java.util.Collections.emptyList; + +import io.opentelemetry.exporter.logging.LoggingSpanExporter; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class LoggingSpanExporterConfigurer { + + private LoggingSpanExporterConfigurer() {} + + public static void enableLoggingExporter( + SdkTracerProviderBuilder builder, ConfigProperties config) { + // don't install another instance if the user has already explicitly requested it. + if (loggingExporterIsNotAlreadyConfigured(config)) { + builder.addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())); + } + } + + private static boolean loggingExporterIsNotAlreadyConfigured(ConfigProperties config) { + return !config.getList("otel.traces.exporter", emptyList()).contains("logging"); + } +} diff --git a/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/resources/ResourceProviderPropertiesCustomizer.java b/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/internal/resources/ResourceProviderPropertiesCustomizer.java similarity index 93% rename from sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/resources/ResourceProviderPropertiesCustomizer.java rename to sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/internal/resources/ResourceProviderPropertiesCustomizer.java index d9242de19f79..f6647ccc19ab 100644 --- a/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/resources/ResourceProviderPropertiesCustomizer.java +++ b/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/internal/resources/ResourceProviderPropertiesCustomizer.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.resources; +package io.opentelemetry.instrumentation.internal.resources; import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer; import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; @@ -17,6 +17,10 @@ import java.util.Set; import javax.annotation.Nullable; +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ public class ResourceProviderPropertiesCustomizer implements AutoConfigurationCustomizerProvider { private static final Map DISABLED_BY_DEFAULT_RESOURCE_PROVIDERS = new HashMap<>(); @@ -49,7 +53,7 @@ public class ResourceProviderPropertiesCustomizer implements AutoConfigurationCu "cloudfoundry"); // for testing DISABLED_BY_DEFAULT_RESOURCE_PROVIDERS.put( - "io.opentelemetry.instrumentation.resources.ResourceProviderPropertiesCustomizerTest$Provider", + "io.opentelemetry.instrumentation.internal.resources.ResourceProviderPropertiesCustomizerTest$Provider", "test"); } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AddThreadDetailsSpanProcessor.java b/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/internal/thread/AddThreadDetailsSpanProcessor.java similarity index 58% rename from javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AddThreadDetailsSpanProcessor.java rename to sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/internal/thread/AddThreadDetailsSpanProcessor.java index 496d8580ff79..43b12fa6c141 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AddThreadDetailsSpanProcessor.java +++ b/sdk-autoconfigure-support/src/main/java/io/opentelemetry/instrumentation/internal/thread/AddThreadDetailsSpanProcessor.java @@ -3,22 +3,33 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.tooling; +package io.opentelemetry.instrumentation.internal.thread; +import static io.opentelemetry.api.common.AttributeKey.longKey; +import static io.opentelemetry.api.common.AttributeKey.stringKey; + +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.ReadWriteSpan; import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SpanProcessor; -import io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes; +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ public class AddThreadDetailsSpanProcessor implements SpanProcessor { + // attributes are not stable yet + public static final AttributeKey THREAD_ID = longKey("thread.id"); + public static final AttributeKey THREAD_NAME = stringKey("thread.name"); + @Override public void onStart(Context context, ReadWriteSpan span) { Thread currentThread = Thread.currentThread(); - span.setAttribute(ThreadIncubatingAttributes.THREAD_ID, currentThread.getId()); - span.setAttribute(ThreadIncubatingAttributes.THREAD_NAME, currentThread.getName()); + span.setAttribute(THREAD_ID, currentThread.getId()); + span.setAttribute(THREAD_NAME, currentThread.getName()); } @Override diff --git a/sdk-autoconfigure-support/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider b/sdk-autoconfigure-support/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider index 3f8716ab23aa..f52cd7078755 100644 --- a/sdk-autoconfigure-support/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider +++ b/sdk-autoconfigure-support/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider @@ -1 +1 @@ -io.opentelemetry.instrumentation.resources.ResourceProviderPropertiesCustomizer +io.opentelemetry.instrumentation.internal.resources.ResourceProviderPropertiesCustomizer diff --git a/sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/resources/ResourceProviderPropertiesCustomizerTest.java b/sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/internal/resources/ResourceProviderPropertiesCustomizerTest.java similarity index 96% rename from sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/resources/ResourceProviderPropertiesCustomizerTest.java rename to sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/internal/resources/ResourceProviderPropertiesCustomizerTest.java index 18928d915917..672e8ad69186 100644 --- a/sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/resources/ResourceProviderPropertiesCustomizerTest.java +++ b/sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/internal/resources/ResourceProviderPropertiesCustomizerTest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.resources; +package io.opentelemetry.instrumentation.internal.resources; import static org.assertj.core.api.Assertions.assertThat; @@ -58,7 +58,7 @@ private EnabledTestCase( @TestFactory Stream enabledTestCases() { String className = - "io.opentelemetry.instrumentation.resources.ResourceProviderPropertiesCustomizerTest$Provider"; + "io.opentelemetry.instrumentation.internal.resources.ResourceProviderPropertiesCustomizerTest$Provider"; return Stream.of( new EnabledTestCase( "explicitEnabled", true, Collections.emptySet(), Collections.emptySet(), true), diff --git a/sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/internal/thread/AddThreadDetailsSpanProcessorTest.java b/sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/internal/thread/AddThreadDetailsSpanProcessorTest.java new file mode 100644 index 000000000000..29da26fb0bbd --- /dev/null +++ b/sdk-autoconfigure-support/src/test/java/io/opentelemetry/instrumentation/internal/thread/AddThreadDetailsSpanProcessorTest.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.internal.thread; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; +import io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes; +import org.junit.jupiter.api.Test; + +class AddThreadDetailsSpanProcessorTest { + + private final ReadWriteSpan span = mock(ReadWriteSpan.class); + + private final SpanProcessor spanProcessor = new AddThreadDetailsSpanProcessor(); + + @Test + void onStart() { + assertThat(spanProcessor.isStartRequired()).isTrue(); + } + + @Test + void setThreadAttributes() { + Thread thread = Thread.currentThread(); + spanProcessor.onStart(Context.root(), span); + + verify(span).setAttribute(ThreadIncubatingAttributes.THREAD_ID, thread.getId()); + verify(span).setAttribute(ThreadIncubatingAttributes.THREAD_NAME, thread.getName()); + verifyNoMoreInteractions(span); + } +} diff --git a/sdk-autoconfigure-support/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider b/sdk-autoconfigure-support/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider index 243cb5615b57..3c09c998c9c7 100644 --- a/sdk-autoconfigure-support/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider +++ b/sdk-autoconfigure-support/src/test/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider @@ -1 +1 @@ -io.opentelemetry.instrumentation.resources.ResourceProviderPropertiesCustomizerTest$Provider +io.opentelemetry.instrumentation.internal.resources.ResourceProviderPropertiesCustomizerTest$Provider diff --git a/smoke-tests-otel-starter/spring-boot-2/src/test/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTest.java b/smoke-tests-otel-starter/spring-boot-2/src/test/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTest.java index 65315b926d5b..f911cc5aea78 100644 --- a/smoke-tests-otel-starter/spring-boot-2/src/test/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTest.java +++ b/smoke-tests-otel-starter/spring-boot-2/src/test/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTest.java @@ -18,5 +18,6 @@ // The headers are simply set here to make sure that headers can be parsed "otel.exporter.otlp.headers.c=3", "otel.instrumentation.runtime-telemetry.emit-experimental-telemetry=true", + "otel.instrumentation.common.thread_details.enabled=true", }) class OtelSpringStarterSmokeTest extends AbstractOtelSpringStarterSmokeTest {} diff --git a/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/GraalVmNativeKafkaSpringStarterSmokeTest.java b/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/GraalVmNativeKafkaSpringStarterSmokeTest.java index b64e19ce8c8c..fc53907b729a 100644 --- a/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/GraalVmNativeKafkaSpringStarterSmokeTest.java +++ b/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/GraalVmNativeKafkaSpringStarterSmokeTest.java @@ -27,6 +27,6 @@ AbstractKafkaSpringStarterSmokeTest.KafkaConfig.class }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@EnabledInNativeImage // see JvmMongodbSpringStarterSmokeTest for the JVM test +@EnabledInNativeImage // see AbstractJvmKafkaSpringStarterSmokeTest for the JVM test @RequiresDockerCompose public class GraalVmNativeKafkaSpringStarterSmokeTest extends AbstractKafkaSpringStarterSmokeTest {} diff --git a/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/GraalVmNativeMongodbSpringStarterSmokeTest.java b/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/GraalVmNativeMongodbSpringStarterSmokeTest.java index 18a8a46dda0a..4c26d4f82a56 100644 --- a/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/GraalVmNativeMongodbSpringStarterSmokeTest.java +++ b/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/GraalVmNativeMongodbSpringStarterSmokeTest.java @@ -23,7 +23,7 @@ @SpringBootTest( classes = {OtelSpringStarterSmokeTestApplication.class, SpringSmokeOtelConfiguration.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@EnabledInNativeImage // see JvmMongodbSpringStarterSmokeTest for the JVM test +@EnabledInNativeImage // see AbstractJvmMongodbSpringStarterSmokeTest for the JVM test @RequiresDockerCompose public class GraalVmNativeMongodbSpringStarterSmokeTest extends AbstractMongodbSpringStarterSmokeTest {} diff --git a/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTest.java b/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTest.java index 9fe9916312b2..538e68d3ffc3 100644 --- a/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTest.java +++ b/smoke-tests-otel-starter/spring-boot-3/src/test/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTest.java @@ -21,6 +21,7 @@ "otel.exporter.otlp.headers.c=3", "otel.instrumentation.runtime-telemetry.emit-experimental-telemetry=true", "otel.instrumentation.runtime-telemetry-java17.enable-all=true", + "otel.instrumentation.common.thread_details.enabled=true", }) class OtelSpringStarterSmokeTest extends AbstractOtelSpringStarterSmokeTest { diff --git a/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractJvmKafkaSpringStarterSmokeTest.java b/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractJvmKafkaSpringStarterSmokeTest.java index 2441e61d2cb1..7052b6eef4a8 100644 --- a/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractJvmKafkaSpringStarterSmokeTest.java +++ b/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractJvmKafkaSpringStarterSmokeTest.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.kafka.KafkaInstrumentationAutoConfiguration; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.thread.ThreadDetailsAutoConfiguration; import java.time.Duration; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -50,6 +51,7 @@ void setUpContext() { .withConfiguration( AutoConfigurations.of( OpenTelemetryAutoConfiguration.class, + ThreadDetailsAutoConfiguration.class, SpringSmokeOtelConfiguration.class, KafkaAutoConfiguration.class, KafkaInstrumentationAutoConfiguration.class, diff --git a/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractOtelSpringStarterSmokeTest.java b/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractOtelSpringStarterSmokeTest.java index 7395ed49f0a4..aba56ee6c883 100644 --- a/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractOtelSpringStarterSmokeTest.java +++ b/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractOtelSpringStarterSmokeTest.java @@ -30,6 +30,7 @@ import io.opentelemetry.semconv.incubating.CodeIncubatingAttributes; import io.opentelemetry.semconv.incubating.DbIncubatingAttributes; import io.opentelemetry.semconv.incubating.ServiceIncubatingAttributes; +import io.opentelemetry.semconv.incubating.ThreadIncubatingAttributes; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; @@ -37,6 +38,7 @@ import java.util.List; import org.assertj.core.api.AbstractCharSequenceAssert; import org.assertj.core.api.AbstractIterableAssert; +import org.assertj.core.api.AbstractLongAssert; import org.assertj.core.api.MapAssert; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; @@ -180,9 +182,7 @@ void shouldSendTelemetry() { UrlAttributes.URL_FULL, stringAssert -> stringAssert.endsWith("/ping")), equalTo(ServerAttributes.SERVER_ADDRESS, "localhost"), - satisfies( - ServerAttributes.SERVER_PORT, - integerAssert -> integerAssert.isNotZero())), + satisfies(ServerAttributes.SERVER_PORT, AbstractLongAssert::isNotZero)), serverSpan -> HttpSpanDataAssert.create(serverSpan) .assertServerGetRequest("/ping") @@ -207,10 +207,14 @@ void shouldSendTelemetry() { equalTo( AttributeKey.stringArrayKey("http.request.header.key"), Collections.singletonList("value")), + satisfies(ServerAttributes.SERVER_PORT, AbstractLongAssert::isNotZero), + satisfies( + ThreadIncubatingAttributes.THREAD_ID, + AbstractLongAssert::isNotZero), satisfies( - ServerAttributes.SERVER_PORT, - integerAssert -> integerAssert.isNotZero())), - span -> withSpanAssert(span))); + ThreadIncubatingAttributes.THREAD_NAME, + AbstractCharSequenceAssert::isNotBlank)), + AbstractSpringStarterSmokeTest::withSpanAssert)); // Metric testing.waitAndAssertMetrics( @@ -309,7 +313,7 @@ void restTemplate() { span -> HttpSpanDataAssert.create(span).assertClientGetRequest("/ping"), span -> span.hasKind(SpanKind.SERVER).hasAttribute(HttpAttributes.HTTP_ROUTE, "/ping"), - span -> withSpanAssert(span))); + AbstractSpringStarterSmokeTest::withSpanAssert)); } @Test