Skip to content

feat(sdk): support OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT#3377

Open
bryantbiggs wants to merge 2 commits intoopen-telemetry:mainfrom
bryantbiggs:fix/span-attribute-value-length-limit
Open

feat(sdk): support OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT#3377
bryantbiggs wants to merge 2 commits intoopen-telemetry:mainfrom
bryantbiggs:fix/span-attribute-value-length-limit

Conversation

@bryantbiggs
Copy link
Copy Markdown
Contributor

@bryantbiggs bryantbiggs commented Feb 20, 2026

Summary

Implements OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT per the SDK environment variable specification. When configured, Value::String and Array::String attribute values are truncated to the specified number of Unicode characters on spans, span events, and span links.

This is a spec-required feature that Go and Java SDKs have supported since their 1.0 releases. Its absence is tracked as part of #3374 (missing spec-required environment variables). The stale PR #3090 by @msierks-pcln attempted this 6+ months ago but stalled after CLA issues; this implementation incorporates the maintainer review feedback from that PR.

Supersedes #3090.

Why this belongs in a single PR

The changes span two crates but form a single logical unit:

  1. opentelemetry crateValue::truncate() and StringValue::truncate() are general-purpose string truncation methods needed because StringValue's internal storage is pub(crate), so the SDK crate cannot manipulate it directly. These methods contain no enforcement logic — they are utilities.

  2. opentelemetry-sdk crate — The enforcement: reading the env var, storing the limit in SpanLimits, and calling truncate() at every attribute ingestion point (span build, set_attribute, add_event, add_link).

Splitting these into separate PRs would leave the API methods without a caller, or the SDK enforcement without the methods it calls.

Design decisions

  • u32 not i32 — only positive values are meaningful (addresses feat: add support for OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT #3090 reviewer feedback)
  • Option<u32> with None default — no sentinel needed; unlimited by default per spec
  • Only OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT, not OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT — the global fallback should wait until logs also support it (per maintainer feedback on feat: add support for OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT #3090: "OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT is not something we can add right now, as Logs don't respect this at all"). This is consistent with how OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT exists without a global OTEL_ATTRIBUTE_COUNT_LIMIT fallback in this codebase.
  • Truncation is silent — no ellipsis appended, matching spec behavior (addresses feat: add support for OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT #3090 reviewer feedback about being explicit about implications)
  • Truncation respects UTF-8 character boundaries — uses char_indices().nth() to find the byte offset, never splits a multi-byte character

Breaking change

SpanLimits gains a new public field max_attribute_value_length: Option<u32>. Code that constructs SpanLimits via struct literal will need to add this field (use None for unlimited). This is a known limitation of SpanLimits not being #[non_exhaustive], tracked in #2551.

Changes

  • opentelemetry: add Value::truncate() and StringValue::truncate() with 8 unit tests
  • SpanLimits: add max_attribute_value_length: Option<u32> field and truncate_string_values() helper
  • Config: read OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT env var with 4 unit tests
  • TracerProviderBuilder: add with_max_attribute_value_length(u32) builder method
  • Span / SdkTracer: apply truncation at all attribute ingestion points with 5 integration tests

Test plan

  • StringValue::truncate: ASCII, empty, zero-length, multi-byte UTF-8 (euro sign, CJK, accented chars)
  • Value::truncate: only affects String/Array::String, leaves bool/i64/f64 and their arrays unchanged
  • Span attribute truncation via builder and set_attribute
  • UTF-8 boundary correctness
  • Event attribute truncation
  • Link attribute truncation
  • No truncation when limit is not set
  • Env var parsing: valid, invalid, negative
  • cargo fmt --all -- --check
  • cargo clippy (both crates)
  • bash ./scripts/lint.sh
  • Full workspace cargo check
  • 85 trace tests pass, 13 common tests pass

@bryantbiggs bryantbiggs requested a review from a team as a code owner February 20, 2026 17:52
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 20, 2026

Codecov Report

❌ Patch coverage is 96.36364% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.4%. Comparing base (9650783) to head (a37a513).

Files with missing lines Patch % Lines
opentelemetry-sdk/src/trace/span.rs 92.4% 10 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##            main   #3377     +/-   ##
=======================================
+ Coverage   83.2%   83.4%   +0.1%     
=======================================
  Files        128     128             
  Lines      25045   25319    +274     
=======================================
+ Hits       20858   21123    +265     
- Misses      4187    4196      +9     

☔ 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.

@bryantbiggs bryantbiggs force-pushed the fix/span-attribute-value-length-limit branch from 39d7133 to 07b684f Compare March 6, 2026 01:55
@bryantbiggs bryantbiggs force-pushed the fix/span-attribute-value-length-limit branch from 07b684f to 29da1dd Compare March 14, 2026 17:58
Add support for the OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT environment
variable and TracerProviderBuilder::with_max_attribute_value_length().

When configured, Value::String and Array::String attribute values are
truncated to the specified number of Unicode characters (not bytes) on:
- Span attributes (both at build time and via set_attribute)
- Span event attributes
- Span link attributes

Truncation respects UTF-8 character boundaries and avoids allocations
when the string is already within the limit.

The limit defaults to None (unlimited) and can be set via:
- The OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT env var
- TracerProviderBuilder::with_max_attribute_value_length()
Move the duplicated truncation logic (3x in tracer.rs, 1x helper in
span.rs) into SpanLimits::truncate_string_values(). All call sites
now use the shared method.

Fix SDK changelog to note the breaking SpanLimits field addition.
Add opentelemetry crate changelog for new pub truncate() methods.
@bryantbiggs bryantbiggs force-pushed the fix/span-attribute-value-length-limit branch from 29da1dd to a37a513 Compare March 21, 2026 01:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant