feat(trace-utils): add v1-native agentless JSON encoder brick - #2370
feat(trace-utils): add v1-native agentless JSON encoder brick#2370anais-raison wants to merge 7 commits into
Conversation
Isolated brick for APMSP-2812: adds encode_payload_from_v1 and its v1::Span-native helpers (collect_attrs_v1, flatten_attr_into_v1, encode_span_link_v1, encode_span_event_v1) alongside the existing v0.4 agentless encoder. Not wired into any live send path yet.
📚 Documentation Check Results📦
|
🔒 Cargo Deny Results📦
|
|
✅ All CI checks and tests passed. 🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: ec1bf49 | Docs | View more details | Give us feedback! |
BenchmarksComparisonBenchmark execution time: 2026-08-28 13:53:24 Comparing candidate commit ec1bf49 in PR branch Found 0 performance improvements and 2 performance regressions! Performance is the same for 138 metrics, 0 unstable metrics.
|
Artifact Size Benchmark Reportaarch64-alpine-linux-musl
aarch64-unknown-linux-gnu
libdatadog-x64-windows
libdatadog-x86-windows
x86_64-alpine-linux-musl
x86_64-unknown-linux-gnu
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1fbc4b65b4
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| attrs.serialize_entry(key, &ser_fn!(<T: TraceData> |ser, v: &'a AttributeValueV1<T>| { | ||
| encode_event_attr_value_v1(ser, v) |
There was a problem hiding this comment.
Emit raw JSON values for event attributes
When a v1 span event contains any scalar or list attribute, this emits the v0.4 MessagePack wrapper (for example, {"type":0,"string_value":"timeout"}) inside the JSON-stringified events value. The existing agentless encoder's encode_span_event emits the attribute directly as "timeout" (and lists as plain JSON arrays), which is the schema consumed by the agentless intake; once this path is wired in, event attributes will therefore be misinterpreted rather than remaining equivalent to the v0.4 agentless output.
Useful? React with 👍 / 👎.
| .filter(|(k, _)| !PROMOTED_ATTR_KEYS_V1.contains(&(*k).borrow())) | ||
| .chain(chunk_attrs_dd.iter().filter(|(k, _)| { | ||
| !PROMOTED_ATTR_KEYS_V1.contains(&(*k).borrow()) |
There was a problem hiding this comment.
Filter promoted names after flattening attributes
When a structured attribute flattens to a reserved name—for example, attribute span = {kind: "client"} alongside span_kind = Server, or _dd = {origin: ...}—this filter does not recognize the collision because it checks only the unflattened top-level key. The resulting leaf is serialized after the dedicated field, producing duplicate JSON keys that commonly resolve to the attribute value and violate the stated dedicated-field-wins behavior; filter the flattened leaves against the promoted-key set as well.
Useful? React with 👍 / 👎.
What does this PR do?
Adds a v1-native equivalent of the existing v0.4 agentless JSON encoder, as groundwork for making
v1::Span/v1::TraceChunkthe exporter's canonical internal type:agentless_encoder::encode_payload_from_v1and its helpers (collect_attrs_v1,flatten_attr_into_v1,encode_span_link_v1,encode_span_event_v1) (libdd-trace-utils)Nothing is wired into the live pipeline yet.
Motivation
Part of APMSP-2812: migration of the exporter from v0.4 to v1 with isolated bricks first before one final breaking PR that will handle the actual swap.
Additional Notes
Pure addition, no behavior change — these functions aren't called anywhere yet, so there's no regression risk.