Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

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

Merged
cijothomas merged 14 commits intoopen-telemetry:mainopen-telemetry/opentelemetry-rust:mainfrom
cijothomas:stabilize-span-attributescijothomas/opentelemetry-rust:stabilize-span-attributesCopy head branch name to clipboard
May 7, 2026
Merged

feat(appender-tracing): stabilize span attribute propagation#3482
cijothomas merged 14 commits intoopen-telemetry:mainopen-telemetry/opentelemetry-rust:mainfrom
cijothomas:stabilize-span-attributescijothomas/opentelemetry-rust:stabilize-span-attributesCopy head branch name to clipboard

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. Note: the experimental feature was never released, so this is effectively a new feature.

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

  • Single builder method with a value type to configure runtime behavior:

    use opentelemetry_appender_tracing::layer::TracingSpanAttributes;
    
    // Copy all tracing-span attributes onto log records:
    let layer = OpenTelemetryTracingBridge::builder(&provider)
        .with_tracing_span_attributes(TracingSpanAttributes::all())
        .build();
    
    // Or restrict to an allowlist:
    let layer = OpenTelemetryTracingBridge::builder(&provider)
        .with_tracing_span_attributes(TracingSpanAttributes::allowlist(["session.id"]))
        .build();

    One setter means no invalid combinations are expressible — no runtime warnings or extra feature plumbing needed.

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.

Tests

All existing tests have been updated. Tests cover:

  • tracing_appender_span_attributes_disabled_by_default — enrichment off by default.
  • tracing_appender_span_attributes_all_copies_allTracingSpanAttributes::all() copies all span attributes.
  • tracing_appender_span_attribute_allowlist_includes_only_namedTracingSpanAttributes::allowlist(...) filters correctly.
  • tracing_appender_span_attribute_allowlist_nested_spans — allowlist filtering across nested spans.
  • tracing_appender_span_attribute_allowlist_with_on_record — allowlist with late-recorded fields.
  • tracing_appender_empty_allowlist_copies_nothing — empty allowlist means "allow nothing".

Out of Scope

Refs

Merge requirement checklist

  • CONTRIBUTING guidelines followed
  • Unit tests added/updated
  • Appropriate CHANGELOG.md files updated for non-trivial, user-facing changes
  • Changes in public API reviewed (adds TracingSpanAttributes type and with_tracing_span_attributes builder method, 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 92.68293% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.1%. Comparing base (04b6a6f) to head (921d6cf).

Files with missing lines Patch % Lines
opentelemetry-appender-tracing/src/layer.rs 92.6% 9 Missing ⚠️
Additional details and impacted files
@@          Coverage Diff          @@
##            main   #3482   +/-   ##
=====================================
  Coverage   84.1%   84.1%           
=====================================
  Files        126     126           
  Lines      26620   26719   +99     
=====================================
+ Hits       22400   22489   +89     
- Misses      4220    4230   +10     

☔ 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.
Comment thread opentelemetry-appender-tracing/src/layer.rs Outdated
cijothomas added 8 commits May 5, 2026 17:22
Replace the two-method design (with_all_span_attributes + with_span_attribute_allowlist)
with a single with_span_attributes method that accepts a SpanAttributes value type.

SpanAttributes has two named constructors:
- SpanAttributes::all() — copy all tracing-span attributes
- SpanAttributes::allowlist(keys) — copy only named attributes

One setter means no invalid combinations are expressible, eliminating the
need for runtime warnings and the internal-logs feature plumbing.

Addresses Utpilla's review feedback on PR open-telemetry#3482.
Avoids confusion with potential future OTel span attributes type.
Leaves room for a future OTelSpanAttributes that copies attributes
from OpenTelemetry spans.
Consistent with the TracingSpanAttributes type name.
Store TracingSpanAttributesInner directly instead of collapsing to
HashSet. Previously an empty HashSet was used as a sentinel for 'copy
all', which meant allowlist([]) would silently behave as all().
Now allowlist([]) correctly means 'copy nothing'.
Verifies that allowlist([]) means 'allow nothing' — enrichment is
enabled but no span attributes match the empty set.
Add a section covering TracingSpanAttributes usage with code examples.
Update the Feature Flags section. Replace the old tracing-spans note
with a clearer one scoped to enrichment.
@cijothomas cijothomas marked this pull request as ready for review May 6, 2026 01:32
@cijothomas
Copy link
Copy Markdown
Member Author

@codefromthecrypt @leghadjeu-christian Please review if you have some bandwidth!

Copy link
Copy Markdown
Contributor

@leghadjeu-christian leghadjeu-christian left a comment

Choose a reason for hiding this comment

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

@cijothomas LGTM, thanks for this

Comment thread opentelemetry-appender-tracing/src/layer.rs
Copy link
Copy Markdown
Member

@lalitb lalitb left a comment

Choose a reason for hiding this comment

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

LGTM, once we agree on the collision-policy.

@cijothomas cijothomas added this pull request to the merge queue May 7, 2026
Merged via the queue into open-telemetry:main with commit cc87dd9 May 7, 2026
28 checks passed
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.

6 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.