From df8a4d106b77dce52d751c5cd2b6f174326f5140 Mon Sep 17 00:00:00 2001 From: Munir Date: Wed, 20 May 2026 21:31:13 -0400 Subject: [PATCH] feat(datadog-opentelemetry): wire telemetry session IDs from libdatadog Bump the published libdatadog workspace stack to 4.x/5.x for TelemetryInstrumentationSessions and TraceExporter. Propagate runtime lineage env into config, telemetry, and the trace exporter, and refresh root and instrumentation lockfiles plus third-party license data. Capture session lineage as a pure LineageContext value: a single, narrowly scoped env read replaces the previous std::env::set_var write inside ConfigBuilder::build(), eliminating the POSIX-unsound mutation and the TOCTOU race between the var_os check and set_var. Tests inject env via a closure so no global state is touched. The public surface re-exports only LineageContext and TelemetryInstrumentationSessions; the env keys, install helper, and free spawn helpers are no longer exposed. Co-authored-by: Cursor --- Cargo.lock | 362 ++++++++++++++++-- Cargo.toml | 14 +- LICENSE-3rdparty.csv | 25 ++ datadog-opentelemetry/Cargo.toml | 4 +- .../src/core/configuration/configuration.rs | 2 +- datadog-opentelemetry/src/core/mod.rs | 1 + datadog-opentelemetry/src/core/telemetry.rs | 5 + .../src/core/telemetry_session.rs | 162 ++++++++ datadog-opentelemetry/src/exporter/mod.rs | 21 +- datadog-opentelemetry/src/span_exporter.rs | 9 +- instrumentation/Cargo.lock | 341 ++++++++++++++++- 11 files changed, 885 insertions(+), 61 deletions(-) create mode 100644 datadog-opentelemetry/src/core/telemetry_session.rs diff --git a/Cargo.lock b/Cargo.lock index bb973b8f..e698ccd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,6 +170,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "borrow-or-share" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc0b364ead1874514c8c2855ab558056ebfeb775653e7ae45ff72f28f8f3166c" + [[package]] name = "bumpalo" version = "3.19.0" @@ -359,6 +365,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -460,6 +476,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctor" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "datadog-opentelemetry" version = "0.3.3" @@ -469,6 +495,7 @@ dependencies = [ "assert_unordered", "base64 0.21.7", "criterion", + "ctor", "datadog-opentelemetry", "foldhash 0.1.5", "hashbrown 0.15.5", @@ -476,6 +503,7 @@ dependencies = [ "hyper", "hyper-util", "libc", + "libdd-capabilities-impl", "libdd-common", "libdd-data-pipeline", "libdd-library-config", @@ -553,7 +581,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -577,6 +605,17 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "fluent-uri" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc74ac4d8359ae70623506d512209619e5cf8f347124910440dbc221714b328e" +dependencies = [ + "borrow-or-share", + "ref-cast", + "serde", +] + [[package]] name = "fnv" version = "1.0.7" @@ -716,8 +755,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.11.1+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] @@ -926,6 +967,22 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "tower-service", +] + [[package]] name = "hyper-timeout" version = "0.5.2" @@ -1161,11 +1218,37 @@ version = "0.2.185" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" +[[package]] +name = "libdd-capabilities" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ce42b411956272ea0ff851dddbd8ea4dae251192ffdbc50e90e20737ffd600" +dependencies = [ + "anyhow", + "bytes", + "http", + "thiserror 1.0.69", +] + +[[package]] +name = "libdd-capabilities-impl" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79a6210d654b578a52ac4abe31f94b88f52740c8f2a62adc969cad240eae319d" +dependencies = [ + "bytes", + "http", + "http-body-util", + "libdd-capabilities", + "libdd-common", + "tokio", +] + [[package]] name = "libdd-common" -version = "3.0.2" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c779949577250487179d904508f18750070e9a01eb58dce378409ec5fa066f3b" +checksum = "933c5940905e9a3c8dd8c0439697b3fb327289cef7858370e6a5f440139f6314" dependencies = [ "anyhow", "bytes", @@ -1179,37 +1262,46 @@ dependencies = [ "http-body", "http-body-util", "hyper", + "hyper-rustls", "hyper-util", "libc", "nix", "pin-project", "regex", + "rustls", + "rustls-native-certs", "serde", "static_assertions", "thiserror 1.0.69", "tokio", + "tokio-rustls", "tower-service", "windows-sys 0.52.0", ] [[package]] name = "libdd-data-pipeline" -version = "3.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "358411451d99011f13c7628acee25dc144f2bbeade87acf10fa7d5ffce1053dc" +checksum = "3c0d0fcb6725d8399b46533a7eb023475e8b1be0da5942e25a34ef1efdfb2b43" dependencies = [ "anyhow", "arc-swap", + "async-trait", "bytes", "either", + "getrandom 0.2.16", "http", "http-body-util", + "libdd-capabilities", + "libdd-capabilities-impl", "libdd-common", "libdd-ddsketch", "libdd-dogstatsd-client", + "libdd-shared-runtime", "libdd-telemetry", "libdd-tinybytes", - "libdd-trace-protobuf 3.0.1", + "libdd-trace-protobuf 3.0.2", "libdd-trace-stats", "libdd-trace-utils", "rmp-serde", @@ -1233,9 +1325,9 @@ dependencies = [ [[package]] name = "libdd-dogstatsd-client" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f8eca39d1e2ef6267cf77fc51eb7ebc7d4f44827e150b4d317c29d8c33bf87" +checksum = "8f79afd4a3f84f80f6b631e4446d09131c156f1179295e390e9b4dc2bfa527cf" dependencies = [ "anyhow", "cadence", @@ -1263,14 +1355,34 @@ dependencies = [ "serde_yaml", ] +[[package]] +name = "libdd-shared-runtime" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9c295f7b55ec78e261537627a75be4e926a94e2b0014e98392b3f98e1957aa" +dependencies = [ + "async-trait", + "futures", + "futures-util", + "libdd-capabilities", + "libdd-capabilities-impl", + "libdd-common", + "tokio", + "tokio-util", + "tracing", + "wasm-bindgen-futures", +] + [[package]] name = "libdd-telemetry" -version = "4.0.0" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78774ffce79da677602829d7fe27468283e5349010e974257233edf4cd12b783" +checksum = "1662c33b446eed81b610b5d567ddb9c45c5b7587c6c23c5f5545a98b451cc0ba" dependencies = [ "anyhow", + "async-trait", "base64 0.22.1", + "bytes", "futures", "hashbrown 0.15.5", "http", @@ -1278,6 +1390,7 @@ dependencies = [ "libc", "libdd-common", "libdd-ddsketch", + "libdd-shared-runtime", "serde", "serde_json", "sys-info", @@ -1290,9 +1403,9 @@ dependencies = [ [[package]] name = "libdd-tinybytes" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47838e12ae2665250b4cdba4e3119230b79e3c522bb9f48dd0c87346f5a8f44" +checksum = "97db80e3f3f9d19643ac444d6267951a5dab622ad9828c51149d49150625cfe8" dependencies = [ "serde", ] @@ -1304,7 +1417,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab12e095f3589d02ceed76556e7aa8a1b5bc928a900e143b624e2331294e54b5" dependencies = [ "anyhow", - "libdd-trace-protobuf 3.0.1", + "libdd-trace-protobuf 3.0.2", +] + +[[package]] +name = "libdd-trace-obfuscation" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d30126bbcb5d10f0e4a97b39199e4918fb51abd37473606bc874c3e7a159bf1" +dependencies = [ + "anyhow", + "fluent-uri", + "libdd-common", + "libdd-trace-protobuf 3.0.2", + "libdd-trace-utils", + "log", + "percent-encoding", + "serde", + "serde_json", ] [[package]] @@ -1320,9 +1450,9 @@ dependencies = [ [[package]] name = "libdd-trace-protobuf" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1809242895edc53ac51a21287829f42474e749dbc222ea7f414cb3f0d1f91d4e" +checksum = "c67e3e9a09dab3f19d4f79006f3efb8b4bf8416551465edaeeb71816949e2197" dependencies = [ "prost", "serde", @@ -1331,37 +1461,55 @@ dependencies = [ [[package]] name = "libdd-trace-stats" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92b882863f7c531d51e73f7bc5930c705e47829332128d9bdcad0fea3b2b942" +checksum = "7f3d860f564da2ad30141a352fe4b924f8cf37dd0b32b3f4b0ef4ee52b9b43fe" dependencies = [ + "anyhow", + "arc-swap", + "async-trait", "hashbrown 0.15.5", + "http", + "libdd-capabilities", + "libdd-capabilities-impl", + "libdd-common", "libdd-ddsketch", - "libdd-trace-protobuf 3.0.1", + "libdd-shared-runtime", + "libdd-trace-obfuscation", + "libdd-trace-protobuf 3.0.2", "libdd-trace-utils", + "rmp-serde", + "serde", + "tokio", + "tokio-util", + "tracing", ] [[package]] name = "libdd-trace-utils" -version = "3.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870506e9bb79c93ce5bbfe9d715c53c7ea393a177c7299f0bf43745c0adea0c7" +checksum = "8442cf9c141da05cd170a6c230cba13b50d0bd3635df16928f296a7ad233b2d8" dependencies = [ "anyhow", + "base64 0.22.1", "bytes", "cargo-platform", "cargo_metadata", "futures", + "getrandom 0.2.16", "http", "http-body", "http-body-util", "httpmock", "hyper", "indexmap", + "libdd-capabilities", + "libdd-capabilities-impl", "libdd-common", "libdd-tinybytes", "libdd-trace-normalization", - "libdd-trace-protobuf 3.0.1", + "libdd-trace-protobuf 3.0.2", "prost", "rand 0.8.5", "rmp", @@ -1513,6 +1661,12 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + [[package]] name = "opentelemetry" version = "0.31.0" @@ -1948,6 +2102,26 @@ dependencies = [ "bitflags", ] +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "regex" version = "1.11.1" @@ -2026,6 +2200,20 @@ dependencies = [ "web-sys", ] +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rmp" version = "0.8.14" @@ -2093,7 +2281,53 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] @@ -2117,12 +2351,44 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" +dependencies = [ + "bitflags", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.26" @@ -2167,6 +2433,7 @@ version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" dependencies = [ + "indexmap", "itoa", "memchr", "ryu", @@ -2308,6 +2575,12 @@ version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b3c8667cd96245cbb600b8dec5680a7319edd719c5aa2b5d23c6bff94f39765" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.105" @@ -2356,7 +2629,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -2512,6 +2785,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.17" @@ -2745,6 +3028,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.4" @@ -2962,13 +3251,19 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-registry" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows-result", "windows-strings", ] @@ -2979,7 +3274,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -2988,7 +3283,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -3009,6 +3304,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -3224,6 +3528,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + [[package]] name = "zerotrie" version = "0.2.3" diff --git a/Cargo.toml b/Cargo.toml index 34a93c45..f2bb2c95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,11 +23,15 @@ authors = ["Datadog Inc. "] [workspace.dependencies] # Libdatadog dependencies - change to a stable version once we release -libdd-data-pipeline = { version = "3.0.1", default-features = false } -libdd-trace-utils = { version = "3.0.0", default-features = false } -libdd-telemetry = { version = "4.0.0", default-features = false } -libdd-common = { version = "3.0.1", default-features = false } -libdd-tinybytes = { version = "1.1.0", default-features = false } +libdd-data-pipeline = { version = "4.0.0", default-features = false, features = [ + "https", + "telemetry", +] } +libdd-capabilities-impl = { version = "2.0.0", default-features = false, features = ["https"] } +libdd-trace-utils = { version = "4.0.0", default-features = false } +libdd-telemetry = { version = "5.0.0", default-features = false } +libdd-common = { version = "4.1.0", default-features = false } +libdd-tinybytes = { version = "1.1.1", default-features = false } libdd-library-config = { version = "1.1.0", default-features = false } opentelemetry_sdk = { version = "0.31.0", features = [ "trace", diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 7d62d732..b0fa80e6 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -18,6 +18,7 @@ base64,https://github.com/marshallpierce/rust-base64,MIT OR Apache-2.0,"Alice Ma base64,https://github.com/marshallpierce/rust-base64,MIT OR Apache-2.0,Marshall Pierce bitflags,https://github.com/bitflags/bitflags,MIT OR Apache-2.0,The Rust Project Developers block-buffer,https://github.com/RustCrypto/utils,MIT OR Apache-2.0,RustCrypto Developers +borrow-or-share,https://github.com/yescallop/borrow-or-share,MIT-0,Scallop Ye bumpalo,https://github.com/fitzgen/bumpalo,MIT OR Apache-2.0,Nick Fitzgerald byteorder,https://github.com/BurntSushi/byteorder,Unlicense OR MIT,Andrew Gallant bytes,https://github.com/tokio-rs/bytes,MIT,"Carl Lerche , Sean McArthur " @@ -49,6 +50,7 @@ crossbeam-epoch,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-utils,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-utils Authors crunchy,https://github.com/AtheMathmo/crunchy,MIT,Eira Fransham crypto-common,https://github.com/RustCrypto/traits,MIT OR Apache-2.0,RustCrypto Developers +ctor,https://github.com/mmastrac/rust-ctor,Apache-2.0 OR MIT,Matt Mastracci diff,https://github.com/utkarshkukreti/diff.rs,MIT OR Apache-2.0,Utkarsh Kukreti digest,https://github.com/RustCrypto/traits,MIT OR Apache-2.0,RustCrypto Developers displaydoc,https://github.com/yaahc/displaydoc,MIT OR Apache-2.0,Jane Lusby @@ -57,6 +59,7 @@ equivalent,https://github.com/indexmap-rs/equivalent,Apache-2.0 OR MIT,The equiv errno,https://github.com/lambda-fairy/rust-errno,MIT OR Apache-2.0,"Chris Wong , Dan Gohman " event-listener,https://github.com/smol-rs/event-listener,Apache-2.0 OR MIT,"Stjepan Glavina , John Nunley " event-listener-strategy,https://github.com/smol-rs/event-listener-strategy,Apache-2.0 OR MIT,John Nunley +fluent-uri,https://github.com/yescallop/fluent-uri-rs,MIT,Scallop Ye fnv,https://github.com/servo/rust-fnv,Apache-2.0 OR MIT,Alex Crichton foldhash,https://github.com/orlp/foldhash,Zlib,Orson Peters form_urlencoded,https://github.com/servo/rust-url,MIT OR Apache-2.0,The rust-url developers @@ -87,6 +90,7 @@ httparse,https://github.com/seanmonstar/httparse,MIT OR Apache-2.0,Sean McArthur httpdate,https://github.com/pyfisch/httpdate,MIT OR Apache-2.0,Pyfisch httpmock,https://github.com/httpmock/httpmock,MIT,Alexander Liesenfeld hyper,https://github.com/hyperium/hyper,MIT,Sean McArthur +hyper-rustls,https://github.com/rustls/hyper-rustls,Apache-2.0 OR ISC OR MIT,The hyper-rustls Authors hyper-timeout,https://github.com/hjr3/hyper-timeout,MIT OR Apache-2.0,Herman J. Radtke III hyper-util,https://github.com/hyperium/hyper-util,MIT,Sean McArthur icu_collections,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers @@ -108,14 +112,18 @@ itoa,https://github.com/dtolnay/itoa,MIT OR Apache-2.0,David Tolnay libc,https://github.com/rust-lang/libc,MIT OR Apache-2.0,The Rust Project Developers +libdd-capabilities,https://github.com/DataDog/libdatadog/tree/main/libdd-capabilities,Apache-2.0,The libdd-capabilities Authors +libdd-capabilities-impl,https://github.com/DataDog/libdatadog/tree/main/libdd-capabilities-impl,Apache-2.0,The libdd-capabilities-impl Authors libdd-common,https://github.com/DataDog/libdatadog/tree/main/datadog-common,Apache-2.0,The libdd-common Authors libdd-data-pipeline,https://github.com/DataDog/libdatadog/tree/main/libdd-data-pipeline,Apache-2.0,The libdd-data-pipeline Authors libdd-ddsketch,https://github.com/DataDog/libdatadog/tree/main/libdd-ddsketch,Apache-2.0,The libdd-ddsketch Authors libdd-dogstatsd-client,https://github.com/DataDog/libdatadog/tree/main/libdd-dogstatsd-client,Apache-2.0,The libdd-dogstatsd-client Authors libdd-library-config,https://github.com/DataDog/libdatadog/tree/main/libdd-library-config,Apache-2.0,The libdd-library-config Authors +libdd-shared-runtime,https://github.com/DataDog/libdatadog/tree/main/libdd-shared-runtime,Apache-2.0,The libdd-shared-runtime Authors libdd-telemetry,https://github.com/DataDog/libdatadog/tree/main/libdd-telemetry,Apache-2.0,The libdd-telemetry Authors libdd-tinybytes,https://github.com/DataDog/libdatadog/tree/main/libdd-tinybytes,Apache-2.0,The libdd-tinybytes Authors libdd-trace-normalization,https://github.com/DataDog/libdatadog/tree/main/libdd-trace-normalization,Apache-2.0,David Lee +libdd-trace-obfuscation,https://github.com/DataDog/libdatadog/tree/main/libdd-trace-obfuscation,Apache-2.0,Datadog Inc. libdd-trace-protobuf,https://github.com/DataDog/libdatadog/tree/main/libdd-trace-protobuf,Apache-2.0,The libdd-trace-protobuf Authors libdd-trace-stats,https://github.com/DataDog/libdatadog/tree/main/libdd-trace-stats,Apache-2.0,The libdd-trace-stats Authors libdd-trace-utils,https://github.com/DataDog/libdatadog/tree/main/libdd-trace-utils,Apache-2.0,The libdd-trace-utils Authors @@ -136,6 +144,7 @@ num-traits,https://github.com/rust-num/num-traits,MIT OR Apache-2.0,The Rust Pro object,https://github.com/gimli-rs/object,Apache-2.0 OR MIT,The object Authors once_cell,https://github.com/matklad/once_cell,MIT OR Apache-2.0,Aleksey Kladov oorandom,https://hg.sr.ht/~icefox/oorandom,MIT,Simon Heath +openssl-probe,https://github.com/alexcrichton/openssl-probe,MIT OR Apache-2.0,Alex Crichton opentelemetry,https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry,Apache-2.0,The opentelemetry Authors opentelemetry-appender-tracing,https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-appender-tracing,Apache-2.0,The opentelemetry-appender-tracing Authors opentelemetry-http,https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-http,Apache-2.0,The opentelemetry-http Authors @@ -172,12 +181,15 @@ rand_xorshift,https://github.com/rust-random/rngs,MIT OR Apache-2.0,"The Rand Pr rayon,https://github.com/rayon-rs/rayon,MIT OR Apache-2.0,The rayon Authors rayon-core,https://github.com/rayon-rs/rayon,MIT OR Apache-2.0,The rayon-core Authors redox_syscall,https://gitlab.redox-os.org/redox-os/syscall,MIT,Jeremy Soller +ref-cast,https://github.com/dtolnay/ref-cast,MIT OR Apache-2.0,David Tolnay +ref-cast-impl,https://github.com/dtolnay/ref-cast,MIT OR Apache-2.0,David Tolnay regex,https://github.com/rust-lang/regex,MIT OR Apache-2.0,"The Rust Project Developers, Andrew Gallant " regex-automata,https://github.com/BurntSushi/regex-automata,Unlicense OR MIT,Andrew Gallant regex-automata,https://github.com/rust-lang/regex/tree/master/regex-automata,MIT OR Apache-2.0,"The Rust Project Developers, Andrew Gallant " regex-syntax,https://github.com/rust-lang/regex,MIT OR Apache-2.0,The Rust Project Developers regex-syntax,https://github.com/rust-lang/regex/tree/master/regex-syntax,MIT OR Apache-2.0,"The Rust Project Developers, Andrew Gallant " reqwest,https://github.com/seanmonstar/reqwest,MIT OR Apache-2.0,Sean McArthur +ring,https://github.com/briansmith/ring,Apache-2.0 AND ISC,The ring Authors rmp,https://github.com/3Hren/msgpack-rust,MIT,Evgeny Safronov rmp-serde,https://github.com/3Hren/msgpack-rust,MIT,Evgeny Safronov rmpv,https://github.com/3Hren/msgpack-rust,MIT,Evgeny Safronov @@ -185,10 +197,17 @@ rustc-demangle,https://github.com/rust-lang/rustc-demangle,MIT OR Apache-2.0,Ale rustc_version,https://github.com/djc/rustc-version-rs,MIT OR Apache-2.0,The rustc_version Authors rustc_version_runtime,https://github.com/seppo0010/rustc-version-runtime-rs,MIT,Sebastian Waisbrot rustix,https://github.com/bytecodealliance/rustix,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,"Dan Gohman , Jakub Konka " +rustls,https://github.com/rustls/rustls,Apache-2.0 OR ISC OR MIT,The rustls Authors +rustls-native-certs,https://github.com/rustls/rustls-native-certs,Apache-2.0 OR ISC OR MIT,The rustls-native-certs Authors +rustls-pki-types,https://github.com/rustls/pki-types,MIT OR Apache-2.0,The rustls-pki-types Authors +rustls-webpki,https://github.com/rustls/webpki,ISC,The rustls-webpki Authors rustversion,https://github.com/dtolnay/rustversion,MIT OR Apache-2.0,David Tolnay ryu,https://github.com/dtolnay/ryu,Apache-2.0 OR BSL-1.0,David Tolnay same-file,https://github.com/BurntSushi/same-file,Unlicense OR MIT,Andrew Gallant +schannel,https://github.com/steffengy/schannel-rs,MIT,"Steven Fackler , Steffen Butzer " scopeguard,https://github.com/bluss/scopeguard,MIT OR Apache-2.0,bluss +security-framework,https://github.com/kornelski/rust-security-framework,MIT OR Apache-2.0,"Steven Fackler , Kornel " +security-framework-sys,https://github.com/kornelski/rust-security-framework,MIT OR Apache-2.0,"Steven Fackler , Kornel " semver,https://github.com/dtolnay/semver,MIT OR Apache-2.0,David Tolnay serde,https://github.com/serde-rs/serde,MIT OR Apache-2.0,"Erick Tryzelaar , David Tolnay " serde_bytes,https://github.com/serde-rs/bytes,MIT OR Apache-2.0,David Tolnay @@ -209,6 +228,7 @@ socket2,https://github.com/rust-lang/socket2,MIT OR Apache-2.0,"Alex Crichton static_assertions,https://github.com/nvzqz/static-assertions-rs,MIT OR Apache-2.0,Nikolai Vazquez stringmetrics,https://github.com/pluots/stringmetrics,Apache-2.0,Trevor Gross +subtle,https://github.com/dalek-cryptography/subtle,BSD-3-Clause,"Isis Lovecruft , Henry de Valence " syn,https://github.com/dtolnay/syn,MIT OR Apache-2.0,David Tolnay sync_wrapper,https://github.com/Actyx/sync_wrapper,Apache-2.0,Actyx AG synstructure,https://github.com/mystor/synstructure,MIT,Nika Layzell @@ -225,6 +245,7 @@ tinystr,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Devel tinytemplate,https://github.com/bheisler/TinyTemplate,Apache-2.0 OR MIT,Brook Heisler tokio,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors tokio-macros,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors +tokio-rustls,https://github.com/rustls/tokio-rustls,MIT OR Apache-2.0,The tokio-rustls Authors tokio-stream,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors tokio-util,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors tonic,https://github.com/hyperium/tonic,MIT,Lucio Franco @@ -245,6 +266,7 @@ unicode-ident,https://github.com/dtolnay/unicode-ident,(MIT OR Apache-2.0) AND U unicode-width,https://github.com/unicode-rs/unicode-width,MIT OR Apache-2.0,"kwantam , Manish Goregaokar " unicode-xid,https://github.com/unicode-rs/unicode-xid,MIT OR Apache-2.0,"erick.tryzelaar , kwantam , Manish Goregaokar " unsafe-libyaml,https://github.com/dtolnay/unsafe-libyaml,MIT,David Tolnay +untrusted,https://github.com/briansmith/untrusted,ISC,Brian Smith url,https://github.com/servo/rust-url,MIT OR Apache-2.0,The rust-url developers urlencoding,https://github.com/kornelski/rust_urlencoding,MIT,"Kornel , Bertram Truong " utf8_iter,https://github.com/hsivonen/utf8_iter,Apache-2.0 OR MIT,Henri Sivonen @@ -268,10 +290,12 @@ winapi-util,https://github.com/BurntSushi/winapi-util,Unlicense OR MIT,Andrew Ga winapi-x86_64-pc-windows-gnu,https://github.com/retep998/winapi-rs,MIT OR Apache-2.0,Peter Atashian windows,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft windows-link,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows-link,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-link Authors windows-registry,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft windows-result,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft windows-strings,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft windows-sys,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows-sys,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-sys Authors windows-targets,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft windows_aarch64_gnullvm,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft windows_aarch64_msvc,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft @@ -291,6 +315,7 @@ zerocopy,https://github.com/google/zerocopy,BSD-2-Clause OR Apache-2.0 OR MIT,"J zerocopy-derive,https://github.com/google/zerocopy,BSD-2-Clause OR Apache-2.0 OR MIT,"Joshua Liebow-Feeser , Jack Wrenn " zerofrom,https://github.com/unicode-org/icu4x,Unicode-3.0,Manish Goregaokar zerofrom-derive,https://github.com/unicode-org/icu4x,Unicode-3.0,Manish Goregaokar +zeroize,https://github.com/RustCrypto/utils,Apache-2.0 OR MIT,The RustCrypto Project Developers zerotrie,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers zerovec,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers zerovec-derive,https://github.com/unicode-org/icu4x,Unicode-3.0,Manish Goregaokar diff --git a/datadog-opentelemetry/Cargo.toml b/datadog-opentelemetry/Cargo.toml index ecbcc3f4..d5ffb860 100644 --- a/datadog-opentelemetry/Cargo.toml +++ b/datadog-opentelemetry/Cargo.toml @@ -54,12 +54,15 @@ base64 = "0.21" sha2 = "0.10" uuid = { version = "1.11.0", features = ["v4"] } arc-swap = "1.7.1" +ctor = "0.2" +libc = "0.2" # core Test utils criterion = { version = "0.5.1", optional = true } # Libdatadog dependencies libdd-data-pipeline = { workspace = true } +libdd-capabilities-impl = { workspace = true } libdd-trace-utils = { workspace = true } libdd-telemetry = { workspace = true } libdd-common = { workspace = true } @@ -68,7 +71,6 @@ percent-encoding = "2.3.1" [target.'cfg(target_os="linux")'.dependencies] libdd-library-config = { workspace = true } -libc = "0.2" [dev-dependencies] assert_unordered = "0.3" diff --git a/datadog-opentelemetry/src/core/configuration/configuration.rs b/datadog-opentelemetry/src/core/configuration/configuration.rs index 3e3bdfda..7d097c70 100644 --- a/datadog-opentelemetry/src/core/configuration/configuration.rs +++ b/datadog-opentelemetry/src/core/configuration/configuration.rs @@ -1387,7 +1387,7 @@ impl Config { } /// Static runtime id if the process - fn process_runtime_id() -> &'static str { + pub(crate) fn process_runtime_id() -> &'static str { // TODO(paullgdc): Regenerate on fork? Would we even support forks? static RUNTIME_ID: OnceLock = OnceLock::new(); RUNTIME_ID.get_or_init(|| uuid::Uuid::new_v4().to_string()) diff --git a/datadog-opentelemetry/src/core/mod.rs b/datadog-opentelemetry/src/core/mod.rs index b38404f0..dcd070a5 100644 --- a/datadog-opentelemetry/src/core/mod.rs +++ b/datadog-opentelemetry/src/core/mod.rs @@ -12,6 +12,7 @@ mod error; pub mod log; pub(crate) mod telemetry; +pub(crate) mod telemetry_session; pub(crate) mod utils; #[cfg(feature = "test-utils")] diff --git a/datadog-opentelemetry/src/core/telemetry.rs b/datadog-opentelemetry/src/core/telemetry.rs index 2ba52b08..4d29dc32 100644 --- a/datadog-opentelemetry/src/core/telemetry.rs +++ b/datadog-opentelemetry/src/core/telemetry.rs @@ -16,6 +16,7 @@ use libdd_telemetry::{ }; use super::configuration::{Config, ConfigurationProvider}; +use super::telemetry_session; use crate::{dd_debug, dd_error, dd_warn}; static TELEMETRY: TelemetryCell = OnceLock::new(); @@ -249,6 +250,10 @@ fn make_telemetry_worker( builder.config = libdd_telemetry::config::Config::from_env(); builder.config.telemetry_heartbeat_interval = Duration::from_secs_f64(config.telemetry_heartbeat_interval()); + let inst = telemetry_session::sessions_from_runtime_id(config.runtime_id()); + builder.config.session_id = inst.session_id; + builder.config.root_session_id = inst.root_session_id; + builder.config.parent_session_id = inst.parent_session_id; // builder.config.debug_enabled = true; builder.run().map(|handle| { diff --git a/datadog-opentelemetry/src/core/telemetry_session.rs b/datadog-opentelemetry/src/core/telemetry_session.rs new file mode 100644 index 00000000..72b75b94 --- /dev/null +++ b/datadog-opentelemetry/src/core/telemetry_session.rs @@ -0,0 +1,162 @@ +// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +//! Telemetry session ids. A library constructor runs once between `exec` and +//! `main`, captures inbound lineage from `_DD_ROOT_RS_SESSION_ID` / +//! `_DD_PARENT_RS_SESSION_ID` via `libc::getenv`, and installs the outbound +//! env via `libc::setenv` (or `libc::putenv_s` on Windows) so subprocesses +//! spawned via `Command::spawn` inherit it transparently. The constructor +//! runs before any user thread exists, so the `setenv` call is sound. +//! +//! Best-effort: not refreshed on bare `fork()` (`exec` resets memory and +//! re-runs the constructor; bare fork inherits the cached value). Daemons +//! and `nix::unistd::fork` callers will report the parent's session until +//! the tracer grows a `pthread_atfork` child handler. + +use std::ffi::{CStr, CString}; +use std::sync::OnceLock; + +use libdd_data_pipeline::trace_exporter::TelemetryInstrumentationSessions; + +const ENV_ROOT_RS_SESSION_ID: &str = "_DD_ROOT_RS_SESSION_ID"; +const ENV_PARENT_RS_SESSION_ID: &str = "_DD_PARENT_RS_SESSION_ID"; + +static CAPTURED: OnceLock = OnceLock::new(); + +/// Session ids for this process. Returns the value captured by the +/// constructor; falls back to a fresh env read if the constructor did not +/// run (e.g. exotic targets without `.init_array` support). +pub(crate) fn sessions_from_runtime_id(runtime_id: &str) -> TelemetryInstrumentationSessions { + if let Some(cached) = CAPTURED.get() { + if cached.session_id.as_deref() == Some(runtime_id) { + return cached.clone(); + } + } + sessions_from_env(runtime_id, fallback_read_env) +} + +#[allow(clippy::disallowed_methods)] +fn fallback_read_env(key: &str) -> Option { + std::env::var(key).ok() +} + +#[ctor::ctor] +fn install_lineage() { + // Swallow any unexpected panic during library load so we never abort the + // host process; lineage just degrades to "missing" in that case. + let _ = std::panic::catch_unwind(install_lineage_inner); +} + +fn install_lineage_inner() { + let runtime_id = crate::core::configuration::Config::process_runtime_id(); + // SAFETY: this constructor runs once, between `exec` and `main`, before + // any thread is spawned by the host program. `libc::{getenv, setenv, + // putenv_s}` are sound while the process is single-threaded. + let captured = sessions_from_env(runtime_id, |k| unsafe { libc_getenv(k) }); + let _ = CAPTURED.set(captured); + unsafe { install_outbound_env_libc(runtime_id) }; +} + +/// # Safety +/// Caller must ensure no other thread is mutating the process environment +/// concurrently. +unsafe fn libc_getenv(key: &str) -> Option { + let key_c = CString::new(key).ok()?; + let ptr = unsafe { libc::getenv(key_c.as_ptr()) }; + if ptr.is_null() { + return None; + } + Some( + unsafe { CStr::from_ptr(ptr) } + .to_string_lossy() + .into_owned(), + ) +} + +/// # Safety +/// Caller must ensure no other thread is reading or mutating the process +/// environment concurrently. +unsafe fn install_outbound_env_libc(runtime_id: &str) { + let Ok(rid_c) = CString::new(runtime_id) else { + return; + }; + let root_c = c"_DD_ROOT_RS_SESSION_ID"; + let parent_c = c"_DD_PARENT_RS_SESSION_ID"; + + // Preserve root inherited from an upstream parent; otherwise we become root. + if unsafe { libc::getenv(root_c.as_ptr()) }.is_null() { + unsafe { ll_setenv(root_c, rid_c.as_c_str()) }; + } + unsafe { ll_setenv(parent_c, rid_c.as_c_str()) }; +} + +#[cfg(unix)] +unsafe fn ll_setenv(key: &CStr, value: &CStr) { + unsafe { libc::setenv(key.as_ptr(), value.as_ptr(), 1) }; +} + +#[cfg(windows)] +unsafe fn ll_setenv(key: &CStr, value: &CStr) { + unsafe { libc::putenv_s(key.as_ptr(), value.as_ptr()) }; +} + +fn sessions_from_env(runtime_id: &str, get_env: F) -> TelemetryInstrumentationSessions +where + F: Fn(&str) -> Option, +{ + let session_id = runtime_id.to_owned(); + TelemetryInstrumentationSessions { + root_session_id: get_env(ENV_ROOT_RS_SESSION_ID).filter(|r| r != &session_id), + parent_session_id: get_env(ENV_PARENT_RS_SESSION_ID).filter(|p| p != &session_id), + session_id: Some(session_id), + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::collections::HashMap; + + fn env_map(items: &[(&str, &str)]) -> impl Fn(&str) -> Option { + let map: HashMap = items + .iter() + .map(|(k, v)| ((*k).to_string(), (*v).to_string())) + .collect(); + move |k| map.get(k).cloned() + } + + #[test] + fn no_lineage_when_env_unset() { + let s = sessions_from_env("rid-a", env_map(&[])); + assert_eq!(s.session_id.as_deref(), Some("rid-a")); + assert!(s.root_session_id.is_none()); + assert!(s.parent_session_id.is_none()); + } + + #[test] + fn drops_lineage_matching_runtime_id() { + let s = sessions_from_env( + "current", + env_map(&[ + (ENV_ROOT_RS_SESSION_ID, "current"), + (ENV_PARENT_RS_SESSION_ID, "current"), + ]), + ); + assert!(s.root_session_id.is_none()); + assert!(s.parent_session_id.is_none()); + } + + #[test] + fn captures_distinct_lineage() { + let s = sessions_from_env( + "current", + env_map(&[ + (ENV_ROOT_RS_SESSION_ID, "root-x"), + (ENV_PARENT_RS_SESSION_ID, "parent-x"), + ]), + ); + assert_eq!(s.session_id.as_deref(), Some("current")); + assert_eq!(s.root_session_id.as_deref(), Some("root-x")); + assert_eq!(s.parent_session_id.as_deref(), Some("parent-x")); + } +} diff --git a/datadog-opentelemetry/src/exporter/mod.rs b/datadog-opentelemetry/src/exporter/mod.rs index 1f8dd3e8..5e69de8e 100644 --- a/datadog-opentelemetry/src/exporter/mod.rs +++ b/datadog-opentelemetry/src/exporter/mod.rs @@ -9,12 +9,15 @@ use std::{ }; use crate::{dd_debug, dd_error}; +use libdd_capabilities_impl::NativeCapabilities; use libdd_data_pipeline::trace_exporter::{ agent_response::AgentResponse, error::{self as trace_exporter_error, TraceExporterError}, - TraceExporter, TraceExporterBuilder, + TraceExporter as LibddTraceExporter, TraceExporterBuilder, }; +pub type TraceExporter = LibddTraceExporter; + #[derive(Clone, Copy)] pub struct AsyncExporterConfig { /// Whether the async exporter waits for the trace chunks to be exported before returning from @@ -583,7 +586,7 @@ impl TraceExporterWorker { ) -> TraceExporterHandle { let handle = thread::spawn({ move || { - let trace_exporter = match builder.build() { + let trace_exporter = match builder.build::() { Ok(exporter) => exporter, Err(e) => { return Err(e); @@ -607,10 +610,16 @@ impl TraceExporterWorker { fn run(mut self) -> Result<(), TraceExporterError> { #[cfg(feature = "test-utils")] { - // Wait for the agent info to be fetched to get deterministic output when deciding - // to drop traces or not - self.trace_exporter - .wait_agent_info_ready(Duration::from_secs(5)) + // Block on the async `wait_agent_info_ready` from this plain + // `thread::spawn`; needed for deterministic sampling in tests. + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("tokio runtime for wait_agent_info_ready") + .block_on( + self.trace_exporter + .wait_agent_info_ready(Duration::from_secs(5)), + ) .unwrap(); } while let Ok((message, data)) = self.rx.receive(self.config.max_flush_interval) { diff --git a/datadog-opentelemetry/src/span_exporter.rs b/datadog-opentelemetry/src/span_exporter.rs index dbacfdad..6e739e17 100644 --- a/datadog-opentelemetry/src/span_exporter.rs +++ b/datadog-opentelemetry/src/span_exporter.rs @@ -5,15 +5,17 @@ use std::{sync::Arc, time::Duration}; use arc_swap::ArcSwap; use libdd_data_pipeline::trace_exporter::{ - agent_response::AgentResponse, error::TraceExporterError, TelemetryConfig, TraceExporter, + agent_response::AgentResponse, error::TraceExporterError, TelemetryConfig, TraceExporterOutputFormat, }; + use opentelemetry_sdk::{trace::SpanData, Resource}; use crate::{ configuration::Config, + core::telemetry_session, ddtrace_transform, - exporter::{AsyncExporterError, AsyncTraceExporter, Exporter, TraceChunk}, + exporter::{AsyncExporterError, AsyncTraceExporter, Exporter, TraceChunk, TraceExporter}, mappings::CachedConfig, }; @@ -61,6 +63,9 @@ impl DatadogExporter { runtime_id: Some(config.runtime_id().to_string()), debug_enabled: false, }); + builder.set_telemetry_instrumentation_sessions( + telemetry_session::sessions_from_runtime_id(config.runtime_id()), + ); } DatadogExporter { exporter: AsyncTraceExporter::new( diff --git a/instrumentation/Cargo.lock b/instrumentation/Cargo.lock index 757a9a90..c3391087 100644 --- a/instrumentation/Cargo.lock +++ b/instrumentation/Cargo.lock @@ -116,6 +116,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "borrow-or-share" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc0b364ead1874514c8c2855ab558056ebfeb775653e7ae45ff72f28f8f3166c" + [[package]] name = "bumpalo" version = "3.20.2" @@ -238,6 +244,22 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -333,6 +355,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctor" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "datadog-aws-lambda" version = "0.1.0" @@ -355,12 +387,14 @@ dependencies = [ "arc-swap", "base64 0.21.7", "criterion", + "ctor", "foldhash 0.1.5", "hashbrown 0.15.5", "http-body-util", "hyper", "hyper-util", "libc", + "libdd-capabilities-impl", "libdd-common", "libdd-data-pipeline", "libdd-library-config", @@ -433,6 +467,17 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "fluent-uri" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc74ac4d8359ae70623506d512209619e5cf8f347124910440dbc221714b328e" +dependencies = [ + "borrow-or-share", + "ref-cast", + "serde", +] + [[package]] name = "fnv" version = "1.0.7" @@ -565,8 +610,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -740,6 +787,22 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "tower-service", +] + [[package]] name = "hyper-timeout" version = "0.5.2" @@ -1042,11 +1105,37 @@ version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +[[package]] +name = "libdd-capabilities" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ce42b411956272ea0ff851dddbd8ea4dae251192ffdbc50e90e20737ffd600" +dependencies = [ + "anyhow", + "bytes", + "http", + "thiserror 1.0.69", +] + +[[package]] +name = "libdd-capabilities-impl" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79a6210d654b578a52ac4abe31f94b88f52740c8f2a62adc969cad240eae319d" +dependencies = [ + "bytes", + "http", + "http-body-util", + "libdd-capabilities", + "libdd-common", + "tokio", +] + [[package]] name = "libdd-common" -version = "3.0.2" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c779949577250487179d904508f18750070e9a01eb58dce378409ec5fa066f3b" +checksum = "933c5940905e9a3c8dd8c0439697b3fb327289cef7858370e6a5f440139f6314" dependencies = [ "anyhow", "bytes", @@ -1060,37 +1149,46 @@ dependencies = [ "http-body", "http-body-util", "hyper", + "hyper-rustls", "hyper-util", "libc", "nix", "pin-project", "regex", + "rustls", + "rustls-native-certs", "serde", "static_assertions", "thiserror 1.0.69", "tokio", + "tokio-rustls", "tower-service", "windows-sys 0.52.0", ] [[package]] name = "libdd-data-pipeline" -version = "3.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "358411451d99011f13c7628acee25dc144f2bbeade87acf10fa7d5ffce1053dc" +checksum = "3c0d0fcb6725d8399b46533a7eb023475e8b1be0da5942e25a34ef1efdfb2b43" dependencies = [ "anyhow", "arc-swap", + "async-trait", "bytes", "either", + "getrandom 0.2.17", "http", "http-body-util", + "libdd-capabilities", + "libdd-capabilities-impl", "libdd-common", "libdd-ddsketch", "libdd-dogstatsd-client", + "libdd-shared-runtime", "libdd-telemetry", "libdd-tinybytes", - "libdd-trace-protobuf 3.0.1", + "libdd-trace-protobuf 3.0.2", "libdd-trace-stats", "libdd-trace-utils", "rmp-serde", @@ -1114,9 +1212,9 @@ dependencies = [ [[package]] name = "libdd-dogstatsd-client" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f8eca39d1e2ef6267cf77fc51eb7ebc7d4f44827e150b4d317c29d8c33bf87" +checksum = "8f79afd4a3f84f80f6b631e4446d09131c156f1179295e390e9b4dc2bfa527cf" dependencies = [ "anyhow", "cadence", @@ -1144,14 +1242,34 @@ dependencies = [ "serde_yaml", ] +[[package]] +name = "libdd-shared-runtime" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9c295f7b55ec78e261537627a75be4e926a94e2b0014e98392b3f98e1957aa" +dependencies = [ + "async-trait", + "futures", + "futures-util", + "libdd-capabilities", + "libdd-capabilities-impl", + "libdd-common", + "tokio", + "tokio-util", + "tracing", + "wasm-bindgen-futures", +] + [[package]] name = "libdd-telemetry" -version = "4.0.0" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78774ffce79da677602829d7fe27468283e5349010e974257233edf4cd12b783" +checksum = "1662c33b446eed81b610b5d567ddb9c45c5b7587c6c23c5f5545a98b451cc0ba" dependencies = [ "anyhow", + "async-trait", "base64 0.22.1", + "bytes", "futures", "hashbrown 0.15.5", "http", @@ -1159,6 +1277,7 @@ dependencies = [ "libc", "libdd-common", "libdd-ddsketch", + "libdd-shared-runtime", "serde", "serde_json", "sys-info", @@ -1171,9 +1290,9 @@ dependencies = [ [[package]] name = "libdd-tinybytes" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47838e12ae2665250b4cdba4e3119230b79e3c522bb9f48dd0c87346f5a8f44" +checksum = "97db80e3f3f9d19643ac444d6267951a5dab622ad9828c51149d49150625cfe8" dependencies = [ "serde", ] @@ -1185,7 +1304,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab12e095f3589d02ceed76556e7aa8a1b5bc928a900e143b624e2331294e54b5" dependencies = [ "anyhow", - "libdd-trace-protobuf 3.0.1", + "libdd-trace-protobuf 3.0.2", +] + +[[package]] +name = "libdd-trace-obfuscation" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d30126bbcb5d10f0e4a97b39199e4918fb51abd37473606bc874c3e7a159bf1" +dependencies = [ + "anyhow", + "fluent-uri", + "libdd-common", + "libdd-trace-protobuf 3.0.2", + "libdd-trace-utils", + "log", + "percent-encoding", + "serde", + "serde_json", ] [[package]] @@ -1201,9 +1337,9 @@ dependencies = [ [[package]] name = "libdd-trace-protobuf" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1809242895edc53ac51a21287829f42474e749dbc222ea7f414cb3f0d1f91d4e" +checksum = "c67e3e9a09dab3f19d4f79006f3efb8b4bf8416551465edaeeb71816949e2197" dependencies = [ "prost", "serde", @@ -1212,33 +1348,51 @@ dependencies = [ [[package]] name = "libdd-trace-stats" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92b882863f7c531d51e73f7bc5930c705e47829332128d9bdcad0fea3b2b942" +checksum = "7f3d860f564da2ad30141a352fe4b924f8cf37dd0b32b3f4b0ef4ee52b9b43fe" dependencies = [ + "anyhow", + "arc-swap", + "async-trait", "hashbrown 0.15.5", + "http", + "libdd-capabilities", + "libdd-capabilities-impl", + "libdd-common", "libdd-ddsketch", - "libdd-trace-protobuf 3.0.1", + "libdd-shared-runtime", + "libdd-trace-obfuscation", + "libdd-trace-protobuf 3.0.2", "libdd-trace-utils", + "rmp-serde", + "serde", + "tokio", + "tokio-util", + "tracing", ] [[package]] name = "libdd-trace-utils" -version = "3.0.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870506e9bb79c93ce5bbfe9d715c53c7ea393a177c7299f0bf43745c0adea0c7" +checksum = "8442cf9c141da05cd170a6c230cba13b50d0bd3635df16928f296a7ad233b2d8" dependencies = [ "anyhow", + "base64 0.22.1", "bytes", "futures", + "getrandom 0.2.17", "http", "http-body", "http-body-util", "indexmap", + "libdd-capabilities", + "libdd-capabilities-impl", "libdd-common", "libdd-tinybytes", "libdd-trace-normalization", - "libdd-trace-protobuf 3.0.1", + "libdd-trace-protobuf 3.0.2", "prost", "rand 0.8.6", "rmp", @@ -1345,6 +1499,12 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + [[package]] name = "opentelemetry" version = "0.31.0" @@ -1645,6 +1805,26 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "regex" version = "1.12.3" @@ -1708,6 +1888,20 @@ dependencies = [ "web-sys", ] +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rmp" version = "0.8.15" @@ -1768,6 +1962,52 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.23.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.22" @@ -1789,6 +2029,38 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.28" @@ -1841,6 +2113,7 @@ version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ + "indexmap", "itoa", "memchr", "serde", @@ -1944,6 +2217,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.117" @@ -2080,6 +2359,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.18" @@ -2296,6 +2585,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.8" @@ -2815,6 +3110,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + [[package]] name = "zerotrie" version = "0.2.4"