feat(trace-utils): add v1-native OTLP encoder brick - #2369
Conversation
Isolated brick for APMSP-2812: adds map_traces_to_otlp_v1, mapping v1::TraceChunk/v1::Span directly to the prost OTLP IR with no hex/decimal round trip and no meta/metrics flatten. Bumps build_resource and proto_kv to pub(super) so mapper_v1 can reuse them. 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: 627ba5d | Docs | View more details | Give us feedback! |
BenchmarksComparisonBenchmark execution time: 2026-09-01 13:32:56 Comparing candidate commit 627ba5d in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 141 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.
Pull request overview
This PR adds a v1-native OTLP encoder “brick” to libdd-trace-utils, enabling direct mapping from v1::TraceChunk / v1::Span into the prost OTLP trace IR as groundwork for migrating the exporter’s canonical internal type from v0.4 to v1.
Changes:
- Add
otlp_encoder::map_traces_to_otlp_v1and a newmapper_v1module implementing v1-native mapping (including typed/nested attribute support). - Re-export the new mapper from
otlp_encoder::mod.rs. - Promote shared helpers in the existing v0.4 mapper (
build_resource,proto_kv) topub(super)for reuse.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| libdd-trace-utils/src/otlp_encoder/mod.rs | Exposes the new v1 mapper module and re-exports map_traces_to_otlp_v1. |
| libdd-trace-utils/src/otlp_encoder/mapper.rs | Makes resource/kv helpers pub(super) so mapper_v1 can reuse them. |
| libdd-trace-utils/src/otlp_encoder/mapper_v1.rs | Implements v1-native chunk/span → OTLP mapping plus unit tests. |
Suppressed comments (1)
libdd-trace-utils/src/otlp_encoder/mapper_v1.rs:85
- Same ordering issue as above: iterating
span.attributes.defensive_dedup().iter()can produce nondeterministic key order when the map isn't already marked deduped. Iteratingspan.attributes.iter()keeps a stable, predictable order whilemerged.insert(...)still ensures span values win on collisions.
for (k, v) in span.attributes.defensive_dedup().iter() {
let key = (*k).borrow();
if merged.insert(key, v).is_none() {
order.push(key);
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| // OTLP timestamps are unsigned; clamp negatives to 0 so the `as u64` cast can't wrap. | ||
| start_time_unix_nano: span.start.max(0) as u64, | ||
| end_time_unix_nano: (span.start + span.duration).max(0) as u64, |
| for (k, v) in chunk.attributes.defensive_dedup().iter() { | ||
| let key = (*k).borrow(); | ||
| if merged.insert(key, v).is_none() { | ||
| order.push(key); | ||
| } | ||
| } |
| fn bs(s: &str) -> BytesString { | ||
| BytesString::from_static(Box::leak(s.to_string().into_boxed_str())) | ||
| } |
What does this PR do?
Adds a v1-native equivalent of the existing v0.4 OTLP mapper, as groundwork for making
v1::Span/v1::TraceChunkthe exporter's canonical internal type:otlp_encoder::map_traces_to_otlp_v1(libdd-trace-utils), mappingv1::TraceChunk/v1::Spandirectly to the prost OTLP IRNothing 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 — this function isn't called anywhere yet, so there's no regression risk. Also bumps
build_resource/proto_kvin the existing v0.4 mapper to pub(super) so the v1 mapper can reuse them without duplicating that logic.