Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sdk-autoconfigure-support/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
@@ -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<SpanProcessor> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still interested in thread.name being added before span start, especially in declarative config, so it can be used by the declarative config rule-based sampler

I guess we could always have the rule-based sampler hard-code support for thread.name since it runs on the same thread, but that feels a little hacky (is thread.name always available in the rule-based sampler then even if the attribute isn't being stamped onto the span?)

I'm not sure how best to accomplish this though

cc @laurit

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way I see it we have 2 options. Either let rule based sampler compute thread.name itself or add the thread.name in instrumentation api.

@Override
public String getName() {
return "thread_details";
}

@Override
public SpanProcessor create(DeclarativeConfigProperties config) {
return new AddThreadDetailsSpanProcessor();
}

@Override
public Class<SpanProcessor> getType() {
return SpanProcessor.class;
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.opentelemetry.instrumentation.thread.internal.ThreadDetailsComponentProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.opentelemetry.instrumentation.thread.internal.ThreadDetailsCustomizerProvider
Original file line number Diff line number Diff line change
@@ -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()));
}
}
Loading