Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
624bdac
feat(capabilities): trait architecture http draft
Aaalibaba42 Feb 11, 2026
f17efaa
feat: allow cross boundary default client
Aaalibaba42 Feb 13, 2026
37eb0d5
feat: example of using the DefaultHttpClient in libdatadog
Aaalibaba42 Feb 13, 2026
5ec05ba
feat(capabilities: http): increase trait api surface
Aaalibaba42 Feb 16, 2026
449306a
feat(capabilities): cargo patch version
Aaalibaba42 Feb 18, 2026
88fdae9
feat(capabilities): http capability throughout
Aaalibaba42 Feb 18, 2026
216119b
feat(capabilities: http): reuse client option
Aaalibaba42 Feb 18, 2026
f4586fc
fix: clippy + fmt
Aaalibaba42 Feb 18, 2026
3941878
chore: codeowner thingy
Aaalibaba42 Feb 18, 2026
853e0db
fix(capabilities: http): don't enforce invariants through type system…
Aaalibaba42 Feb 19, 2026
521a111
fix(ci): register new folders
Aaalibaba42 Feb 19, 2026
31b2bce
chore: license
Aaalibaba42 Feb 19, 2026
280cf5d
fix: forgot to re enable some tests
Aaalibaba42 Feb 19, 2026
d86a20b
chore: disable bench for capabilities crates
Aaalibaba42 Feb 19, 2026
892ff60
feat(capabilities: http): use http crate's types for easier hyper com…
Aaalibaba42 Feb 19, 2026
989a9b7
feat(http): more call sites converted
Aaalibaba42 Feb 23, 2026
67e13a5
fix: absorb isolate_hyper changes
Aaalibaba42 Feb 23, 2026
98679f5
Merge remote-tracking branch 'origin/main' into jwiriath/capability-t…
Aaalibaba42 Feb 23, 2026
0af6b20
chore: format
Aaalibaba42 Feb 23, 2026
78b3826
chore: 3rd party licenses
Aaalibaba42 Feb 23, 2026
8412225
fix(mini_agent): possibility of providing own client
Aaalibaba42 Feb 26, 2026
fad4ad7
chore(capabilities): use thiserror and anyhow instead of doing own er…
Aaalibaba42 Feb 26, 2026
ec8e331
fix: style
Aaalibaba42 Feb 26, 2026
f44f4cb
fix: cargo and http version consolidation
Aaalibaba42 Feb 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ docker-bake.hcl @DataDog/apm-common-components-core
docs @DataDog/libdatadog
examples @DataDog/libdatadog
libdd-alloc/ @DataDog/libdatadog-profiling
libdd-capabilities*/ @DataDog/apm-common-components-core
libdd-common*/ @DataDog/libdatadog
libdd-crashtracker*/ @DataDog/libdatadog-profiling
libdd-data-pipeline*/ @DataDog/libdatadog-apm
Expand Down
32 changes: 32 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ members = [
"libdd-trace-utils",
"libdd-trace-stats",
"datadog-tracer-flare",
"libdd-capabilities",
"libdd-capabilities-impl",
"libdd-common",
"libdd-common-ffi",
"libdd-telemetry",
Expand Down Expand Up @@ -107,3 +109,7 @@ codegen-units = 1
# so benchmarks are not measuring the same thing as the release build. This patch removes
# the default dependency on libm. A PR will be opened to proptest to make this optional.
proptest = { git = 'https://github.com/bantonsson/proptest.git', branch = "ban/avoid-libm-in-std" }

# Currently needs to live under patch but once it is on crates.io, only the
# integration would need to specify this.
libdd-capabilities-impl = { path = "libdd-capabilities-impl" }
2 changes: 1 addition & 1 deletion LICENSE-3rdparty.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
root_name: builder, build_common, tools, libdd-alloc, libdd-crashtracker, libdd-common, libdd-telemetry, libdd-ddsketch, libdd-crashtracker-ffi, libdd-common-ffi, datadog-ffe, datadog-ffe-ffi, datadog-ipc, datadog-ipc-macros, libdd-tinybytes, tarpc, tarpc-plugins, spawn_worker, cc_utils, libdd-library-config, libdd-library-config-ffi, datadog-live-debugger, libdd-data-pipeline, libdd-dogstatsd-client, libdd-trace-protobuf, libdd-trace-stats, libdd-trace-utils, libdd-trace-normalization, libdd-log, datadog-live-debugger-ffi, libdd-profiling, libdd-profiling-protobuf, libdd-profiling-ffi, libdd-data-pipeline-ffi, libdd-ddsketch-ffi, libdd-log-ffi, libdd-telemetry-ffi, symbolizer-ffi, datadog-profiling-replayer, datadog-remote-config, datadog-sidecar, datadog-sidecar-macros, datadog-sidecar-ffi, libdd-trace-obfuscation, datadog-tracer-flare, sidecar_mockgen, test_spawn_from_lib
root_name: builder, build_common, tools, libdd-alloc, libdd-crashtracker, libdd-common, libdd-capabilities, libdd-telemetry, libdd-capabilities-impl, libdd-ddsketch, libdd-crashtracker-ffi, libdd-common-ffi, datadog-ffe, datadog-ffe-ffi, datadog-ipc, datadog-ipc-macros, libdd-tinybytes, tarpc, tarpc-plugins, spawn_worker, cc_utils, libdd-library-config, libdd-library-config-ffi, datadog-live-debugger, libdd-data-pipeline, libdd-dogstatsd-client, libdd-trace-protobuf, libdd-trace-stats, libdd-trace-utils, libdd-trace-normalization, libdd-log, datadog-live-debugger-ffi, libdd-profiling, libdd-profiling-protobuf, libdd-profiling-ffi, libdd-data-pipeline-ffi, libdd-ddsketch-ffi, libdd-log-ffi, libdd-telemetry-ffi, symbolizer-ffi, datadog-profiling-replayer, datadog-remote-config, datadog-sidecar, datadog-sidecar-macros, datadog-sidecar-ffi, libdd-trace-obfuscation, datadog-tracer-flare, sidecar_mockgen, test_spawn_from_lib, bin_tests
third_party_libraries:
- package_name: addr2line
package_version: 0.24.2
Expand Down
4 changes: 2 additions & 2 deletions datadog-remote-config/src/fetch/test_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,9 @@ impl RemoteConfigServer {
tracer_version: "1.2.3".to_string(),
endpoint: self.endpoint.clone(),
},
#[cfg(not(feature = "live-debugger"))]
#[cfg(not(all(feature = "live-debugger", not(target_arch = "wasm32"))))]
products: vec![RemoteConfigProduct::ApmTracing],
#[cfg(feature = "live-debugger")]
#[cfg(all(feature = "live-debugger", not(target_arch = "wasm32")))]
products: vec![
RemoteConfigProduct::ApmTracing,
RemoteConfigProduct::LiveDebugger,
Expand Down
8 changes: 4 additions & 4 deletions datadog-remote-config/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ use crate::{
};
#[cfg(feature = "ffe")]
use datadog_ffe::rules_based::UniversalFlagConfig;
#[cfg(feature = "live-debugger")]
#[cfg(all(feature = "live-debugger", not(target_arch = "wasm32")))]
use datadog_live_debugger::LiveDebuggingData;

#[derive(Debug)]
pub enum RemoteConfigData {
DynamicConfig(DynamicConfigFile),
#[cfg(feature = "live-debugger")]
#[cfg(all(feature = "live-debugger", not(target_arch = "wasm32")))]
LiveDebugger(LiveDebuggingData),
TracerFlareConfig(AgentConfigFile),
TracerFlareTask(AgentTaskFile),
Expand All @@ -39,7 +39,7 @@ impl RemoteConfigData {
RemoteConfigProduct::ApmTracing => {
RemoteConfigData::DynamicConfig(config::dynamic::parse_json(data)?)
}
#[cfg(feature = "live-debugger")]
#[cfg(all(feature = "live-debugger", not(target_arch = "wasm32")))]
RemoteConfigProduct::LiveDebugger => {
let parsed = datadog_live_debugger::parse_json(&String::from_utf8_lossy(data))?;
RemoteConfigData::LiveDebugger(parsed)
Expand All @@ -57,7 +57,7 @@ impl From<&RemoteConfigData> for RemoteConfigProduct {
fn from(value: &RemoteConfigData) -> Self {
match value {
RemoteConfigData::DynamicConfig(_) => RemoteConfigProduct::ApmTracing,
#[cfg(feature = "live-debugger")]
#[cfg(all(feature = "live-debugger", not(target_arch = "wasm32")))]
RemoteConfigData::LiveDebugger(_) => RemoteConfigProduct::LiveDebugger,
RemoteConfigData::TracerFlareConfig(_) => RemoteConfigProduct::AgentConfig,
RemoteConfigData::TracerFlareTask(_) => RemoteConfigProduct::AgentTask,
Expand Down
6 changes: 3 additions & 3 deletions datadog-remote-config/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub enum RemoteConfigProduct {
AsmDD,
AsmFeatures,
FfeFlags,
#[cfg(feature = "live-debugger")]
#[cfg(all(feature = "live-debugger", not(target_arch = "wasm32")))]
LiveDebugger,
}

Expand All @@ -39,7 +39,7 @@ impl Display for RemoteConfigProduct {
RemoteConfigProduct::AsmDD => "ASM_DD",
RemoteConfigProduct::AsmFeatures => "ASM_FEATURES",
RemoteConfigProduct::FfeFlags => "FFE_FLAGS",
#[cfg(feature = "live-debugger")]
#[cfg(all(feature = "live-debugger", not(target_arch = "wasm32")))]
RemoteConfigProduct::LiveDebugger => "LIVE_DEBUGGING",
};
write!(f, "{str}")
Expand Down Expand Up @@ -90,7 +90,7 @@ impl RemoteConfigPath {
"ASM_DD" => RemoteConfigProduct::AsmDD,
"ASM_FEATURES" => RemoteConfigProduct::AsmFeatures,
"FFE_FLAGS" => RemoteConfigProduct::FfeFlags,
#[cfg(feature = "live-debugger")]
#[cfg(all(feature = "live-debugger", not(target_arch = "wasm32")))]
"LIVE_DEBUGGING" => RemoteConfigProduct::LiveDebugger,
product => anyhow::bail!("Unknown product {}", product),
},
Expand Down
15 changes: 3 additions & 12 deletions datadog-sidecar/src/service/tracing/trace_flusher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ use super::TraceSendData;
use crate::agent_remote_config::AgentRemoteConfigWriter;
use datadog_ipc::platform::NamedShmHandle;
use futures::future::join_all;
use http_body_util::BodyExt;
use libdd_common::http_common::new_default_client;
use libdd_common::{Endpoint, HttpClient, MutexExt};
use libdd_common::{Endpoint, MutexExt};
use libdd_trace_utils::trace_utils;
use libdd_trace_utils::trace_utils::SendData;
use libdd_trace_utils::trace_utils::SendDataResult;
Expand Down Expand Up @@ -96,7 +94,6 @@ pub(crate) struct TraceFlusher {
pub(crate) min_force_drop_size_bytes: AtomicU32, // put a limit on memory usage
remote_config: Mutex<AgentRemoteConfigs>,
pub metrics: Mutex<TraceFlusherMetrics>,
client: HttpClient,
}
impl Default for TraceFlusher {
fn default() -> Self {
Expand All @@ -107,7 +104,6 @@ impl Default for TraceFlusher {
min_force_drop_size_bytes: AtomicU32::new(trace_utils::MAX_PAYLOAD_SIZE as u32),
remote_config: Mutex::new(Default::default()),
metrics: Mutex::new(Default::default()),
client: new_default_client(),
}
}
}
Expand Down Expand Up @@ -249,18 +245,13 @@ impl TraceFlusher {

async fn send_and_handle_trace(&self, send_data: SendData) {
let endpoint = send_data.get_target().clone();
let response = send_data.send(&self.client).await;
let response = send_data.send().await;
self.metrics.lock_or_panic().update(&response);
match response.last_result {
Ok(response) => {
if endpoint.api_key.is_none() {
// not when intake
match response.into_body().collect().await {
Ok(body) => {
self.write_remote_configs(endpoint.clone(), body.to_bytes().to_vec())
}
Err(e) => error!("Error receiving agent configuration: {e:?}"),
}
self.write_remote_configs(endpoint.clone(), response.into_body().to_vec());
}
info!("Successfully flushed traces to {endpoint:?}");
}
Expand Down
6 changes: 4 additions & 2 deletions datadog-tracer-flare/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ publish = false

[dependencies]
anyhow = "1.0"
bytes = "1.4"
http = "1"
libdd-capabilities = { path = "../libdd-capabilities" }
libdd-capabilities-impl = { path = "../libdd-capabilities-impl" }
libdd-common = { path = "../libdd-common" }
datadog-remote-config = { path = "../datadog-remote-config", default-features = false }
libdd-trace-utils = { path = "../libdd-trace-utils" }
http = "1"
bytes = "1.4"
tokio = { version = "1.36.0", features = ["time"] }
serde_json = "1.0"
zip = "4.0.0"
Expand Down
20 changes: 20 additions & 0 deletions libdd-capabilities-impl/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/
# SPDX-License-Identifier: Apache-2.0

[package]
name = "libdd-capabilities-impl"
version = "0.1.0"
edition = "2021"
description = "Native implementations of libdd-capabilities traits"

[lib]
crate-type = ["lib"]
bench = false

[dependencies]
libdd-capabilities = { path = "../libdd-capabilities" }
libdd-common = { path = "../libdd-common" }
hyper = { workspace = true }
http = "1"
bytes = "1.4"
http-body-util = "0.1"
48 changes: 48 additions & 0 deletions libdd-capabilities-impl/src/http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

//! HTTP capability implementation using hyper.

use bytes::Bytes;
use http_body_util::BodyExt;
use libdd_capabilities::http::{HttpClientTrait, HttpError};
use libdd_capabilities::maybe_send::MaybeSend;
use libdd_common::{connector::Connector, http_common};

pub struct DefaultHttpClient {
client: http_common::GenericHttpClient<Connector>,
}

impl HttpClientTrait for DefaultHttpClient {
fn new_client() -> Self {
Self {
client: http_common::new_default_client(),
}
}

#[allow(clippy::manual_async_fn)]
fn request(
&self,
req: http::Request<Bytes>,
) -> impl std::future::Future<Output = Result<http::Response<Bytes>, HttpError>> + MaybeSend
{
let client = self.client.clone();
async move {
let hyper_req = req.map(http_common::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(http::Response::from_parts(parts, collected))
}
}
}
12 changes: 12 additions & 0 deletions libdd-capabilities-impl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

//! Native capability implementations.
//!
//! This crate is patchable: `libdatadog-nodejs` overrides it via
//! `[patch.crates-io]` with wasm implementations backed by JS transports.
//! Both versions export the same `DefaultHttpClient` type.

mod http;

pub use http::DefaultHttpClient;
21 changes: 21 additions & 0 deletions libdd-capabilities/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/
# SPDX-License-Identifier: Apache-2.0

[package]
name = "libdd-capabilities"
version = "0.1.0"
edition = "2021"
description = "Portable capability traits for cross-platform libdatadog"
homepage = "https://github.com/DataDog/libdatadog"
repository = "https://github.com/DataDog/libdatadog"
license = "Apache-2.0"

[lib]
crate-type = ["lib"]
bench = false

[dependencies]
http = "1"
bytes = "1.4"
anyhow = "1.0"
thiserror = "1.0"
34 changes: 34 additions & 0 deletions libdd-capabilities/src/http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

//! HTTP capability trait and error types.
//!
//! Request and response types are provided by the [`http`] crate, which is a
//! pure-types crate with no platform dependencies (compiles on wasm). The body
//! type is [`bytes::Bytes`].

use crate::maybe_send::MaybeSend;
use core::future::Future;

#[derive(Debug, thiserror::Error)]
pub enum HttpError {
#[error("Network error: {0}")]
Network(anyhow::Error),
#[error("Request timed out")]
Timeout,
#[error("Response body error: {0}")]
ResponseBody(anyhow::Error),
#[error("Invalid request: {0}")]
InvalidRequest(anyhow::Error),
#[error("HTTP error: {0}")]
Other(anyhow::Error),
}

pub trait HttpClientTrait {
fn new_client() -> Self;

fn request(
&self,
req: http::Request<bytes::Bytes>,
) -> impl Future<Output = Result<http::Response<bytes::Bytes>, HttpError>> + MaybeSend;
}
10 changes: 10 additions & 0 deletions libdd-capabilities/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

//! Portable capability traits for cross-platform libdatadog.

pub mod http;
pub mod maybe_send;

pub use self::http::{HttpClientTrait, HttpError};
pub use maybe_send::MaybeSend;
Loading
Loading