Skip to content

add thread details for declarative config#15209

Closed
zeitlinger wants to merge 26 commits into
open-telemetry:mainfrom
zeitlinger:declarative-config-thread-details-provider2
Closed

add thread details for declarative config#15209
zeitlinger wants to merge 26 commits into
open-telemetry:mainfrom
zeitlinger:declarative-config-thread-details-provider2

Conversation

@zeitlinger

@zeitlinger zeitlinger commented Nov 3, 2025

Copy link
Copy Markdown
Member

Part of #14087
Alternative for #14564

Summary

Moves thread details (thread.id, thread.name) from the AddThreadDetailsSpanProcessor to an InstrumenterCustomizer-based approach using ThreadDetailsAttributesExtractor. This means thread attributes are added via AttributesExtractor at instrumentation build time rather than via SpanProcessor at span start time.

The existing AddThreadDetailsSpanProcessor is still used for non-declarative-config agent mode (where it remains on by default via otel.javaagent.add-thread-details=true). The new InstrumenterCustomizer path is used for declarative config, where it is off by default — users must explicitly enable it:

  • Agent (declarative config): thread_details_enabled: true under the java_agent distribution node (default: false)
  • Spring starter (declarative config): thread_details.enabled: true under spring_starter instrumentation config (default: false)
  • Agent (env var / system properties): otel.javaagent.add-thread-details (default: true, unchanged)

Making it off by default in 3.0 for non-declarative-config users is tracked in #15334.

Approach

  • ThreadDetailsAttributesExtractor in instrumentation-api-incubator captures thread.id and thread.name on span start
  • InstrumenterCustomizerProvider implementations (one for agent, one for spring starter) register the extractor when enabled
  • Agent provider reads from AgentDistributionConfig.isThreadDetailsEnabled()
  • Spring starter provider reads from ExtendedOpenTelemetry.getInstrumentationConfig("spring_starter")
  • Config lives under distribution nodes (not instrumentation.common) per SIG feedback — this is controlled by agent/starter, not individual instrumentations
  • The AddThreadDetailsSpanProcessor registration is removed from AgentTracerProviderConfigurer (the processor class itself is retained for non-DC use)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for configuring thread details (thread ID and thread name) as span attributes through declarative configuration in the instrumentation API. When enabled via configuration, an AttributesExtractor automatically adds thread information to spans created by instrumenters.

  • Adds ThreadDetailsAttributesExtractor to InstrumenterBuilder to capture thread ID and name
  • Integrates with declarative configuration under instrumentation/java/thread_details/enabled
  • Adds comprehensive test coverage for both enabled and disabled states

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
InstrumenterBuilder.java Implements thread details extraction logic and configuration parsing
AddThreadDetailsTest.java Tests thread details functionality with parameterized enabled/disabled scenarios
build.gradle.kts Adds test dependency for declarative configuration support

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@zeitlinger zeitlinger marked this pull request as draft November 3, 2025 17:55
@zeitlinger zeitlinger force-pushed the declarative-config-thread-details-provider2 branch from 6fb9796 to 29883b5 Compare November 9, 2025 12:51
@zeitlinger zeitlinger marked this pull request as ready for review November 9, 2025 12:51

@trask trask left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can you update the PR description with a summary of the relationship between this and the existing thread details span processor? and mention it's off by default when using declarative config (and we can consider making it off by default in 3.0 for others)

@zeitlinger zeitlinger force-pushed the declarative-config-thread-details-provider2 branch from acdc794 to dd2b211 Compare November 17, 2025 12:56
@zeitlinger

Copy link
Copy Markdown
Member Author

and we can consider making it off by default in 3.0 for others)

created #15334

@zeitlinger

Copy link
Copy Markdown
Member Author

@trask please check again

@trask trask left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@jaydeluca can you take a look also?

let's also figure out where to document this, ideally in same place as other declarative config "common" attributes

@zeitlinger

Copy link
Copy Markdown
Member Author

@trask please have another look

@zeitlinger zeitlinger force-pushed the declarative-config-thread-details-provider2 branch from fff4d30 to 8c8a96c Compare December 5, 2025 09:06
@zeitlinger zeitlinger added this to the v2.23.0 milestone Dec 5, 2025
@zeitlinger zeitlinger requested a review from trask December 5, 2025 13:07
@trask trask removed this from the v2.23.0 milestone Dec 12, 2025
@zeitlinger

Copy link
Copy Markdown
Member Author

@trask please have another look

@github-actions github-actions Bot added the test native This label can be applied to PRs to trigger them to run native tests label Jan 14, 2026
@zeitlinger zeitlinger force-pushed the declarative-config-thread-details-provider2 branch from 46e9ee9 to aaea68d Compare January 14, 2026 13:59
@zeitlinger

Copy link
Copy Markdown
Member Author

@trask please have a look

zeitlinger and others added 5 commits May 12, 2026 12:50
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
@zeitlinger

Copy link
Copy Markdown
Member Author

@trask can this be merged now?

@zeitlinger zeitlinger added this to the v3.0.0 milestone Jun 11, 2026
@trask trask modified the milestones: v3.0.0, v2.29.0 Jun 12, 2026
@trask trask requested a review from Copilot June 12, 2026 14:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Comment on lines +17 to +20
public void customize(InstrumenterCustomizer customizer) {
if (AgentDistributionConfig.get().isThreadDetailsEnabled()) {
customizer.addAttributesExtractor(new ThreadDetailsAttributesExtractor<>());
}
Comment on lines +32 to +46
/** Called from OpenTelemetryAutoConfiguration for declarative config. */
public static void configureDeclarativeConfig(Object model) {
enabled = isEnabled(model);
}

/** Called from OpenTelemetryAutoConfiguration for properties-based config. */
public static void configureProperties(Environment environment) {
enabled = Boolean.TRUE.equals(environment.getProperty(LEGACY_PROPERTY, Boolean.class));
}

@Override
public void customize(InstrumenterCustomizer customizer) {
if (enabled) {
customizer.addAttributesExtractor(new ThreadDetailsAttributesExtractor<>());
}
trask added a commit to trask/opentelemetry-java-instrumentation that referenced this pull request Jun 15, 2026
Registers AddThreadDetailsSpanProcessor through declarative config (a named
ComponentProvider plus a DeclarativeConfigurationCustomizerProvider that injects
the processor node) for both the javaagent and the spring starter. Because it is
a SpanProcessor, thread.id/thread.name are added to manually-created spans too,
not only Instrumenter-built spans.

- agent: enabled via distribution.javaagent (otel.javaagent.add-thread-details)
- spring starter: enabled via distribution.spring_starter.thread_details_enabled

Alternative to the InstrumenterCustomizer/AttributesExtractor approach in open-telemetry#15209.

Signed-off-by: Trask Stalnaker <trask.stalnaker@gmail.com>
trask added a commit to trask/opentelemetry-java-instrumentation that referenced this pull request Jun 15, 2026
Registers AddThreadDetailsSpanProcessor through declarative config (a named
ComponentProvider plus a DeclarativeConfigurationCustomizerProvider that injects
the processor node) for both the javaagent and the spring starter. Because it is
a SpanProcessor, thread.id/thread.name are added to manually-created spans too,
not only Instrumenter-built spans.

- agent: enabled via distribution.javaagent (otel.javaagent.add-thread-details)
- spring starter: enabled via distribution.spring_starter.thread_details_enabled

Alternative to the InstrumenterCustomizer/AttributesExtractor approach in open-telemetry#15209.

Signed-off-by: Trask Stalnaker <trask.stalnaker@gmail.com>
trask added a commit to trask/opentelemetry-java-instrumentation that referenced this pull request Jun 15, 2026
Registers AddThreadDetailsSpanProcessor through declarative config (a named
ComponentProvider plus a DeclarativeConfigurationCustomizerProvider that injects
the processor node) for both the javaagent and the spring starter. Because it is
a SpanProcessor, thread.id/thread.name are added to manually-created spans too,
not only Instrumenter-built spans.

- agent: enabled via distribution.javaagent (otel.javaagent.add-thread-details)
- spring starter: enabled via distribution.spring_starter.thread_details_enabled

Alternative to the InstrumenterCustomizer/AttributesExtractor approach in open-telemetry#15209.

Signed-off-by: Trask Stalnaker <trask.stalnaker@gmail.com>
trask added a commit to trask/opentelemetry-java-instrumentation that referenced this pull request Jun 15, 2026
Registers AddThreadDetailsSpanProcessor through declarative config (a named
ComponentProvider plus a DeclarativeConfigurationCustomizerProvider that injects
the processor node) for both the javaagent and the spring starter. Because it is
a SpanProcessor, thread.id/thread.name are added to manually-created spans too,
not only Instrumenter-built spans.

- agent: enabled via distribution.javaagent (otel.javaagent.add-thread-details)
- spring starter: enabled via distribution.spring_starter.thread_details_enabled

Alternative to the InstrumenterCustomizer/AttributesExtractor approach in open-telemetry#15209.

Signed-off-by: Trask Stalnaker <trask.stalnaker@gmail.com>
trask added a commit to trask/opentelemetry-java-instrumentation that referenced this pull request Jun 15, 2026
Registers AddThreadDetailsSpanProcessor through declarative config (a named
ComponentProvider plus a DeclarativeConfigurationCustomizerProvider that injects
the processor node) for both the javaagent and the spring starter. Because it is
a SpanProcessor, thread.id/thread.name are added to manually-created spans too,
not only Instrumenter-built spans.

- agent: enabled via distribution.javaagent (otel.javaagent.add-thread-details)
- spring starter: enabled via distribution.spring_starter.thread_details_enabled

Alternative to the InstrumenterCustomizer/AttributesExtractor approach in open-telemetry#15209.

Signed-off-by: Trask Stalnaker <trask.stalnaker@gmail.com>
trask added a commit to trask/opentelemetry-java-instrumentation that referenced this pull request Jun 15, 2026
Registers AddThreadDetailsSpanProcessor through declarative config (a named
ComponentProvider plus a DeclarativeConfigurationCustomizerProvider that injects
the processor node) for both the javaagent and the spring starter. Because it is
a SpanProcessor, thread.id/thread.name are added to manually-created spans too,
not only Instrumenter-built spans.

- agent: enabled via distribution.javaagent (otel.javaagent.add-thread-details)
- spring starter: enabled via distribution.spring_starter.thread_details_enabled

Alternative to the InstrumenterCustomizer/AttributesExtractor approach in open-telemetry#15209.

Signed-off-by: Trask Stalnaker <trask.stalnaker@gmail.com>
trask added a commit to trask/opentelemetry-java-instrumentation that referenced this pull request Jun 15, 2026
Registers AddThreadDetailsSpanProcessor through declarative config (a named
ComponentProvider plus a DeclarativeConfigurationCustomizerProvider that injects
the processor node) for both the javaagent and the spring starter. Because it is
a SpanProcessor, thread.id/thread.name are added to manually-created spans too,
not only Instrumenter-built spans.

- agent: enabled via distribution.javaagent (otel.javaagent.add-thread-details)
- spring starter: enabled via distribution.spring_starter.thread_details_enabled

Alternative to the InstrumenterCustomizer/AttributesExtractor approach in open-telemetry#15209.

Signed-off-by: Trask Stalnaker <trask.stalnaker@gmail.com>
trask added a commit to trask/opentelemetry-java-instrumentation that referenced this pull request Jun 15, 2026
Registers AddThreadDetailsSpanProcessor through declarative config (a named
ComponentProvider plus a DeclarativeConfigurationCustomizerProvider that injects
the processor node) for both the javaagent and the spring starter. Because it is
a SpanProcessor, thread.id/thread.name are added to manually-created spans too,
not only Instrumenter-built spans.

- agent: enabled via distribution.javaagent (otel.javaagent.add-thread-details)
- spring starter: enabled via distribution.spring_starter.thread_details_enabled

Alternative to the InstrumenterCustomizer/AttributesExtractor approach in open-telemetry#15209.

Signed-off-by: Trask Stalnaker <trask.stalnaker@gmail.com>
trask added a commit to trask/opentelemetry-java-instrumentation that referenced this pull request Jun 15, 2026
Registers AddThreadDetailsSpanProcessor through declarative config (a named
ComponentProvider plus a DeclarativeConfigurationCustomizerProvider that injects
the processor node) for both the javaagent and the spring starter. Because it is
a SpanProcessor, thread.id/thread.name are added to manually-created spans too,
not only Instrumenter-built spans.

- agent: enabled via distribution.javaagent (otel.javaagent.add-thread-details)
- spring starter: enabled via distribution.spring_starter.thread_details_enabled

Alternative to the InstrumenterCustomizer/AttributesExtractor approach in open-telemetry#15209.

Signed-off-by: Trask Stalnaker <trask.stalnaker@gmail.com>
trask added a commit to trask/opentelemetry-java-instrumentation that referenced this pull request Jun 15, 2026
Registers AddThreadDetailsSpanProcessor through declarative config (a named
ComponentProvider plus a DeclarativeConfigurationCustomizerProvider that injects
the processor node) for both the javaagent and the spring starter. Because it is
a SpanProcessor, thread.id/thread.name are added to manually-created spans too,
not only Instrumenter-built spans.

- agent: enabled via distribution.javaagent (otel.javaagent.add-thread-details)
- spring starter: enabled via distribution.spring_starter.thread_details_enabled

Alternative to the InstrumenterCustomizer/AttributesExtractor approach in open-telemetry#15209.

Signed-off-by: Trask Stalnaker <trask.stalnaker@gmail.com>
trask added a commit to trask/opentelemetry-java-instrumentation that referenced this pull request Jun 15, 2026
Registers AddThreadDetailsSpanProcessor through declarative config (a named
ComponentProvider plus a DeclarativeConfigurationCustomizerProvider that injects
the processor node) for both the javaagent and the spring starter. Because it is
a SpanProcessor, thread.id/thread.name are added to manually-created spans too,
not only Instrumenter-built spans.

- agent: enabled via distribution.javaagent (otel.javaagent.add-thread-details)
- spring starter: enabled via distribution.spring_starter.thread_details_enabled

Alternative to the InstrumenterCustomizer/AttributesExtractor approach in open-telemetry#15209.

Signed-off-by: Trask Stalnaker <trask.stalnaker@gmail.com>
@trask

trask commented Jun 16, 2026

Copy link
Copy Markdown
Member

I decided against moving thread attributes from span processor to instrumenter due to losing coverage for manual spans. I think losing coverage for manual spans may be worse (or at least no better) than the current situation of samplers not having access to thread attributes. See new PR #19008.

@trask trask removed this from the v2.29.0 milestone Jun 16, 2026
@zeitlinger

Copy link
Copy Markdown
Member Author

Close in favor of #19008

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test native This label can be applied to PRs to trigger them to run native tests

Projects

Development

Successfully merging this pull request may close these issues.

5 participants