feat(data-pipeline): add runtime-independent request preparation - #2389
feat(data-pipeline): add runtime-independent request preparation#2389rochdev wants to merge 4 commits into
Conversation
📚 Documentation Check Results📦
|
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: 322d933 | Docs | View more details | Give us feedback! |
🔒 Cargo Deny Results📦
|
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
|
BenchmarksComparisonBenchmark execution time: 2026-08-23 03:28:32 Comparing candidate commit 322d933 in PR branch Found 8 performance improvements and 8 performance regressions! Performance is the same for 136 metrics, 0 unstable metrics.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fc9ff139a3
ℹ️ 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".
| pub const DEFAULT_AGENTLESS_TIMEOUT: Duration = Duration::from_secs(15); | ||
|
|
||
| /// Agentless trace request configuration. | ||
| #[derive(Clone, Debug)] |
There was a problem hiding this comment.
Redact credentials from agentless debug output
Whenever a caller logs AgentlessTraceConfig with {:?}, the derived implementation now prints the raw api_key; the deleted implementation explicitly replaced this value with <redacted>. The same exposure propagates through PreparedAgentlessRequest because PreparedRequest also derives Debug over its headers (including dd-api-key) and trace payload, so routine diagnostics can leak both credentials and customer trace data. Preserve a custom redacting Debug implementation for these public types instead of deriving it.
Useful? React with 👍 / 👎.
| Ok(PreparedAgentlessRequest { | ||
| request: PreparedRequest::new(target, json_body, headers, compression_strategy), | ||
| retry_strategy, |
There was a problem hiding this comment.
Add the configured API key to pre-encoded requests
When a host uses the newly public prepare_agentless_json_request entry point with an ordinary metadata/trace-count header map, this passes those headers through unchanged and never uses config.api_key, so the resulting request lacks dd-api-key and the intake rejects it. The other preparation entry points add this required header, and the configuration field is documented as supplying it; this low-level entry point should also inject the configured key (or explicitly require and validate an already-authenticated header map).
Useful? React with 👍 / 👎.
| let trace_count = traces.len(); | ||
| let json_body = libdd_trace_utils::agentless_encoder::encode_payload(&traces, metadata) | ||
| .map_err(PrepareAgentlessError::Serialization)?; |
There was a problem hiding this comment.
Compute top-level flags for decoded-trace callers
When callers use the public prepare_agentless_traces_request directly with metadata.client_computed_top_level == false, the traces are encoded immediately without running compute_top_level_span, so the agentless JSON omits the _top_level metrics that the byte-oriented entry point and existing exporter deliberately add. Move that normalization into this shared decoded-trace function so both public preparation paths produce equivalent payloads.
Useful? React with 👍 / 👎.
| #[cfg(not(target_arch = "wasm32"))] | ||
| #[cfg(feature = "http-client")] | ||
| pub mod connector; |
There was a problem hiding this comment.
Keep non-TLS connector consumers buildable
On native builds that disable default/TLS features, gating the entire connector module behind http-client removes even the UDS/named-pipe helpers used by existing consumers: libdd-dogstatsd-client/src/client/sink.rs imports connector::uds while depending on libdd-common with default features off, and libdd-http-client's hyper-backend feature activates libdd-common but not libdd-common/http-client. Those supported feature combinations now fail to compile; either keep the transport URI helpers available without the HTTP stack or propagate http-client from every feature that compiles these consumers.
Useful? React with 👍 / 👎.
fc9ff13 to
1c04286
Compare
1c04286 to
52dfcbb
Compare
bengl
left a comment
There was a problem hiding this comment.
Seems fine to me, but @DataDog/apm-common-components-core should probably review.
Implementation changed significantly to keep retries on the Rust side.
What does this PR do?
Adds a new
libdd-data-pipeline-corecrate that prepares agentless APMrequests without owning an async executor or HTTP client. It exposes the
prepared request to host-managed bindings while reusing
libdd-trace-utils::send_with_retryso retries, per-attempt timeouts, andbackoff remain shared Rust behavior.
The host supplies only the HTTP and sleep capabilities and drives the returned
future on the executor appropriate for its target. The existing
libdd-data-pipelineexporter continues to use the same preparation and retryimplementation through its native capabilities.
This also makes the native HTTP stack in
libdd-commonand the runtime-backeddependencies in
libdd-trace-utilsopt-in. Host-managed native and WASMbindings can therefore share the same runtime-independent core dependency
graph.
Motivation
Language bindings need native and WASM implementations with identical
pipeline behavior without pulling the full exporter runtime, stats, telemetry,
and worker machinery into artifacts that only need agentless request
processing. Keeping retry and timeout policy in Rust avoids duplicating those
semantics in every host binding.
Additional Notes
The existing executor-owned
libdd-data-pipelineAPI remains available andreuses the same core implementation.
Sensitive API keys, headers, and request bodies are redacted from debug output.
This PR was generated by Codex.
How to test the change?
cargo +nightly-2026-07-26 fmt --all -- --checkcargo test -p libdd-data-pipeline-core --features compressioncargo test -p libdd-trace-utils prepared_request_debug_redacts_sensitive_datacargo +stable clippy -p libdd-data-pipeline-core --features compression --all-targets --no-deps -- -D warningscargo +stable clippy -p libdd-data-pipeline --features compression --all-targets --no-deps -- -D warningscargo check -p libdd-dogstatsd-client --no-default-featurescargo check -p libdd-http-client --no-default-features --features hyper-backendcargo tree -p libdd-data-pipeline-core --features compression --edges normalThe host-managed core dependency tree contains no Tokio, Hyper, Rustls,
libdd-shared-runtime, orlibdd-capabilities-impldependencies.