fix(otlp): preserve unknown span fields in traces when no policy matches - #298
Open
detail-app[bot] wants to merge 1 commit into
Open
detail-app[bot] wants to merge 1 commit into
detail-app[bot] wants to merge 1 commit into
Conversation
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a narrow OTLP trace bug fix that preserves unknown JSON and protobuf span fields only when no filtering or transformation occurs, while retaining re-encoding for modified payloads. Regression tests cover both formats and the drop-policy path, with no schema or infrastructure changes. You can add or adjust custom eligibility rules. Learn more. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Detail bug report: View on Detail
Bug
When trace policies are loaded, the OTLP traces pipeline (
processJsonTracesandprocessProtobufTracesinsrc/signals/otlp/traces.zig) re-encoded the decodedTracesDataunconditionally afterfilterSpansInPlace. Because decoding drops schema-unknown span-level fields — JSON viaignore_unknown_fields = true, protobuf because the generatedSpanstruct has no_unknown_fields— every re-encode silently stripped any span-level field absent from the compiled proto whenever no span matched a policy (the common no-match regime). This was a parity gap with the OTLP logs path (processJsonLogs/processProtobufLogsinsrc/signals/otlp/logs.zig), which already guarded against this. Introduced when the traces functions were first created in #89.This is forward-compatibility-only: no current OTLP v1.1 span-level field is stripped (the pinned
policy_zig0.7.3Spanincludes all of them). The defect affects vendor-extension top-level/nested span fields and any future OTLP span-level additions untilpolicy_zigis rebuilt.Fixes ENG-699
Fix
Added the same "nothing modified → return original bytes" fast path to both traces functions, mirroring the OTLP logs-path siblings. When
filterSpansInPlacereportsdropped_count == 0 and !was_transformed, the original input bytes are copied into a fresh allocation and returned without re-encoding, preserving unknown fields byte-for-byte.This closes the no-match / no-transform regime (the demonstrated defect and the logs-parity gap). The match+transform regime (e.g. sampling-threshold tracestate writeback setting
was_transformed = true) still re-encodes — the same acknowledged limitation as the logs path; fully resolving it would require enabling_unknown_fieldsin the generated proto structs, which is out of scope here.Testing
zig build test --summary all, Debug and ReleaseSafe): 522 pass, 1 pre-existing skip, 0 failures. Added 3 regression tests covering both paths and the negative case:dropped_count > 0).task lint(zig fmt --check+ziglint) clean;zig buildandzig build -Doptimize=ReleaseSafesucceed.bench/scaling/test-equivalence.sh, POLICY_COUNT=0): Edge and otelcol forward an equal number of logs/traces/metrics records with no semantic divergence.futureOtelFieldand a protobuf span with unknown field 999 produced forwarded bodies byte-equal to the input, with the unknown fields intact on both/v1/tracespaths.One
task signoffstep could not be verified:gh signoff -frequires thebasecamp/gh-signoffGitHub CLI extension, which failed to install with HTTP 401 (invalid GitHub token in this environment). All other signoff components (task do,task build:safe,task test:s3-e2eagainst MinIO) passed.Automatic Fixes PRs can be configured here.