Skip to content

feat(data-pipeline): OTLP HTTP/protobuf trace export#2115

Open
bm1549 wants to merge 40 commits into
mainfrom
brian.marks/otlp-http-protobuf-export
Open

feat(data-pipeline): OTLP HTTP/protobuf trace export#2115
bm1549 wants to merge 40 commits into
mainfrom
brian.marks/otlp-http-protobuf-export

Conversation

@bm1549

@bm1549 bm1549 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds OTLP HTTP/protobuf as a trace-export encoding alongside HTTP/JSON, selectable via the OTel-standard OTEL_EXPORTER_OTLP_TRACES_PROTOCOL (http/json default, http/protobuf). The generated prost OTLP types are the single intermediate representation: the mapper builds them directly from native spans, protobuf is prost::encode_to_vec, and JSON is a serde serializer over the same types.

Motivation

libdatadog's OTLP trace export only spoke HTTP/JSON. SDKs that honor OTEL_EXPORTER_OTLP_TRACES_PROTOCOL need http/protobuf to match the OTel default and to talk to collectors that expect protobuf.

Additional Notes

  • Prost is the single IR: no parallel hand-rolled JSON model, no string round-trip. encode_otlp_protobuf is encode_to_vec; encode_otlp_json is a serde serializer (json_serializer.rs) emitting OTLP-spec JSON (hex ids, base64 bytes, int64-as-string, lowerCamelCase, proto3 defaults omitted).
  • OtlpProtocol is {HttpJson, HttpProtobuf}; grpc is rejected at the parse boundary (FromStr) rather than carried as an unsupported variant. content_type()/encode() live on the type.
  • Integrates with the OTLP metrics exporter already on main: the shared low-level sender takes the content-type per request, so traces use the configured protocol while metrics stay JSON.
  • Carries through otel_trace_semantics_enabled (OTel attribute compatibility, feat(otlp)!: Export OTLP spans with attribute-level OTel compatibility #2091): when set, the prost mapper omits the DD-specific span attributes and promotes the error message to the OTLP Status.
  • Span-link W3C trace flags are carried through to OTLP Link.flags.
  • Benchmarks for the encoder hot paths, plus allocation tuning (pre-sized Vecs, allocation-free id/timestamp/int serialization).

How to test the change?

  • cargo test -p libdd-trace-utils -p libdd-data-pipeline -p libdd-data-pipeline-ffi, cargo test --doc, clippy, fmt, and cargo ffi-test pass. A parity test asserts the JSON and protobuf encodings carry the same span from the one prost IR; a protobuf round-trip test asserts the encoding is lossless.
  • End-to-end through dd-trace-py (feat(otlp): support http/protobuf OTLP trace export dd-trace-py#18609): emitted protobuf-only OTLP traces through a local Agent to the backend. Wire was application/x-protobuf (HTTP 200), spans ingested with correct service/resource and a preserved 128-bit trace id.
  • Benchmarks: cargo bench -p libdd-trace-utils --bench main -- otlp/.

BREAKING CHANGE: removes the previously public libdd_trace_utils::otlp_encoder::json_types module (the hand-rolled OTLP JSON model). OTLP encoding now builds prost-generated types as the single IR. libdatadog consumers pin by version, so they pick this up on the next release.

bm1549 and others added 15 commits June 12, 2026 14:09
Records the approved design: vendor OTLP trace + collector protos and
generate prost types (zero new runtime deps), keep the hand-rolled serde
JSON path, share one mapper with a serde->prost converter, and select the
protocol via builder + C FFI. Includes the dd-trace-py companion wiring
and the layered E2E plan (local receiver, system-tests, sdk-backend-verify).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bite-sized, TDD-structured plan across 9 phases: vendor+generate prost
types, serde->prost converter, encoder dispatch, protocol config through
builder + C FFI, full validation gauntlet + libdatadog PR, then dd-trace-py
PyO3/writer wiring and three E2E tiers (local receiver, system-tests,
sdk-backend-verify) + dd-trace-py PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Vendors opentelemetry/proto/trace/v1/trace.proto and
opentelemetry/proto/collector/trace/v1/trace_service.proto from
open-telemetry/opentelemetry-proto commit 1e725b853bc8f6b46ee62e8232e4c83017b9536f
(matching the already-vendored common.proto and resource.proto).

Adds both protos to the prost_build compile list in build.rs, generates
the committed Rust types (opentelemetry.proto.trace.v1.rs and
opentelemetry.proto.collector.trace.v1.rs), and updates _includes.rs.

Also qualifies "Span" → "pb.Span" / "pb.idx.Span" in build.rs
type_attribute calls to prevent serde derives from leaking into the
new opentelemetry::proto::trace::v1::Span type.
…ests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-type match

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bm1549 bm1549 added the AI Generated PR largely written by AI tools label Jun 12, 2026
@datadog-datadog-prod-us1

datadog-datadog-prod-us1 Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 83.80%
Overall Coverage: 73.96% (-0.10%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 80aad24 | Docs | Datadog PR Page | Give us feedback!

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

📚 Documentation Check Results

⚠️ 3055 documentation warning(s) found

📦 libdd-data-pipeline-ffi - 1210 warning(s)

📦 libdd-data-pipeline - 1099 warning(s)

📦 libdd-trace-protobuf - 121 warning(s)

📦 libdd-trace-utils - 625 warning(s)


Updated: 2026-06-23 20:57:05 UTC | Commit: 023c89f | missing-docs job results

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Clippy Allow Annotation Report

Comparing clippy allow annotations between branches:

  • Base Branch: origin/main
  • PR Branch: origin/brian.marks/otlp-http-protobuf-export

Summary by Rule

Rule Base Branch PR Branch Change
unwrap_used 3 3 No change (0%)
Total 3 3 No change (0%)

Annotation Counts by File

File Base Branch PR Branch Change
libdd-data-pipeline/src/otlp/metrics.rs 1 1 No change (0%)
libdd-data-pipeline/src/trace_exporter/mod.rs 2 2 No change (0%)

Annotation Stats by Crate

Crate Base Branch PR Branch Change
clippy-annotation-reporter 5 5 No change (0%)
datadog-ffe-ffi 1 1 No change (0%)
datadog-ipc 22 22 No change (0%)
datadog-live-debugger 4 4 No change (0%)
datadog-live-debugger-ffi 10 10 No change (0%)
datadog-profiling-replayer 4 4 No change (0%)
datadog-sidecar 45 45 No change (0%)
libdd-common 13 13 No change (0%)
libdd-common-ffi 12 12 No change (0%)
libdd-data-pipeline 6 6 No change (0%)
libdd-ddsketch 2 2 No change (0%)
libdd-dogstatsd-client 1 1 No change (0%)
libdd-profiling 13 13 No change (0%)
libdd-remote-config 3 3 No change (0%)
libdd-telemetry 20 20 No change (0%)
libdd-tinybytes 4 4 No change (0%)
libdd-trace-normalization 2 2 No change (0%)
libdd-trace-obfuscation 3 3 No change (0%)
libdd-trace-stats 1 1 No change (0%)
libdd-trace-utils 11 11 No change (0%)
Total 182 182 No change (0%)

About This Report

This report tracks Clippy allow annotations for specific rules, showing how they've changed in this PR. Decreasing the number of these annotations generally improves code quality.

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

🔒 Cargo Deny Results

⚠️ 14 issue(s) found, showing only errors (advisories, bans, sources)

📦 libdd-data-pipeline-ffi - 5 error(s)

Show output
error[unsound]: Rand is unsound with a custom logger using `rand::rng()`
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:226:1
    │
226 │ rand 0.8.5 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
    │
    ├ ID: RUSTSEC-2026-0097
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0097
    ├ It has been reported (by @lopopolo) that the `rand` library is [unsound](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library) (i.e. that safe code using the public API can cause Undefined Behaviour) when all the following conditions are met:
      
      - The `log` and `thread_rng` features are enabled
      - A [custom logger](https://docs.rs/log/latest/log/#implementing-a-logger) is defined
      - The custom logger accesses `rand::rng()` (previously `rand::thread_rng()`) and calls any `TryRng` (previously `RngCore`) methods on `ThreadRng`
      - The `ThreadRng` (attempts to) reseed while called from the custom logger (this happens every 64 kB of generated data)
      - Trace-level logging is enabled or warn-level logging is enabled and the random source (the `getrandom` crate) is unable to provide a new seed
      
      `TryRng` (previously `RngCore`) methods for `ThreadRng` use `unsafe` code to cast `*mut BlockRng<ReseedingCore>` to `&mut BlockRng<ReseedingCore>`. When all the above conditions are met this results in an aliased mutable reference, violating the Stacked Borrows rules. Miri is able to detect this violation in sample code. Since construction of [aliased mutable references is Undefined Behaviour](https://doc.rust-lang.org/stable/nomicon/references.html), the behaviour of optimized builds is hard to predict.
    ├ Announcement: https://github.com/rust-random/rand/pull/1763
    ├ Solution: Upgrade to >=0.10.1 OR <0.10.0, >=0.9.3 OR <0.9.0, >=0.8.6 (try `cargo update -p rand`)
    ├ rand v0.8.5
      ├── libdd-common v5.0.0
      │   ├── libdd-capabilities-impl v2.0.0
      │   │   ├── libdd-data-pipeline v6.0.0
      │   │   │   └── libdd-data-pipeline-ffi v36.0.0
      │   │   ├── libdd-data-pipeline-ffi v36.0.0 (*)
      │   │   ├── libdd-shared-runtime v1.0.0
      │   │   │   ├── libdd-data-pipeline v6.0.0 (*)
      │   │   │   ├── libdd-data-pipeline-ffi v36.0.0 (*)
      │   │   │   ├── libdd-telemetry v5.0.1
      │   │   │   │   └── libdd-data-pipeline v6.0.0 (*)
      │   │   │   └── libdd-trace-stats v5.0.0
      │   │   │       └── libdd-data-pipeline v6.0.0 (*)
      │   │   ├── libdd-trace-stats v5.0.0 (*)
      │   │   └── libdd-trace-utils v8.0.0
      │   │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── (dev) libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       ├── libdd-trace-obfuscation v4.0.0
      │   │       │   └── libdd-trace-stats v5.0.0 (*)
      │   │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   ├── libdd-common-ffi v36.0.0
      │   │   └── libdd-data-pipeline-ffi v36.0.0 (*)
      │   ├── libdd-data-pipeline v6.0.0 (*)
      │   ├── libdd-dogstatsd-client v3.0.0
      │   │   └── libdd-data-pipeline v6.0.0 (*)
      │   ├── libdd-shared-runtime v1.0.0 (*)
      │   ├── libdd-telemetry v5.0.1 (*)
      │   ├── libdd-trace-obfuscation v4.0.0 (*)
      │   ├── libdd-trace-stats v5.0.0 (*)
      │   └── libdd-trace-utils v8.0.0 (*)
      ├── (dev) libdd-data-pipeline v6.0.0 (*)
      ├── (dev) libdd-ddsketch v1.0.1
      │   ├── libdd-data-pipeline v6.0.0 (*)
      │   ├── libdd-telemetry v5.0.1 (*)
      │   └── libdd-trace-stats v5.0.0 (*)
      ├── (dev) libdd-trace-normalization v2.0.0
      │   ├── libdd-data-pipeline v6.0.0 (*)
      │   └── libdd-trace-utils v8.0.0 (*)
      ├── (dev) libdd-trace-stats v5.0.0 (*)
      ├── libdd-trace-utils v8.0.0 (*)
      └── proptest v1.5.0
          └── (dev) libdd-tinybytes v1.1.1
              ├── libdd-data-pipeline v6.0.0 (*)
              ├── libdd-data-pipeline-ffi v36.0.0 (*)
              ├── (dev) libdd-tinybytes v1.1.1 (*)
              └── libdd-trace-utils v8.0.0 (*)

error[vulnerability]: Name constraints for URI names were incorrectly accepted
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:253:1
    │
253 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0098
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0098
    ├ Name constraints for URI names were ignored and therefore accepted.
      
      Note this library does not provide an API for asserting URI names, and URI name constraints are otherwise not implemented.  URI name constraints are now rejected unconditionally.
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-965h-392x-2mh5](https://github.com/rustls/webpki/security/advisories/GHSA-965h-392x-2mh5). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      ├── rustls v0.23.37
      │   ├── hyper-rustls v0.27.7
      │   │   └── libdd-common v5.0.0
      │   │       ├── libdd-capabilities-impl v2.0.0
      │   │       │   ├── libdd-data-pipeline v6.0.0
      │   │       │   │   └── libdd-data-pipeline-ffi v36.0.0
      │   │       │   ├── libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       │   ├── libdd-shared-runtime v1.0.0
      │   │       │   │   ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   ├── libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       │   │   ├── libdd-telemetry v5.0.1
      │   │       │   │   │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   └── libdd-trace-stats v5.0.0
      │   │       │   │       └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   ├── libdd-trace-stats v5.0.0 (*)
      │   │       │   └── libdd-trace-utils v8.0.0
      │   │       │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │       ├── (dev) libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       │       ├── libdd-trace-obfuscation v4.0.0
      │   │       │       │   └── libdd-trace-stats v5.0.0 (*)
      │   │       │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   │       ├── libdd-common-ffi v36.0.0
      │   │       │   └── libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-dogstatsd-client v3.0.0
      │   │       │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-shared-runtime v1.0.0 (*)
      │   │       ├── libdd-telemetry v5.0.1 (*)
      │   │       ├── libdd-trace-obfuscation v4.0.0 (*)
      │   │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       └── libdd-trace-utils v8.0.0 (*)
      │   ├── libdd-common v5.0.0 (*)
      │   ├── rustls-platform-verifier v0.6.2
      │   │   └── libdd-common v5.0.0 (*)
      │   └── tokio-rustls v0.26.0
      │       ├── hyper-rustls v0.27.7 (*)
      │       └── libdd-common v5.0.0 (*)
      └── rustls-platform-verifier v0.6.2 (*)

error[vulnerability]: Name constraints were accepted for certificates asserting a wildcard name
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:253:1
    │
253 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0099
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0099
    ├ Permitted subtree name constraints for DNS names were accepted for certificates asserting a wildcard name.
      
      This was incorrect because, given a name constraint of `accept.example.com`, `*.example.com` could feasibly allow a name of `reject.example.com` which is outside the constraint.
      This is very similar to [CVE-2025-61727](https://go.dev/issue/76442).
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-xgp8-3hg3-c2mh](https://github.com/rustls/webpki/security/advisories/GHSA-xgp8-3hg3-c2mh). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      ├── rustls v0.23.37
      │   ├── hyper-rustls v0.27.7
      │   │   └── libdd-common v5.0.0
      │   │       ├── libdd-capabilities-impl v2.0.0
      │   │       │   ├── libdd-data-pipeline v6.0.0
      │   │       │   │   └── libdd-data-pipeline-ffi v36.0.0
      │   │       │   ├── libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       │   ├── libdd-shared-runtime v1.0.0
      │   │       │   │   ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   ├── libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       │   │   ├── libdd-telemetry v5.0.1
      │   │       │   │   │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   └── libdd-trace-stats v5.0.0
      │   │       │   │       └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   ├── libdd-trace-stats v5.0.0 (*)
      │   │       │   └── libdd-trace-utils v8.0.0
      │   │       │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │       ├── (dev) libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       │       ├── libdd-trace-obfuscation v4.0.0
      │   │       │       │   └── libdd-trace-stats v5.0.0 (*)
      │   │       │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   │       ├── libdd-common-ffi v36.0.0
      │   │       │   └── libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-dogstatsd-client v3.0.0
      │   │       │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-shared-runtime v1.0.0 (*)
      │   │       ├── libdd-telemetry v5.0.1 (*)
      │   │       ├── libdd-trace-obfuscation v4.0.0 (*)
      │   │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       └── libdd-trace-utils v8.0.0 (*)
      │   ├── libdd-common v5.0.0 (*)
      │   ├── rustls-platform-verifier v0.6.2
      │   │   └── libdd-common v5.0.0 (*)
      │   └── tokio-rustls v0.26.0
      │       ├── hyper-rustls v0.27.7 (*)
      │       └── libdd-common v5.0.0 (*)
      └── rustls-platform-verifier v0.6.2 (*)

error[vulnerability]: Reachable panic in certificate revocation list parsing
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:253:1
    │
253 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0104
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0104
    ├ A panic was reachable when parsing certificate revocation lists via [`BorrowedCertRevocationList::from_der`]
      or [`OwnedCertRevocationList::from_der`].  This was the result of mishandling a syntactically valid empty
      `BIT STRING` appearing in the `onlySomeReasons` element of a `IssuingDistributionPoint` CRL extension.
      
      This panic is reachable prior to a CRL's signature being verified.
      
      Applications that do not use CRLs are not affected.
      
      Thank you to @tynus3 for the report.
    ├ Solution: Upgrade to >=0.103.13, <0.104.0-alpha.1 OR >=0.104.0-alpha.7 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      ├── rustls v0.23.37
      │   ├── hyper-rustls v0.27.7
      │   │   └── libdd-common v5.0.0
      │   │       ├── libdd-capabilities-impl v2.0.0
      │   │       │   ├── libdd-data-pipeline v6.0.0
      │   │       │   │   └── libdd-data-pipeline-ffi v36.0.0
      │   │       │   ├── libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       │   ├── libdd-shared-runtime v1.0.0
      │   │       │   │   ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   ├── libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       │   │   ├── libdd-telemetry v5.0.1
      │   │       │   │   │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   └── libdd-trace-stats v5.0.0
      │   │       │   │       └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   ├── libdd-trace-stats v5.0.0 (*)
      │   │       │   └── libdd-trace-utils v8.0.0
      │   │       │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │       ├── (dev) libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       │       ├── libdd-trace-obfuscation v4.0.0
      │   │       │       │   └── libdd-trace-stats v5.0.0 (*)
      │   │       │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   │       ├── libdd-common-ffi v36.0.0
      │   │       │   └── libdd-data-pipeline-ffi v36.0.0 (*)
      │   │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-dogstatsd-client v3.0.0
      │   │       │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-shared-runtime v1.0.0 (*)
      │   │       ├── libdd-telemetry v5.0.1 (*)
      │   │       ├── libdd-trace-obfuscation v4.0.0 (*)
      │   │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       └── libdd-trace-utils v8.0.0 (*)
      │   ├── libdd-common v5.0.0 (*)
      │   ├── rustls-platform-verifier v0.6.2
      │   │   └── libdd-common v5.0.0 (*)
      │   └── tokio-rustls v0.26.0
      │       ├── hyper-rustls v0.27.7 (*)
      │       └── libdd-common v5.0.0 (*)
      └── rustls-platform-verifier v0.6.2 (*)

error[vulnerability]: Denial of Service via Stack Exhaustion
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:295:1
    │
295 │ time 0.3.41 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0009
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0009
    ├ ## Impact
      
      When user-provided input is provided to any type that parses with the RFC 2822 format, a denial of
      service attack via stack exhaustion is possible. The attack relies on formally deprecated and
      rarely-used features that are part of the RFC 2822 format used in a malicious manner. Ordinary,
      non-malicious input will never encounter this scenario.
      
      ## Patches
      
      A limit to the depth of recursion was added in v0.3.47. From this version, an error will be returned
      rather than exhausting the stack.
      
      ## Workarounds
      
      Limiting the length of user input is the simplest way to avoid stack exhaustion, as the amount of
      the stack consumed would be at most a factor of the length of the input.
    ├ Announcement: https://github.com/time-rs/time/blob/main/CHANGELOG.md#0347-2026-02-05
    ├ Solution: Upgrade to >=0.3.47 (try `cargo update -p time`)
    ├ time v0.3.41
      └── tracing-appender v0.2.3
          └── libdd-log v1.0.0
              └── (dev) libdd-data-pipeline v6.0.0
                  └── libdd-data-pipeline-ffi v36.0.0

advisories FAILED, bans ok, sources ok

📦 libdd-data-pipeline - 5 error(s)

Show output
error[unsound]: Rand is unsound with a custom logger using `rand::rng()`
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:218:1
    │
218 │ rand 0.8.5 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
    │
    ├ ID: RUSTSEC-2026-0097
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0097
    ├ It has been reported (by @lopopolo) that the `rand` library is [unsound](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library) (i.e. that safe code using the public API can cause Undefined Behaviour) when all the following conditions are met:
      
      - The `log` and `thread_rng` features are enabled
      - A [custom logger](https://docs.rs/log/latest/log/#implementing-a-logger) is defined
      - The custom logger accesses `rand::rng()` (previously `rand::thread_rng()`) and calls any `TryRng` (previously `RngCore`) methods on `ThreadRng`
      - The `ThreadRng` (attempts to) reseed while called from the custom logger (this happens every 64 kB of generated data)
      - Trace-level logging is enabled or warn-level logging is enabled and the random source (the `getrandom` crate) is unable to provide a new seed
      
      `TryRng` (previously `RngCore`) methods for `ThreadRng` use `unsafe` code to cast `*mut BlockRng<ReseedingCore>` to `&mut BlockRng<ReseedingCore>`. When all the above conditions are met this results in an aliased mutable reference, violating the Stacked Borrows rules. Miri is able to detect this violation in sample code. Since construction of [aliased mutable references is Undefined Behaviour](https://doc.rust-lang.org/stable/nomicon/references.html), the behaviour of optimized builds is hard to predict.
    ├ Announcement: https://github.com/rust-random/rand/pull/1763
    ├ Solution: Upgrade to >=0.10.1 OR <0.10.0, >=0.9.3 OR <0.9.0, >=0.8.6 (try `cargo update -p rand`)
    ├ rand v0.8.5
      ├── libdd-common v5.0.0
      │   ├── libdd-capabilities-impl v2.0.0
      │   │   ├── libdd-data-pipeline v6.0.0
      │   │   ├── libdd-shared-runtime v1.0.0
      │   │   │   ├── libdd-data-pipeline v6.0.0 (*)
      │   │   │   ├── libdd-telemetry v5.0.1
      │   │   │   │   └── libdd-data-pipeline v6.0.0 (*)
      │   │   │   └── libdd-trace-stats v5.0.0
      │   │   │       └── libdd-data-pipeline v6.0.0 (*)
      │   │   ├── libdd-trace-stats v5.0.0 (*)
      │   │   └── libdd-trace-utils v8.0.0
      │   │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-trace-obfuscation v4.0.0
      │   │       │   └── libdd-trace-stats v5.0.0 (*)
      │   │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   ├── libdd-data-pipeline v6.0.0 (*)
      │   ├── libdd-dogstatsd-client v3.0.0
      │   │   └── libdd-data-pipeline v6.0.0 (*)
      │   ├── libdd-shared-runtime v1.0.0 (*)
      │   ├── libdd-telemetry v5.0.1 (*)
      │   ├── libdd-trace-obfuscation v4.0.0 (*)
      │   ├── libdd-trace-stats v5.0.0 (*)
      │   └── libdd-trace-utils v8.0.0 (*)
      ├── (dev) libdd-data-pipeline v6.0.0 (*)
      ├── (dev) libdd-ddsketch v1.0.1
      │   ├── libdd-data-pipeline v6.0.0 (*)
      │   ├── libdd-telemetry v5.0.1 (*)
      │   └── libdd-trace-stats v5.0.0 (*)
      ├── (dev) libdd-trace-normalization v2.0.0
      │   ├── libdd-data-pipeline v6.0.0 (*)
      │   └── libdd-trace-utils v8.0.0 (*)
      ├── (dev) libdd-trace-stats v5.0.0 (*)
      ├── libdd-trace-utils v8.0.0 (*)
      └── proptest v1.5.0
          └── (dev) libdd-tinybytes v1.1.1
              ├── libdd-data-pipeline v6.0.0 (*)
              ├── (dev) libdd-tinybytes v1.1.1 (*)
              └── libdd-trace-utils v8.0.0 (*)

error[vulnerability]: Name constraints for URI names were incorrectly accepted
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:245:1
    │
245 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0098
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0098
    ├ Name constraints for URI names were ignored and therefore accepted.
      
      Note this library does not provide an API for asserting URI names, and URI name constraints are otherwise not implemented.  URI name constraints are now rejected unconditionally.
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-965h-392x-2mh5](https://github.com/rustls/webpki/security/advisories/GHSA-965h-392x-2mh5). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      ├── rustls v0.23.37
      │   ├── hyper-rustls v0.27.7
      │   │   └── libdd-common v5.0.0
      │   │       ├── libdd-capabilities-impl v2.0.0
      │   │       │   ├── libdd-data-pipeline v6.0.0
      │   │       │   ├── libdd-shared-runtime v1.0.0
      │   │       │   │   ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   ├── libdd-telemetry v5.0.1
      │   │       │   │   │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   └── libdd-trace-stats v5.0.0
      │   │       │   │       └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   ├── libdd-trace-stats v5.0.0 (*)
      │   │       │   └── libdd-trace-utils v8.0.0
      │   │       │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │       ├── libdd-trace-obfuscation v4.0.0
      │   │       │       │   └── libdd-trace-stats v5.0.0 (*)
      │   │       │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-dogstatsd-client v3.0.0
      │   │       │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-shared-runtime v1.0.0 (*)
      │   │       ├── libdd-telemetry v5.0.1 (*)
      │   │       ├── libdd-trace-obfuscation v4.0.0 (*)
      │   │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       └── libdd-trace-utils v8.0.0 (*)
      │   ├── libdd-common v5.0.0 (*)
      │   ├── rustls-platform-verifier v0.6.2
      │   │   └── libdd-common v5.0.0 (*)
      │   └── tokio-rustls v0.26.0
      │       ├── hyper-rustls v0.27.7 (*)
      │       └── libdd-common v5.0.0 (*)
      └── rustls-platform-verifier v0.6.2 (*)

error[vulnerability]: Name constraints were accepted for certificates asserting a wildcard name
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:245:1
    │
245 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0099
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0099
    ├ Permitted subtree name constraints for DNS names were accepted for certificates asserting a wildcard name.
      
      This was incorrect because, given a name constraint of `accept.example.com`, `*.example.com` could feasibly allow a name of `reject.example.com` which is outside the constraint.
      This is very similar to [CVE-2025-61727](https://go.dev/issue/76442).
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-xgp8-3hg3-c2mh](https://github.com/rustls/webpki/security/advisories/GHSA-xgp8-3hg3-c2mh). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      ├── rustls v0.23.37
      │   ├── hyper-rustls v0.27.7
      │   │   └── libdd-common v5.0.0
      │   │       ├── libdd-capabilities-impl v2.0.0
      │   │       │   ├── libdd-data-pipeline v6.0.0
      │   │       │   ├── libdd-shared-runtime v1.0.0
      │   │       │   │   ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   ├── libdd-telemetry v5.0.1
      │   │       │   │   │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   └── libdd-trace-stats v5.0.0
      │   │       │   │       └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   ├── libdd-trace-stats v5.0.0 (*)
      │   │       │   └── libdd-trace-utils v8.0.0
      │   │       │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │       ├── libdd-trace-obfuscation v4.0.0
      │   │       │       │   └── libdd-trace-stats v5.0.0 (*)
      │   │       │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-dogstatsd-client v3.0.0
      │   │       │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-shared-runtime v1.0.0 (*)
      │   │       ├── libdd-telemetry v5.0.1 (*)
      │   │       ├── libdd-trace-obfuscation v4.0.0 (*)
      │   │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       └── libdd-trace-utils v8.0.0 (*)
      │   ├── libdd-common v5.0.0 (*)
      │   ├── rustls-platform-verifier v0.6.2
      │   │   └── libdd-common v5.0.0 (*)
      │   └── tokio-rustls v0.26.0
      │       ├── hyper-rustls v0.27.7 (*)
      │       └── libdd-common v5.0.0 (*)
      └── rustls-platform-verifier v0.6.2 (*)

error[vulnerability]: Reachable panic in certificate revocation list parsing
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:245:1
    │
245 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0104
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0104
    ├ A panic was reachable when parsing certificate revocation lists via [`BorrowedCertRevocationList::from_der`]
      or [`OwnedCertRevocationList::from_der`].  This was the result of mishandling a syntactically valid empty
      `BIT STRING` appearing in the `onlySomeReasons` element of a `IssuingDistributionPoint` CRL extension.
      
      This panic is reachable prior to a CRL's signature being verified.
      
      Applications that do not use CRLs are not affected.
      
      Thank you to @tynus3 for the report.
    ├ Solution: Upgrade to >=0.103.13, <0.104.0-alpha.1 OR >=0.104.0-alpha.7 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      ├── rustls v0.23.37
      │   ├── hyper-rustls v0.27.7
      │   │   └── libdd-common v5.0.0
      │   │       ├── libdd-capabilities-impl v2.0.0
      │   │       │   ├── libdd-data-pipeline v6.0.0
      │   │       │   ├── libdd-shared-runtime v1.0.0
      │   │       │   │   ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   ├── libdd-telemetry v5.0.1
      │   │       │   │   │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   │   └── libdd-trace-stats v5.0.0
      │   │       │   │       └── libdd-data-pipeline v6.0.0 (*)
      │   │       │   ├── libdd-trace-stats v5.0.0 (*)
      │   │       │   └── libdd-trace-utils v8.0.0
      │   │       │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       │       ├── libdd-trace-obfuscation v4.0.0
      │   │       │       │   └── libdd-trace-stats v5.0.0 (*)
      │   │       │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   │       ├── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-dogstatsd-client v3.0.0
      │   │       │   └── libdd-data-pipeline v6.0.0 (*)
      │   │       ├── libdd-shared-runtime v1.0.0 (*)
      │   │       ├── libdd-telemetry v5.0.1 (*)
      │   │       ├── libdd-trace-obfuscation v4.0.0 (*)
      │   │       ├── libdd-trace-stats v5.0.0 (*)
      │   │       └── libdd-trace-utils v8.0.0 (*)
      │   ├── libdd-common v5.0.0 (*)
      │   ├── rustls-platform-verifier v0.6.2
      │   │   └── libdd-common v5.0.0 (*)
      │   └── tokio-rustls v0.26.0
      │       ├── hyper-rustls v0.27.7 (*)
      │       └── libdd-common v5.0.0 (*)
      └── rustls-platform-verifier v0.6.2 (*)

error[vulnerability]: Denial of Service via Stack Exhaustion
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:286:1
    │
286 │ time 0.3.41 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0009
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0009
    ├ ## Impact
      
      When user-provided input is provided to any type that parses with the RFC 2822 format, a denial of
      service attack via stack exhaustion is possible. The attack relies on formally deprecated and
      rarely-used features that are part of the RFC 2822 format used in a malicious manner. Ordinary,
      non-malicious input will never encounter this scenario.
      
      ## Patches
      
      A limit to the depth of recursion was added in v0.3.47. From this version, an error will be returned
      rather than exhausting the stack.
      
      ## Workarounds
      
      Limiting the length of user input is the simplest way to avoid stack exhaustion, as the amount of
      the stack consumed would be at most a factor of the length of the input.
    ├ Announcement: https://github.com/time-rs/time/blob/main/CHANGELOG.md#0347-2026-02-05
    ├ Solution: Upgrade to >=0.3.47 (try `cargo update -p time`)
    ├ time v0.3.41
      └── tracing-appender v0.2.3
          └── libdd-log v1.0.0
              └── (dev) libdd-data-pipeline v6.0.0

advisories FAILED, bans ok, sources ok

📦 libdd-trace-protobuf - ✅ No issues

📦 libdd-trace-utils - 4 error(s)

Show output
error[unsound]: Rand is unsound with a custom logger using `rand::rng()`
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:181:1
    │
181 │ rand 0.8.5 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
    │
    ├ ID: RUSTSEC-2026-0097
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0097
    ├ It has been reported (by @lopopolo) that the `rand` library is [unsound](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library) (i.e. that safe code using the public API can cause Undefined Behaviour) when all the following conditions are met:
      
      - The `log` and `thread_rng` features are enabled
      - A [custom logger](https://docs.rs/log/latest/log/#implementing-a-logger) is defined
      - The custom logger accesses `rand::rng()` (previously `rand::thread_rng()`) and calls any `TryRng` (previously `RngCore`) methods on `ThreadRng`
      - The `ThreadRng` (attempts to) reseed while called from the custom logger (this happens every 64 kB of generated data)
      - Trace-level logging is enabled or warn-level logging is enabled and the random source (the `getrandom` crate) is unable to provide a new seed
      
      `TryRng` (previously `RngCore`) methods for `ThreadRng` use `unsafe` code to cast `*mut BlockRng<ReseedingCore>` to `&mut BlockRng<ReseedingCore>`. When all the above conditions are met this results in an aliased mutable reference, violating the Stacked Borrows rules. Miri is able to detect this violation in sample code. Since construction of [aliased mutable references is Undefined Behaviour](https://doc.rust-lang.org/stable/nomicon/references.html), the behaviour of optimized builds is hard to predict.
    ├ Announcement: https://github.com/rust-random/rand/pull/1763
    ├ Solution: Upgrade to >=0.10.1 OR <0.10.0, >=0.9.3 OR <0.9.0, >=0.8.6 (try `cargo update -p rand`)
    ├ rand v0.8.5
      ├── (dev) libdd-common v5.0.0
      │   ├── libdd-capabilities-impl v2.0.0
      │   │   └── libdd-trace-utils v8.0.0
      │   │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   └── libdd-trace-utils v8.0.0 (*)
      ├── (dev) libdd-trace-normalization v2.0.0
      │   └── libdd-trace-utils v8.0.0 (*)
      ├── libdd-trace-utils v8.0.0 (*)
      └── proptest v1.5.0
          └── (dev) libdd-tinybytes v1.1.1
              ├── (dev) libdd-tinybytes v1.1.1 (*)
              └── libdd-trace-utils v8.0.0 (*)

error[vulnerability]: Name constraints for URI names were incorrectly accepted
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:206:1
    │
206 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0098
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0098
    ├ Name constraints for URI names were ignored and therefore accepted.
      
      Note this library does not provide an API for asserting URI names, and URI name constraints are otherwise not implemented.  URI name constraints are now rejected unconditionally.
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-965h-392x-2mh5](https://github.com/rustls/webpki/security/advisories/GHSA-965h-392x-2mh5). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      ├── rustls v0.23.37
      │   ├── hyper-rustls v0.27.7
      │   │   └── libdd-common v5.0.0
      │   │       ├── libdd-capabilities-impl v2.0.0
      │   │       │   └── libdd-trace-utils v8.0.0
      │   │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   │       └── libdd-trace-utils v8.0.0 (*)
      │   ├── libdd-common v5.0.0 (*)
      │   ├── rustls-platform-verifier v0.6.2
      │   │   └── libdd-common v5.0.0 (*)
      │   └── tokio-rustls v0.26.0
      │       ├── hyper-rustls v0.27.7 (*)
      │       └── libdd-common v5.0.0 (*)
      └── rustls-platform-verifier v0.6.2 (*)

error[vulnerability]: Name constraints were accepted for certificates asserting a wildcard name
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:206:1
    │
206 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0099
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0099
    ├ Permitted subtree name constraints for DNS names were accepted for certificates asserting a wildcard name.
      
      This was incorrect because, given a name constraint of `accept.example.com`, `*.example.com` could feasibly allow a name of `reject.example.com` which is outside the constraint.
      This is very similar to [CVE-2025-61727](https://go.dev/issue/76442).
      
      Since name constraints are restrictions on otherwise properly-issued certificates, this bug is reachable only after signature verification and requires misissuance to exploit.
      
      This vulnerability is identified as [GHSA-xgp8-3hg3-c2mh](https://github.com/rustls/webpki/security/advisories/GHSA-xgp8-3hg3-c2mh). Thank you to @1seal for the report.
    ├ Solution: Upgrade to >=0.103.12, <0.104.0-alpha.1 OR >=0.104.0-alpha.6 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      ├── rustls v0.23.37
      │   ├── hyper-rustls v0.27.7
      │   │   └── libdd-common v5.0.0
      │   │       ├── libdd-capabilities-impl v2.0.0
      │   │       │   └── libdd-trace-utils v8.0.0
      │   │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   │       └── libdd-trace-utils v8.0.0 (*)
      │   ├── libdd-common v5.0.0 (*)
      │   ├── rustls-platform-verifier v0.6.2
      │   │   └── libdd-common v5.0.0 (*)
      │   └── tokio-rustls v0.26.0
      │       ├── hyper-rustls v0.27.7 (*)
      │       └── libdd-common v5.0.0 (*)
      └── rustls-platform-verifier v0.6.2 (*)

error[vulnerability]: Reachable panic in certificate revocation list parsing
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:206:1
    │
206 │ rustls-webpki 0.103.10 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0104
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0104
    ├ A panic was reachable when parsing certificate revocation lists via [`BorrowedCertRevocationList::from_der`]
      or [`OwnedCertRevocationList::from_der`].  This was the result of mishandling a syntactically valid empty
      `BIT STRING` appearing in the `onlySomeReasons` element of a `IssuingDistributionPoint` CRL extension.
      
      This panic is reachable prior to a CRL's signature being verified.
      
      Applications that do not use CRLs are not affected.
      
      Thank you to @tynus3 for the report.
    ├ Solution: Upgrade to >=0.103.13, <0.104.0-alpha.1 OR >=0.104.0-alpha.7 (try `cargo update -p rustls-webpki`)
    ├ rustls-webpki v0.103.10
      ├── rustls v0.23.37
      │   ├── hyper-rustls v0.27.7
      │   │   └── libdd-common v5.0.0
      │   │       ├── libdd-capabilities-impl v2.0.0
      │   │       │   └── libdd-trace-utils v8.0.0
      │   │       │       └── (dev) libdd-trace-utils v8.0.0 (*)
      │   │       └── libdd-trace-utils v8.0.0 (*)
      │   ├── libdd-common v5.0.0 (*)
      │   ├── rustls-platform-verifier v0.6.2
      │   │   └── libdd-common v5.0.0 (*)
      │   └── tokio-rustls v0.26.0
      │       ├── hyper-rustls v0.27.7 (*)
      │       └── libdd-common v5.0.0 (*)
      └── rustls-platform-verifier v0.6.2 (*)

advisories FAILED, bans ok, sources ok

Updated: 2026-06-23 20:58:21 UTC | Commit: 023c89f | dependency-check job results

@bm1549 bm1549 force-pushed the brian.marks/otlp-http-protobuf-export branch from ee71538 to 664f16f Compare June 12, 2026 19:51
@dd-octo-sts

dd-octo-sts Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Artifact Size Benchmark Report

aarch64-alpine-linux-musl
Artifact Baseline Commit Change
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.so 7.76 MB 7.82 MB +.80% (+64.00 KB) 🔍
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.a 84.54 MB 84.81 MB +.31% (+276.89 KB) 🔍
aarch64-unknown-linux-gnu
Artifact Baseline Commit Change
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.a 95.68 MB 95.94 MB +.27% (+265.85 KB) 🔍
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.so 10.43 MB 10.44 MB +.06% (+7.37 KB) 🔍
libdatadog-x64-windows
Artifact Baseline Commit Change
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.dll 25.02 MB 25.05 MB +.14% (+37.00 KB) 🔍
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.lib 87.33 KB 87.68 KB +.40% (+360 B) 🔍
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.pdb 181.76 MB 182.47 MB +.39% (+728.00 KB) 🔍
/libdatadog-x64-windows/debug/static/datadog_profiling_ffi.lib 932.38 MB 934.80 MB +.25% (+2.41 MB) 🔍
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.dll 8.20 MB 8.20 MB +.02% (+2.50 KB) 🔍
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.lib 87.33 KB 87.68 KB +.40% (+360 B) 🔍
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.pdb 24.13 MB 24.22 MB +.35% (+88.00 KB) 🔍
/libdatadog-x64-windows/release/static/datadog_profiling_ffi.lib 48.20 MB 48.32 MB +.24% (+122.94 KB) 🔍
libdatadog-x86-windows
Artifact Baseline Commit Change
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.dll 21.68 MB 21.71 MB +.15% (+33.50 KB) 🔍
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.lib 88.71 KB 89.06 KB +.40% (+364 B) 🔍
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.pdb 185.74 MB 186.46 MB +.38% (+736.00 KB) 🔍
/libdatadog-x86-windows/debug/static/datadog_profiling_ffi.lib 920.87 MB 923.52 MB +.28% (+2.65 MB) 🔍
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.dll 6.32 MB 6.32 MB +.10% (+6.50 KB) 🔍
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.lib 88.71 KB 89.06 KB +.40% (+364 B) 🔍
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.pdb 25.89 MB 25.98 MB +.36% (+96.00 KB) 🔍
/libdatadog-x86-windows/release/static/datadog_profiling_ffi.lib 45.82 MB 45.94 MB +.25% (+121.81 KB) 🔍
x86_64-alpine-linux-musl
Artifact Baseline Commit Change
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.a 75.37 MB 75.58 MB +.28% (+221.79 KB) 🔍
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.so 8.68 MB 8.68 MB +.04% (+4.00 KB) 🔍
x86_64-unknown-linux-gnu
Artifact Baseline Commit Change
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.a 90.82 MB 91.04 MB +.24% (+229.70 KB) 🔍
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.so 10.55 MB 10.56 MB +.15% (+16.44 KB) 🔍

The OTLP design spec and implementation plan are linked from the PR
description (internal chonk) rather than committed to the repo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bm1549 bm1549 marked this pull request as ready for review June 12, 2026 21:37
@bm1549 bm1549 requested review from a team as code owners June 12, 2026 21:37
bm1549 and others added 9 commits June 18, 2026 18:53
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… encoding, errors on grpc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The build-time gRPC check fired unconditionally, so a `grpc` protocol
(e.g. resolved from the OTel-default OTEL_EXPORTER_OTLP_PROTOCOL) failed
the build of a normal Datadog-agent exporter even with no OTLP endpoint
set — violating the "protocol is inert without an endpoint" contract.
Move the rejection inside the OTLP-endpoint branch so it only fires when
OTLP export is actually enabled. The send-time arm remains a guard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…per-span alloc

Pre-push review cleanups: keep the internal OtlpWireProtocol and the
json_serializer module crate-private (not public API surface), and use
eq_ignore_ascii_case in the span-kind mappers to avoid a per-span
to_lowercase() allocation on the encode hot path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Criterion benches for the OTLP encoder hot paths — native spans -> prost
IR (the mapper), and prost IR -> HTTP/protobuf and HTTP/JSON wire — plus
end-to-end map+encode, over ~1000-span payloads (one large trace and many
small traces). Inputs are decoded from msgpack into borrowed SpanSlices,
matching the production exporter path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… hex

Pre-size the per-export span Vec and per-span attribute Vec in the prost
mapper to avoid reallocations as they fill. This also makes the resulting
prost IR more compact, speeding up the downstream protobuf encode (a
sequential read of the IR). Serialize OTLP/JSON trace/span ids from a
stack buffer (hex::encode_to_slice) instead of allocating a String per id.

Benches (~1000 spans): map -21%, protobuf encode -19%, JSON encode -9%,
end-to-end -10..12%.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ck buffer

OTLP encodes 64-bit integers (nanosecond timestamps and intValue
attributes) as JSON strings to avoid precision loss; these were each
allocating a String per span via to_string(). Format them into a stack
buffer instead (NumStr, mirroring the HexId id writer). Removes ~3
timestamp + N int-attribute String allocations per span on the JSON path.

Bench: encode_json a further -4.5% (now -12.5% vs the original baseline).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s text

Addresses the build.rs comment-strip review note. `[lib] doctest = false`
does not suppress doctests under `cargo test --doc` (a required gate), so
instead fence the one offending example block (Span.attributes in
trace.proto) as a ```text block — rustdoc renders it as text, not a Rust
doctest — and drop `disable_comments` so the OTLP proto docs are generated
onto the prost structs again. `cargo test --doc` stays green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
test_otlp_grpc_without_endpoint_still_builds builds a real TraceExporter,
which spawns the agent_info worker and makes syscalls miri can't execute.
Add #[cfg_attr(miri, ignore)] to match the file's other live-build tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@yannham yannham left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[EDIT: you can ignore, see my later comment below].

Following @ekump 's comment, I also wonder why all the helpers in the mapper take spans by reference, while the main mapping functions actually has ownership. I feel like we could avoid most of the string clones when we're converting native spans to the IR, if we did this transformation destructively (which is fine, we have ownership)? Though I might be missing some details.

Comment thread libdd-data-pipeline/src/otlp/config.rs Outdated
Comment thread libdd-data-pipeline/src/otlp/config.rs Outdated
Comment thread libdd-data-pipeline/src/otlp/exporter.rs Outdated
Comment thread libdd-data-pipeline/src/otlp/mod.rs Outdated
Comment thread libdd-data-pipeline/src/trace_exporter/builder.rs Outdated
Comment thread libdd-trace-utils/src/otlp_encoder/json_serializer.rs
Comment thread libdd-trace-utils/src/otlp_encoder/mapper.rs Outdated
Comment thread libdd-trace-utils/src/otlp_encoder/mapper.rs Outdated
Comment thread libdd-trace-utils/src/otlp_encoder/mapper.rs Outdated
Comment thread libdd-trace-utils/src/otlp_encoder/mapper.rs Outdated
@yannham

yannham commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Ok, I'll take back the comment on owning spans. Spans text is an abstract SpanText type which is generally not a Rust string, so there's not much we can do here when converting to the prost IR in general.

ekump

This comment was marked as outdated.

@ekump ekump dismissed their stale review June 22, 2026 18:15

dismissing as all my comments are addressed

bm1549 and others added 3 commits June 22, 2026 15:39
…ress review

Per reviewer feedback (ekump/bengl/yannham), the public OTLP protocol no longer
carries the unsupported gRPC variant:

- OtlpProtocol is now {HttpJson, HttpProtobuf}; `grpc` is rejected at the parse
  boundary (FromStr) instead of constructed and guarded downstream.
- Remove the internal OtlpWireProtocol; fold content_type()/encode() onto
  OtlpProtocol (identical once gRPC was gone). The send path encodes via
  OtlpProtocol::encode; the exporter derives content-type from config.protocol.
- Drop #[non_exhaustive]; remove the build-time gRPC rejection and the obsolete
  builder tests, since gRPC can no longer be constructed.
- Narrow the public surface: otlp is pub(crate); only OtlpProtocol is re-exported
  (libdd_data_pipeline::OtlpProtocol). OtlpTraceConfig and the mapper helpers are
  pub(crate).

Also: nest push_str_attr, `(p >= 1.0) as u32`, drop a type annotation, idiomatic
iterator/.map(), doc-links, document DecimalBuf, declutter bench code, and add a
protobuf round-trip test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Integrate the OTLP metrics export feature that landed on main with this PR's
protobuf trace export + prost-IR rework:

- exporter: send_otlp_http takes a content_type param (was hardcoded JSON); the
  trace wrapper passes config.protocol.content_type() (JSON or protobuf), metrics
  passes application/json.
- builder: keep both the otlp_protocol field and main's metrics fields; the trace
  OtlpTraceConfig uses self.otlp_protocol (not hardcoded HttpJson).
- mapper: port main's `_dd.stats_computed` resource attribute (from the new
  client_computed_stats field) onto the prost build_resource; port its two stats
  tests to prost assertions.
- metrics depended on the deleted json_types only for status_code constants; those
  now live in (and are re-used from) otlp_encoder::mapper::status_code.
- otlp module keeps main's pub(crate) visibility; OtlpProtocol stays the one
  externally re-exported symbol (libdd_data_pipeline::OtlpProtocol).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
map_span_link hardcoded `flags: 0`, dropping the linked context's W3C trace
flags (the v04 SpanLink.flags field is populated by the msgpack decoder), so
OTLP consumers saw incorrect link metadata. Set `flags: link.flags`; add
regression tests on both the protobuf (mapper) and JSON (serializer) paths.

Also from pre-push review:
- json_serializer: fix a stale comment (output-buffer pre-sizing was measured and
  reverted as a regression; plain `to_vec` is intentional).
- config: make OtlpProtocol::{content_type,encode} pub(crate) so serde_json::Error
  does not leak into the public API (the type stays public for the FFI).
- lib: the OtlpProtocol re-export carries a non-doc impl note.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@bm1549 bm1549 requested review from bengl and yannham June 22, 2026 21:34
The shared benchmark suite runs ~53 min on main against a 60 min GitLab job
cap; the 10 OTLP benches (5 types x 2 fixtures) pushed it over the limit.
Drop the 100x10 fixture, keeping all five bench types (map_to_prost,
encode_protobuf, encode_json, e2e_protobuf, e2e_json) on the 1x1000 fixture.
Both fixtures totalled ~1000 spans and gave similar signal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@yannham yannham left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All concerns addressed for me 👍

In the long run we might want to look at deserializing native span directly to protobuf without going through prost and the IR at some point, but this is obviously way out of the scope of this PR and OTLP in general.

bm1549 and others added 2 commits June 23, 2026 08:39
…st mapper

main landed feat(otlp)!: attribute-level OTel compatibility (#2091), which adds
`otel_trace_semantics_enabled`: when set, the OTLP payload omits DD-specific
per-span attributes (service.name/operation.name/resource.name/span.type) and
the error.*/span.kind meta tags (that info lives in the OTLP Status and Span.kind
fields). Ported that gating into the prost mapper:

- map_traces_to_otlp / map_span / collect_span_attributes thread the flag; the
  promoted tags and the error.*/span.kind meta tags are skipped when enabled, and
  the dropped-count accounting mirrors what was emitted (promoted/excluded
  compat tags), matching #2091's behavior.
- OtlpTraceConfig gains otel_trace_semantics_enabled; the builder wires it; the
  send path passes config.otel_trace_semantics_enabled. Trace protocol stays
  protobuf-capable (config.protocol.encode), metrics stay JSON.
- Ported #2091's test as a prost-native assertion; existing OTLP/metrics tests
  unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…Status

span_status only read meta["error.msg"], but the #2091 OTel-semantics gating
drops both error.msg and error.message meta tags. For the common case
(error.message — used by every SDK except .NET), that silently lost the error
text: empty Status.message and, under OTel-semantics, no error.message attribute
either. Fall back to error.message (mirroring main's json_types mapper) so the
message is always promoted to Status. Add an OTel-semantics regression test.

Found by Codex adversarial review of the #2091 integration.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds OTLP HTTP/protobuf trace export support to libdatadog’s data pipeline, making the trace exporter’s encoding selectable via an OTel-standard protocol setting, while switching OTLP trace encoding to a single prost-generated intermediate representation (IR) used by both JSON and protobuf encoders.

Changes:

  • Replaces the hand-rolled OTLP JSON model with a prost OTLP IR + a custom OTLP/JSON serializer, and adds a protobuf encoder via prost::Message::encode_to_vec.
  • Introduces OtlpProtocol (HttpJson/HttpProtobuf) in libdd-data-pipeline, threads it through the trace exporter + sender, and exposes it through the FFI config.
  • Vendors/generates the OTLP trace protobuf definitions needed for the prost IR and adds tests/benchmarks around encoding parity and performance.

Reviewed changes

Copilot reviewed 23 out of 24 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
libdd-trace-utils/src/otlp_encoder/mod.rs Exposes prost OTLP request type and adds JSON/protobuf encoding entry points.
libdd-trace-utils/src/otlp_encoder/mapper.rs Reworks mapping to build prost OTLP types directly; updates tests for the new IR.
libdd-trace-utils/src/otlp_encoder/json_types.rs Removes the prior hand-rolled OTLP JSON model (breaking change).
libdd-trace-utils/src/otlp_encoder/json_serializer.rs Adds a custom serializer implementing OTLP/JSON wire format from prost types.
libdd-trace-utils/Cargo.toml Adds hex dependency used by the JSON serializer/tests.
libdd-trace-utils/benches/otlp_encoding.rs Adds benchmarks for mapping + protobuf/JSON encoding paths.
libdd-trace-utils/benches/main.rs Registers the new OTLP encoding benchmarks.
libdd-trace-protobuf/src/pb/opentelemetry/proto/trace/v1/trace.proto Adds vendored OTLP trace protobuf schema.
libdd-trace-protobuf/src/pb/opentelemetry/proto/collector/trace/v1/trace_service.proto Adds vendored OTLP trace service schema.
libdd-trace-protobuf/src/opentelemetry.proto.trace.v1.rs Adds prost-generated Rust types for OTLP trace.
libdd-trace-protobuf/src/opentelemetry.proto.collector.trace.v1.rs Adds prost-generated Rust types for OTLP trace service request/response.
libdd-trace-protobuf/src/_includes.rs Wires generated OTLP trace modules into the crate’s include tree.
libdd-trace-protobuf/build.rs Updates prost-build inputs and attributes to generate OTLP trace types.
libdd-data-pipeline/tests/test_trace_exporter_otlp_protobuf_export.rs Adds an integration test validating protobuf payload decodes server-side.
libdd-data-pipeline/src/trace_exporter/mod.rs Switches trace export to protocol-selected encoding via OtlpProtocol.
libdd-data-pipeline/src/trace_exporter/builder.rs Adds builder support for selecting OTLP trace protocol.
libdd-data-pipeline/src/otlp/mod.rs Re-exports OtlpProtocol and updates module docs around encoding choice.
libdd-data-pipeline/src/otlp/metrics.rs Adjusts status code import and passes explicit JSON content-type to sender.
libdd-data-pipeline/src/otlp/exporter.rs Generalizes OTLP HTTP sender to accept content-type + body bytes.
libdd-data-pipeline/src/otlp/config.rs Implements OtlpProtocol parsing + content-type + request encoding helper.
libdd-data-pipeline/src/lib.rs Re-exports OtlpProtocol at crate root for FFI consumption.
libdd-data-pipeline/Cargo.toml Adds prost as a dev-dependency for tests decoding protobuf payloads.
libdd-data-pipeline-ffi/src/trace_exporter.rs Adds FFI config setter for OTLP protocol selection and threads into builder.
Cargo.lock Updates lockfile for newly introduced dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread libdd-trace-utils/src/otlp_encoder/mapper.rs
Comment thread libdd-trace-utils/src/otlp_encoder/mapper.rs Outdated
Comment thread libdd-trace-utils/src/otlp_encoder/mapper.rs
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

@bengl bengl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants