Skip to content

fix(otel): keep last duplicate span in masking batches - #1803

Merged
hassiebp merged 5 commits into
mainfrom
hassiebbot/fix-duplicate-otel-mask-batches
Aug 6, 2026
Merged

fix(otel): keep last duplicate span in masking batches#1803
hassiebp merged 5 commits into
mainfrom
hassiebbot/fix-duplicate-otel-mask-batches

Conversation

@hassiebp

@hassiebp hassiebp commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

What changed

  • keep the last span when a mask_otel_spans export batch contains duplicate (trace_id, span_id) identifiers
  • preserve unrelated spans and apply masking patches to the retained duplicate
  • emit one warning with duplicate and remaining-span counts
  • document the keep-last masking contract
  • add exporter-local regression coverage

Why

The masking hook exposes each batch as a mapping keyed by trace and span ID. Previously, one duplicate identifier caused the SDK to report export success without calling the underlying exporter, silently dropping the entire batch. Replay-safe deterministic instrumentation such as Temporal workflows can legitimately produce this condition.

Linear: LFE-14818

Validation

  • uv run --frozen pytest -q tests/unit/test_mask_otel_spans.py — 51 passed
  • uv run --frozen ruff check .
  • uv run --frozen ruff format --check .
  • uv run --frozen mypy langfuse --no-error-summary
  • commit pre-commit hooks: ruff check, ruff format, mypy

Greptile Summary

The PR changes OpenTelemetry masking batches to retain the last span for each duplicate trace/span identifier instead of dropping the entire batch.

  • Deduplicates valid spans before invoking the masking callback.
  • Preserves unrelated spans and applies masking patches to retained duplicates.
  • Emits one aggregate warning with duplicate and remaining-span counts.
  • Documents and tests the keep-last callback contract.

Confidence Score: 5/5

The PR appears safe to merge because no concrete blocking or independently actionable non-blocking issue was identified.

The new path deterministically retains the final valid span for each duplicate identifier, preserves unrelated spans, applies patches to the retained span, and exports the resulting batch as documented.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[OTel export batch] --> B[Process span attributes and media]
  B --> C[Discard spans with invalid context]
  C --> D[Key spans by trace ID and span ID]
  D --> E{Duplicate identifier?}
  E -->|Yes| F[Replace prior entry with last span]
  E -->|No| G[Retain span]
  F --> H[Emit aggregate warning]
  G --> I[Build masking callback parameters]
  H --> I
  I --> J[Apply returned patches]
  J --> K[Clone retained spans]
  K --> L[Underlying exporter]
Loading

Reviews (1): Last reviewed commit: "fix(otel): keep last duplicate span in m..." | Re-trigger Greptile

Context used:

@hassiebp
hassiebp marked this pull request as ready for review August 6, 2026 09:01
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

@claude review

@blacksmith-sh

This comment has been minimized.

@hassiebp
hassiebp merged commit 98653a2 into main Aug 6, 2026
19 checks passed
@hassiebp
hassiebp deleted the hassiebbot/fix-duplicate-otel-mask-batches branch August 6, 2026 09: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