Skip to content

feat(appender-tracing): stabilize span attribute propagation#3482

Draft
cijothomas wants to merge 5 commits intoopen-telemetry:mainfrom
cijothomas:stabilize-span-attributes
Draft

feat(appender-tracing): stabilize span attribute propagation#3482
cijothomas wants to merge 5 commits intoopen-telemetry:mainfrom
cijothomas:stabilize-span-attributes

Conversation

@cijothomas
Copy link
Copy Markdown
Member

@cijothomas cijothomas commented Apr 30, 2026

Implements the API shape discussed in #3481.

Note: throughout this PR, "span" refers to a tracing::span! from the tracing crate (the source the appender consumes), not an opentelemetry::trace::Span.

Changes

  • Removes the experimental_span_attributes cargo feature. Tracing-span attribute enrichment (copying attributes from active tracing spans onto each emitted log record) is now part of the stable API surface of opentelemetry-appender-tracing.

  • Disabled by default. Users who don't enable enrichment pay no per-span overhead (on_new_span / on_record / scope walk all return early).

  • Two orthogonal builder methods to configure runtime behavior:

    // Copy all tracing-span attributes onto log records:
    let layer = OpenTelemetryTracingBridge::builder(&provider)
        .enable_span_attributes(true)
        .build();
    
    // Or restrict to an allowlist (must also call enable_span_attributes(true)):
    let layer = OpenTelemetryTracingBridge::builder(&provider)
        .enable_span_attributes(true)
        .with_span_attribute_allowlist(["session.id"])
        .build();

    Semantics:

    • enable_span_attributes(bool) toggles enrichment on or off.
    • with_span_attribute_allowlist(keys) configures the filter.
    • The two methods are independent: order doesn't matter, and the allowlist only takes effect when enable_span_attributes(true) is also called.
    • Calling with_span_attribute_allowlist without enable_span_attributes(true) is a no-op; build() emits an otel_warn! to surface the misconfiguration.
  • Adds an internal-logs cargo feature on opentelemetry-appender-tracing (forwarding to opentelemetry/internal-logs) so the otel_warn! call from build() participates in the standard internal-logs feature wiring used by other crates in the workspace.

Terminology

The PR uses "enrichment" rather than "propagation". Propagation is already an overloaded term in OpenTelemetry (W3C TraceContext, baggage, etc.), and "enrichment" matches the term used by the Java and .NET SDKs for this exact pattern, as well as the title of the original PR (#3282) that introduced the experimental feature.

Migration

Users of the previous experimental_span_attributes feature need to:

  1. Drop the experimental_span_attributes feature from Cargo.toml.
  2. Add an explicit .enable_span_attributes(true) call on the builder.
  3. Existing with_span_attribute_allowlist(keys) calls are preserved as-is.

Tests

All existing tests have been migrated off the cargo feature gate. New tests added covering the orthogonal semantics:

  • tracing_appender_span_attributes_disabled_by_default — enrichment off by default.
  • tracing_appender_enable_span_attributes_copies_allenable_span_attributes(true) without allowlist copies all.
  • tracing_appender_allowlist_alone_is_no_opwith_span_attribute_allowlist alone (without enable_span_attributes(true)) does not enrich anything.
  • tracing_appender_enable_then_allowlist_order_independent — order of the two builder methods does not matter.

Test counts:

  • cargo test -p opentelemetry-appender-tracing --all-features --lib: 14 passed, 2 ignored.
  • cargo clippy -p opentelemetry-appender-tracing --all-targets --all-features -- -Dwarnings: clean.
  • cargo clippy -p opentelemetry-appender-tracing --all-targets --no-default-features -- -Dwarnings: clean.
  • cargo clippy --workspace --all-targets --all-features -- -Dwarnings: clean.
  • cargo doc -p opentelemetry-appender-tracing --no-deps --all-features: clean.

Out of Scope

Refs

Merge requirement checklist

  • CONTRIBUTING guidelines followed
  • Unit tests added/updated (added four new tests covering the orthogonal-method semantics; all existing tests run unconditionally)
  • Appropriate CHANGELOG.md files updated for non-trivial, user-facing changes
  • Changes in public API reviewed (adds enable_span_attributes, keeps with_span_attribute_allowlist, adds internal-logs cargo feature, removes experimental_span_attributes feature)

Drops the experimental_span_attributes cargo feature; span attribute
propagation is now part of the stable API surface.

Propagation is disabled by default (no per-span overhead). Users opt in
at runtime via the new builder method:

    OpenTelemetryTracingBridge::builder(&provider)
        .with_span_attributes(std::iter::empty::<&str>())  // copy all
        .build();

    OpenTelemetryTracingBridge::builder(&provider)
        .with_span_attributes(["session.id"])  // allowlist
        .build();

Migration: drop the experimental_span_attributes feature from Cargo.toml,
and replace with_span_attribute_allowlist(keys) with
with_span_attributes(keys). Pass an empty iterator to preserve the
previous "copy everything" default.

Closes open-telemetry#3481.
@cijothomas cijothomas requested a review from a team as a code owner April 30, 2026 20:56
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

Codecov Report

❌ Patch coverage is 99.26471% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 83.7%. Comparing base (f60125e) to head (c821f0e).

Files with missing lines Patch % Lines
opentelemetry-appender-tracing/src/layer.rs 99.2% 1 Missing ⚠️
Additional details and impacted files
@@          Coverage Diff           @@
##            main   #3482    +/-   ##
======================================
  Coverage   83.7%   83.7%            
======================================
  Files        126     126            
  Lines      25386   25507   +121     
======================================
+ Hits       21255   21374   +119     
- Misses      4131    4133     +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Replace the single with_span_attributes method (which required an empty
iterator sentinel to mean 'copy all') with two methods:

- enable_span_attributes(bool): turn the feature on or off.
- with_span_attribute_allowlist(keys): restrict to specific keys; also
  implicitly enables propagation.

Semantics:
- enable_span_attributes(true) enables, preserving any allowlist already
  configured.
- enable_span_attributes(false) disables and clears the allowlist.
- with_span_attribute_allowlist replaces any prior allowlist (last call
  wins) and implicitly enables.

Adds tests for the new interaction semantics.
@cijothomas cijothomas marked this pull request as draft April 30, 2026 21:14
Follow-up to the separate-methods design: the two methods are now fully
orthogonal. with_span_attribute_allowlist no longer implicitly enables
propagation. enable_span_attributes(false) no longer clears any
configured allowlist.

To prevent silent misconfiguration, build() emits an otel_warn! when an
allowlist is set but enable_span_attributes(true) was not called.

Adds an internal-logs feature on opentelemetry-appender-tracing that
forwards to opentelemetry/internal-logs, required by the otel_warn! call.
…el Span

'Propagation' overloads the OTel term for context propagation. 'Enrichment'
is what Java/.NET use for this same pattern (and matches the original
introducing PR's title). Updates CHANGELOG, doc comments, internal
comments, the otel_warn! message, and bench docs.

Also explicitly clarifies in doc comments and CHANGELOG that 'span' here
refers to a tracing::span! from the tracing crate, NOT an
opentelemetry::trace::Span.
Re-runs both logs and span-attributes benches on the current toolchain
and updates the documented results. No real perf regression vs main:
the apparent variance between runs is bench-to-bench noise (~15% jitter
on this hardware), confirmed by running both code paths twice.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant