diff --git a/Cargo.lock b/Cargo.lock index 8970e45a..a5c225a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -448,7 +448,7 @@ dependencies = [ "dogstatsd", "figment", "libdd-trace-obfuscation", - "libdd-trace-utils 3.0.0", + "libdd-trace-utils 3.0.1", "log", "serde", "serde-aux", @@ -542,7 +542,7 @@ dependencies = [ "datadog-logs-agent", "datadog-trace-agent", "dogstatsd", - "libdd-trace-utils 3.0.0", + "libdd-trace-utils 3.0.1", "reqwest", "serde_json", "tokio", @@ -565,10 +565,11 @@ dependencies = [ "hyper", "hyper-http-proxy", "hyper-util", - "libdd-common 3.0.1", + "libdd-capabilities", + "libdd-common 3.0.2", "libdd-trace-obfuscation", - "libdd-trace-protobuf 3.0.0", - "libdd-trace-utils 3.0.0", + "libdd-trace-protobuf 3.0.1", + "libdd-trace-utils 3.0.1", "reqwest", "rmp-serde", "serde", @@ -1431,6 +1432,28 @@ version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +[[package]] +name = "libdd-capabilities" +version = "0.1.0" +source = "git+https://github.com/DataDog/libdatadog?rev=986aab55cb7941d8453dffb59d35a70599d08665#986aab55cb7941d8453dffb59d35a70599d08665" +dependencies = [ + "anyhow", + "bytes", + "http", + "thiserror 1.0.69", +] + +[[package]] +name = "libdd-capabilities-impl" +version = "0.1.0" +source = "git+https://github.com/DataDog/libdatadog?rev=986aab55cb7941d8453dffb59d35a70599d08665#986aab55cb7941d8453dffb59d35a70599d08665" +dependencies = [ + "bytes", + "http", + "libdd-capabilities", + "libdd-common 3.0.2", +] + [[package]] name = "libdd-common" version = "2.0.1" @@ -1464,8 +1487,8 @@ dependencies = [ [[package]] name = "libdd-common" -version = "3.0.1" -source = "git+https://github.com/DataDog/libdatadog?rev=8c88979985154d6d97c0fc2ca9039682981eacad#8c88979985154d6d97c0fc2ca9039682981eacad" +version = "3.0.2" +source = "git+https://github.com/DataDog/libdatadog?rev=986aab55cb7941d8453dffb59d35a70599d08665#986aab55cb7941d8453dffb59d35a70599d08665" dependencies = [ "anyhow", "bytes", @@ -1482,6 +1505,7 @@ dependencies = [ "hyper-rustls", "hyper-util", "libc", + "libdd-capabilities", "nix", "pin-project", "regex", @@ -1586,7 +1610,7 @@ dependencies = [ [[package]] name = "libdd-tinybytes" version = "1.1.0" -source = "git+https://github.com/DataDog/libdatadog?rev=8c88979985154d6d97c0fc2ca9039682981eacad#8c88979985154d6d97c0fc2ca9039682981eacad" +source = "git+https://github.com/DataDog/libdatadog?rev=986aab55cb7941d8453dffb59d35a70599d08665#986aab55cb7941d8453dffb59d35a70599d08665" dependencies = [ "serde", ] @@ -1603,23 +1627,23 @@ dependencies = [ [[package]] name = "libdd-trace-normalization" -version = "1.0.3" -source = "git+https://github.com/DataDog/libdatadog?rev=8c88979985154d6d97c0fc2ca9039682981eacad#8c88979985154d6d97c0fc2ca9039682981eacad" +version = "2.0.0" +source = "git+https://github.com/DataDog/libdatadog?rev=986aab55cb7941d8453dffb59d35a70599d08665#986aab55cb7941d8453dffb59d35a70599d08665" dependencies = [ "anyhow", - "libdd-trace-protobuf 3.0.0", + "libdd-trace-protobuf 3.0.1", ] [[package]] name = "libdd-trace-obfuscation" -version = "1.0.1" -source = "git+https://github.com/DataDog/libdatadog?rev=8c88979985154d6d97c0fc2ca9039682981eacad#8c88979985154d6d97c0fc2ca9039682981eacad" +version = "2.0.0" +source = "git+https://github.com/DataDog/libdatadog?rev=986aab55cb7941d8453dffb59d35a70599d08665#986aab55cb7941d8453dffb59d35a70599d08665" dependencies = [ "anyhow", "fluent-uri", - "libdd-common 3.0.1", - "libdd-trace-protobuf 3.0.0", - "libdd-trace-utils 3.0.0", + "libdd-common 3.0.2", + "libdd-trace-protobuf 3.0.1", + "libdd-trace-utils 3.0.1", "log", "percent-encoding", "regex", @@ -1640,8 +1664,8 @@ dependencies = [ [[package]] name = "libdd-trace-protobuf" -version = "3.0.0" -source = "git+https://github.com/DataDog/libdatadog?rev=8c88979985154d6d97c0fc2ca9039682981eacad#8c88979985154d6d97c0fc2ca9039682981eacad" +version = "3.0.1" +source = "git+https://github.com/DataDog/libdatadog?rev=986aab55cb7941d8453dffb59d35a70599d08665#986aab55cb7941d8453dffb59d35a70599d08665" dependencies = [ "prost 0.14.3", "serde", @@ -1690,25 +1714,29 @@ dependencies = [ [[package]] name = "libdd-trace-utils" -version = "3.0.0" -source = "git+https://github.com/DataDog/libdatadog?rev=8c88979985154d6d97c0fc2ca9039682981eacad#8c88979985154d6d97c0fc2ca9039682981eacad" +version = "3.0.1" +source = "git+https://github.com/DataDog/libdatadog?rev=986aab55cb7941d8453dffb59d35a70599d08665#986aab55cb7941d8453dffb59d35a70599d08665" dependencies = [ "anyhow", + "base64 0.22.1", "bytes", "cargo-platform", "cargo_metadata", "flate2", "futures", + "getrandom 0.2.17", "http", "http-body", "http-body-util", "httpmock", "hyper", "indexmap", - "libdd-common 3.0.1", - "libdd-tinybytes 1.1.0 (git+https://github.com/DataDog/libdatadog?rev=8c88979985154d6d97c0fc2ca9039682981eacad)", - "libdd-trace-normalization 1.0.3", - "libdd-trace-protobuf 3.0.0", + "libdd-capabilities", + "libdd-capabilities-impl", + "libdd-common 3.0.2", + "libdd-tinybytes 1.1.0 (git+https://github.com/DataDog/libdatadog?rev=986aab55cb7941d8453dffb59d35a70599d08665)", + "libdd-trace-normalization 2.0.0", + "libdd-trace-protobuf 3.0.1", "prost 0.14.3", "rand 0.8.5", "rmp", @@ -1906,9 +1934,9 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "openssl-probe" -version = "0.2.1" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "opentelemetry" @@ -2196,7 +2224,7 @@ version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" dependencies = [ - "heck 0.5.0", + "heck 0.4.1", "itertools 0.14.0", "log", "multimap", @@ -2654,9 +2682,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" dependencies = [ "openssl-probe", "rustls-pki-types", @@ -2676,9 +2704,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.10" +version = "0.103.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" +checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" dependencies = [ "aws-lc-rs", "ring", diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 2d04b2ad..90d2e0fe 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -118,6 +118,8 @@ js-sys,https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/js-sys,MI lazy_static,https://github.com/rust-lang-nursery/lazy-static.rs,MIT OR Apache-2.0,Marvin Löbel leb128fmt,https://github.com/bluk/leb128fmt,MIT OR Apache-2.0,Bryant Luk 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 @@ -148,7 +150,7 @@ nom,https://github.com/Geal/nom,MIT,contact@geoffroycouprie.com nu-ansi-term,https://github.com/nushell/nu-ansi-term,MIT,"ogham@bsago.me, Ryan Scheel (Havvy) , Josh Triplett , The Nushell Project Developers" num-traits,https://github.com/rust-num/num-traits,MIT OR Apache-2.0,The Rust Project Developers once_cell,https://github.com/matklad/once_cell,MIT OR Apache-2.0,Aleksey Kladov -openssl-probe,https://github.com/rustls/openssl-probe,MIT OR Apache-2.0,Alex Crichton +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-semantic-conventions,https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-semantic-conventions,Apache-2.0,The opentelemetry-semantic-conventions Authors opentelemetry_sdk,https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-sdk,Apache-2.0,The opentelemetry_sdk Authors diff --git a/crates/datadog-agent-config/Cargo.toml b/crates/datadog-agent-config/Cargo.toml index b9477aca..bd87bcb1 100644 --- a/crates/datadog-agent-config/Cargo.toml +++ b/crates/datadog-agent-config/Cargo.toml @@ -6,8 +6,8 @@ license.workspace = true [dependencies] figment = { version = "0.10", default-features = false, features = ["yaml", "env"] } -libdd-trace-obfuscation = { git = "https://github.com/DataDog/libdatadog", rev = "8c88979985154d6d97c0fc2ca9039682981eacad" } -libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog", rev = "8c88979985154d6d97c0fc2ca9039682981eacad" } +libdd-trace-obfuscation = { git = "https://github.com/DataDog/libdatadog", rev = "986aab55cb7941d8453dffb59d35a70599d08665" } +libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog", rev = "986aab55cb7941d8453dffb59d35a70599d08665" } log = { version = "0.4", default-features = false } serde = { version = "1.0", default-features = false, features = ["derive"] } serde-aux = { version = "4.7", default-features = false } diff --git a/crates/datadog-fips/Cargo.toml b/crates/datadog-fips/Cargo.toml index 9758f41b..e09a358d 100644 --- a/crates/datadog-fips/Cargo.toml +++ b/crates/datadog-fips/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace = true [dependencies] reqwest = { version = "0.12.4", features = ["json", "http2"], default-features = false } rustls = { version = "0.23.18", default-features = false, features = ["fips"], optional = true } -rustls-native-certs = { version = "0.8.1", optional = true } +rustls-native-certs = { version = ">=0.8.1, <0.8.3", optional = true } tracing = { version = "0.1.40", default-features = false } [features] diff --git a/crates/datadog-serverless-compat/Cargo.toml b/crates/datadog-serverless-compat/Cargo.toml index b84bb15f..6d999401 100644 --- a/crates/datadog-serverless-compat/Cargo.toml +++ b/crates/datadog-serverless-compat/Cargo.toml @@ -12,7 +12,7 @@ windows-pipes = ["datadog-trace-agent/windows-pipes", "dogstatsd/windows-pipes"] [dependencies] datadog-logs-agent = { path = "../datadog-logs-agent" } datadog-trace-agent = { path = "../datadog-trace-agent" } -libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog", rev = "8c88979985154d6d97c0fc2ca9039682981eacad" } +libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog", rev = "986aab55cb7941d8453dffb59d35a70599d08665" } datadog-fips = { path = "../datadog-fips", default-features = false } dogstatsd = { path = "../dogstatsd", default-features = true } reqwest = { version = "0.12.4", default-features = false } diff --git a/crates/datadog-trace-agent/Cargo.toml b/crates/datadog-trace-agent/Cargo.toml index 1a69733a..8cb9de03 100644 --- a/crates/datadog-trace-agent/Cargo.toml +++ b/crates/datadog-trace-agent/Cargo.toml @@ -24,12 +24,13 @@ async-trait = "0.1.64" tracing = { version = "0.1", default-features = false } serde = { version = "1.0.145", features = ["derive"] } serde_json = "1.0" -libdd-common = { git = "https://github.com/DataDog/libdatadog", rev = "8c88979985154d6d97c0fc2ca9039682981eacad" } -libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog", rev = "8c88979985154d6d97c0fc2ca9039682981eacad" } -libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog", rev = "8c88979985154d6d97c0fc2ca9039682981eacad", features = [ +libdd-capabilities = { git = "https://github.com/DataDog/libdatadog", rev = "986aab55cb7941d8453dffb59d35a70599d08665" } +libdd-common = { git = "https://github.com/DataDog/libdatadog", rev = "986aab55cb7941d8453dffb59d35a70599d08665" } +libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog", rev = "986aab55cb7941d8453dffb59d35a70599d08665" } +libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog", rev = "986aab55cb7941d8453dffb59d35a70599d08665", features = [ "mini_agent", ] } -libdd-trace-obfuscation = { git = "https://github.com/DataDog/libdatadog", rev = "8c88979985154d6d97c0fc2ca9039682981eacad" } +libdd-trace-obfuscation = { git = "https://github.com/DataDog/libdatadog", rev = "986aab55cb7941d8453dffb59d35a70599d08665" } datadog-fips = { path = "../datadog-fips" } reqwest = { version = "0.12.23", features = ["json", "http2"], default-features = false } bytes = "1.10.1" @@ -40,6 +41,6 @@ serial_test = "2.0.0" duplicate = "0.4.1" temp-env = "0.3.6" tempfile = "3.3.0" -libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog", rev = "8c88979985154d6d97c0fc2ca9039682981eacad", features = [ +libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog", rev = "986aab55cb7941d8453dffb59d35a70599d08665", features = [ "test-utils", ] } diff --git a/crates/datadog-trace-agent/src/config.rs b/crates/datadog-trace-agent/src/config.rs index 5a7b8a8c..ddbd8207 100644 --- a/crates/datadog-trace-agent/src/config.rs +++ b/crates/datadog-trace-agent/src/config.rs @@ -296,6 +296,7 @@ mod tests { [ ("DD_API_KEY", Some("_not_a_real_key_")), ("K_SERVICE", Some("function_name")), + ("FUNCTION_TARGET", Some("function_target")), ], || { let config_res = config::Config::new(); @@ -329,6 +330,7 @@ mod tests { [ ("DD_API_KEY", Some("_not_a_real_key_")), ("K_SERVICE", Some("function_name")), + ("FUNCTION_TARGET", Some("function_target")), ("DD_SITE", Some(dd_site)), ], || { @@ -356,6 +358,7 @@ mod tests { [ ("DD_API_KEY", Some("_not_a_real_key_")), ("K_SERVICE", Some("function_name")), + ("FUNCTION_TARGET", Some("function_target")), ("DD_SITE", Some(dd_site)), ], || { @@ -374,6 +377,7 @@ mod tests { [ ("DD_API_KEY", Some("_not_a_real_key_")), ("K_SERVICE", Some("function_name")), + ("FUNCTION_TARGET", Some("function_target")), ("DD_APM_DD_URL", Some("http://127.0.0.1:3333")), ], || { diff --git a/crates/datadog-trace-agent/src/stats_flusher.rs b/crates/datadog-trace-agent/src/stats_flusher.rs index 6c6e5805..3bee237c 100644 --- a/crates/datadog-trace-agent/src/stats_flusher.rs +++ b/crates/datadog-trace-agent/src/stats_flusher.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use async_trait::async_trait; +use libdd_common::DefaultHttpClient; use std::{sync::Arc, time}; use tokio::sync::{Mutex, mpsc::Receiver}; use tracing::{debug, error}; @@ -76,7 +77,7 @@ impl StatsFlusher for ServerlessStatsFlusher { }; #[allow(clippy::unwrap_used)] - match stats_utils::send_stats_payload( + match stats_utils::send_stats_payload::( serialized_stats_payload, &config.trace_stats_intake, config.trace_stats_intake.api_key.as_ref().unwrap(), diff --git a/crates/datadog-trace-agent/src/trace_flusher.rs b/crates/datadog-trace-agent/src/trace_flusher.rs index 9efebac6..638e3fde 100644 --- a/crates/datadog-trace-agent/src/trace_flusher.rs +++ b/crates/datadog-trace-agent/src/trace_flusher.rs @@ -6,7 +6,11 @@ use std::{error::Error, sync::Arc, time}; use tokio::sync::{Mutex, mpsc::Receiver}; use tracing::{debug, error}; -use libdd_common::{GenericHttpClient, http_common}; +use http_body_util::BodyExt; +use libdd_capabilities::http::{HttpClientTrait, HttpError}; +use libdd_capabilities::{MaybeSend, Request, Response}; +use libdd_common::connector::Connector; +use libdd_common::http_common::{self, Body, GenericHttpClient}; use libdd_trace_utils::trace_utils; use libdd_trace_utils::trace_utils::SendData; @@ -75,14 +79,13 @@ impl TraceFlusher for ServerlessTraceFlusher { } debug!("Flushing {} traces", traces.len()); - let http_client = - match ServerlessTraceFlusher::get_http_client(self.config.proxy_url.as_ref()) { - Ok(client) => client, - Err(e) => { - error!("Failed to create HTTP client: {e:?}"); - return; - } - }; + let http_client = match ProxyHttpClient::with_proxy(self.config.proxy_url.as_ref()) { + Ok(client) => client, + Err(e) => { + error!("Failed to create HTTP client: {e:?}"); + return; + } + }; // Retries are handled internally by SendData::send() for coalesced_traces in trace_utils::coalesce_send_data(traces) { @@ -97,26 +100,63 @@ impl TraceFlusher for ServerlessTraceFlusher { } } -impl ServerlessTraceFlusher { - fn get_http_client( - proxy_https: Option<&String>, - ) -> Result< - GenericHttpClient>, - Box, - > { +#[derive(Clone)] +struct ProxyHttpClient { + client: GenericHttpClient>, +} + +impl std::fmt::Debug for ProxyHttpClient { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ProxyHttpClient").finish() + } +} + +impl ProxyHttpClient { + // `HttpClientTrait::new_client` takes no arguments, so we use `with_proxy` to + // take in the proxy URL and build the client. `new_client` is never called on our code path. + fn with_proxy(proxy_https: Option<&String>) -> Result> { if let Some(proxy) = proxy_https { let proxy = hyper_http_proxy::Proxy::new(hyper_http_proxy::Intercept::Https, proxy.parse()?); - let proxy_connector = hyper_http_proxy::ProxyConnector::from_proxy( - libdd_common::connector::Connector::default(), - proxy, - )?; - Ok(http_common::client_builder().build(proxy_connector)) + let proxy_connector = + hyper_http_proxy::ProxyConnector::from_proxy(Connector::default(), proxy)?; + Ok(Self { + client: http_common::client_builder().build(proxy_connector), + }) } else { - let proxy_connector = hyper_http_proxy::ProxyConnector::new( - libdd_common::connector::Connector::default(), - )?; - Ok(http_common::client_builder().build(proxy_connector)) + let proxy_connector = hyper_http_proxy::ProxyConnector::new(Connector::default())?; + Ok(Self { + client: http_common::client_builder().build(proxy_connector), + }) + } + } +} + +impl HttpClientTrait for ProxyHttpClient { + #[allow(clippy::expect_used)] + fn new_client() -> Self { + Self::with_proxy(None).expect("building proxy connector with default TLS should not fail") + } + + fn request( + &self, + req: Request, + ) -> impl std::future::Future, HttpError>> + MaybeSend + { + let client = self.client.clone(); + async move { + let hyper_req = req.map(Body::from_bytes); + let response = client + .request(hyper_req) + .await + .map_err(|e| HttpError::Network(e.into()))?; + let (parts, body) = response.into_parts(); + let collected = body + .collect() + .await + .map_err(|e| HttpError::ResponseBody(e.into()))? + .to_bytes(); + Ok(Response::from_parts(parts, collected)) } } }