From eb6f49b471d0da36deb493b4aaed8d16391f52cc Mon Sep 17 00:00:00 2001 From: Ayan Khan Date: Wed, 15 Apr 2026 14:01:37 -0400 Subject: [PATCH 1/4] feat(sidecar): wire telemetry_extended_heartbeat_interval through SessionConfig Add telemetry_extended_heartbeat_interval to the sidecar's SessionConfig and FFI so that callers (e.g. PHP) can configure the extended heartbeat interval. The telemetry worker already supports this field in its Config but the sidecar was not passing it through. Co-Authored-By: Claude Opus 4.6 (1M context) --- datadog-sidecar-ffi/src/lib.rs | 4 ++++ datadog-sidecar/src/service/mod.rs | 1 + datadog-sidecar/src/service/sidecar_server.rs | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/datadog-sidecar-ffi/src/lib.rs b/datadog-sidecar-ffi/src/lib.rs index eaa970c40a..b1f824387a 100644 --- a/datadog-sidecar-ffi/src/lib.rs +++ b/datadog-sidecar-ffi/src/lib.rs @@ -614,6 +614,7 @@ pub unsafe extern "C" fn ddog_sidecar_session_set_config( flush_interval_milliseconds: u32, remote_config_poll_interval_millis: u32, telemetry_heartbeat_interval_millis: u32, + telemetry_extended_heartbeat_interval_millis: u64, force_flush_size: usize, force_drop_size: usize, log_level: ffi::CharSlice, @@ -643,6 +644,9 @@ pub unsafe extern "C" fn ddog_sidecar_session_set_config( telemetry_heartbeat_interval: Duration::from_millis( telemetry_heartbeat_interval_millis as u64, ), + telemetry_extended_heartbeat_interval: Duration::from_millis( + telemetry_extended_heartbeat_interval_millis, + ), force_flush_size, force_drop_size, log_level: log_level.to_utf8_lossy().into(), diff --git a/datadog-sidecar/src/service/mod.rs b/datadog-sidecar/src/service/mod.rs index f5c4271577..4d1ebf2df8 100644 --- a/datadog-sidecar/src/service/mod.rs +++ b/datadog-sidecar/src/service/mod.rs @@ -58,6 +58,7 @@ pub struct SessionConfig { pub flush_interval: Duration, pub remote_config_poll_interval: Duration, pub telemetry_heartbeat_interval: Duration, + pub telemetry_extended_heartbeat_interval: Duration, pub force_flush_size: usize, pub force_drop_size: usize, pub log_level: String, diff --git a/datadog-sidecar/src/service/sidecar_server.rs b/datadog-sidecar/src/service/sidecar_server.rs index 27957846f2..2a34b5c593 100644 --- a/datadog-sidecar/src/service/sidecar_server.rs +++ b/datadog-sidecar/src/service/sidecar_server.rs @@ -640,12 +640,16 @@ impl SidecarInterface for ConnectionSidecarHandler { *session.process_tags.lock_or_panic() = config.process_tags.clone(); session.modify_telemetry_config(|cfg| { cfg.telemetry_heartbeat_interval = config.telemetry_heartbeat_interval; + cfg.telemetry_extended_heartbeat_interval = + config.telemetry_extended_heartbeat_interval; let endpoint = get_product_endpoint( libdd_telemetry::config::PROD_INTAKE_SUBDOMAIN, &config.endpoint, ); cfg.set_endpoint(endpoint).ok(); cfg.telemetry_heartbeat_interval = config.telemetry_heartbeat_interval; + cfg.telemetry_extended_heartbeat_interval = + config.telemetry_extended_heartbeat_interval; }); session.modify_trace_config(|cfg| { let endpoint = get_product_endpoint( From 755b54b6dedd6bc19f6a6d99623b3e262032bb68 Mon Sep 17 00:00:00 2001 From: Ayan Khan Date: Wed, 15 Apr 2026 14:09:00 -0400 Subject: [PATCH 2/4] fix(telemetry): use AppExtendedHeartbeat payload for extended heartbeat The ExtendedHeartbeat lifecycle action was wrapping the payload in Payload::AppStarted instead of Payload::AppExtendedHeartbeat, causing it to serialize as "app-started" instead of "app-extended-heartbeat". Co-Authored-By: Claude Opus 4.6 (1M context) --- libdd-telemetry/src/worker/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libdd-telemetry/src/worker/mod.rs b/libdd-telemetry/src/worker/mod.rs index 6da6725acf..aea0b0b5ea 100644 --- a/libdd-telemetry/src/worker/mod.rs +++ b/libdd-telemetry/src/worker/mod.rs @@ -483,9 +483,10 @@ impl TelemetryWorker { self.data.integrations.unflush_stored(); self.data.configurations.unflush_stored(); - let app_started = data::Payload::AppStarted(self.build_app_started()); - match self.send_payload(&app_started).await { - Ok(()) => self.payload_sent_success(&app_started), + let extended_hb = + data::Payload::AppExtendedHeartbeat(self.build_app_started()); + match self.send_payload(&extended_hb).await { + Ok(()) => self.payload_sent_success(&extended_hb), Err(err) => self.log_err(&err), } #[allow(clippy::unwrap_used)] From d414b2050a23a80feb2a16e95d9cb3714dd5cd55 Mon Sep 17 00:00:00 2001 From: Ayan Khan Date: Wed, 15 Apr 2026 14:29:09 -0400 Subject: [PATCH 3/4] fix: update FFI test call sites for new extended heartbeat param Add telemetry_extended_heartbeat_interval_millis argument (86400000ms = 24h default) to both ddog_sidecar_session_set_config calls in the sidecar FFI test. Co-Authored-By: Claude Opus 4.6 (1M context) --- datadog-sidecar-ffi/tests/sidecar.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/datadog-sidecar-ffi/tests/sidecar.rs b/datadog-sidecar-ffi/tests/sidecar.rs index 311f9b73a0..4d282ad4fe 100644 --- a/datadog-sidecar-ffi/tests/sidecar.rs +++ b/datadog-sidecar-ffi/tests/sidecar.rs @@ -98,6 +98,7 @@ fn test_ddog_sidecar_register_app() { 1000, 1000000, 1, + 86400000, 10000000, 10000000, "".into(), @@ -151,6 +152,7 @@ fn test_ddog_sidecar_register_app() { 1000, 1000000, 1, + 86400000, 10000000, 10000000, "".into(), From a03953e56ce16dd099fd80081311d9a89478b248 Mon Sep 17 00:00:00 2001 From: Ayan Khan Date: Wed, 15 Apr 2026 14:47:43 -0400 Subject: [PATCH 4/4] style: fix rustfmt line wrapping Co-Authored-By: Claude Opus 4.6 (1M context) --- libdd-telemetry/src/worker/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libdd-telemetry/src/worker/mod.rs b/libdd-telemetry/src/worker/mod.rs index aea0b0b5ea..a9179b428e 100644 --- a/libdd-telemetry/src/worker/mod.rs +++ b/libdd-telemetry/src/worker/mod.rs @@ -483,8 +483,7 @@ impl TelemetryWorker { self.data.integrations.unflush_stored(); self.data.configurations.unflush_stored(); - let extended_hb = - data::Payload::AppExtendedHeartbeat(self.build_app_started()); + let extended_hb = data::Payload::AppExtendedHeartbeat(self.build_app_started()); match self.send_payload(&extended_hb).await { Ok(()) => self.payload_sent_success(&extended_hb), Err(err) => self.log_err(&err),