From fd1b9e7ddcf38df899adfeb922d24791093a849f Mon Sep 17 00:00:00 2001 From: Kathie Huang Date: Fri, 15 May 2026 13:07:40 -0400 Subject: [PATCH 1/7] Calculate CPU usage and submit metric --- Cargo.lock | 107 +++++++++++++++++- crates/datadog-metrics-collector/Cargo.toml | 5 +- .../src/azure_windows.rs | 37 +++++- crates/datadog-serverless-compat/src/main.rs | 6 - 4 files changed, 142 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b0082d..a3304ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -495,6 +495,7 @@ dependencies = [ "libdd-common 4.0.0", "tokio", "tracing", + "windows 0.62.2", ] [[package]] @@ -3764,12 +3765,107 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core", + "windows-link", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core", + "windows-link", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -3854,6 +3950,15 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -3998,7 +4103,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e0e7162b9e282fd75a0a832cce93994bdb21208d848a418cd05a5fdd9b9ab33" dependencies = [ - "windows", + "windows 0.48.0", ] [[package]] diff --git a/crates/datadog-metrics-collector/Cargo.toml b/crates/datadog-metrics-collector/Cargo.toml index b6f5d4e..aefa85d 100644 --- a/crates/datadog-metrics-collector/Cargo.toml +++ b/crates/datadog-metrics-collector/Cargo.toml @@ -10,8 +10,11 @@ dogstatsd = { path = "../dogstatsd", default-features = true } tracing = { version = "0.1", default-features = false } libdd-common = { git = "https://github.com/DataDog/libdatadog", rev = "4ae8ebe252451374c292efd159ce254c3f5a72e0", default-features = false } +[target.'cfg(windows)'.dependencies] +windows = { version = "0.62", features = ["Win32_System_JobObjects"], optional = true } + [dev-dependencies] tokio = { version = "1", default-features = false, features = ["macros", "rt-multi-thread"] } [features] -windows-enhanced-metrics = [] +windows-enhanced-metrics = ["windows"] \ No newline at end of file diff --git a/crates/datadog-metrics-collector/src/azure_windows.rs b/crates/datadog-metrics-collector/src/azure_windows.rs index ecebb89..800bd37 100644 --- a/crates/datadog-metrics-collector/src/azure_windows.rs +++ b/crates/datadog-metrics-collector/src/azure_windows.rs @@ -3,18 +3,45 @@ //! CPU metrics collector for Azure Functions (Windows) //! -//! NOTE: Windows CPU enhanced metrics are not yet supported. -//! WindowsCpuStatsReader currently always returns None, so no CPU -//! usage information is reported in Windows environments. +//! This module provides functionality to read CPU usage from Windows Job Objects. //! -//! All CPU metrics will be reported in nanocores (1 core = 1,000,000,000 nanocores). +//! All CPU metrics are reported in nanocores (1 core = 1,000,000,000 nanocores). use crate::azure_cpu::{CpuStats, CpuStatsReader}; +use tracing::debug; +use windows::Win32::System::JobObjects::{ + JOBOBJECT_BASIC_ACCOUNTING_INFORMATION, JobObjectBasicAccountingInformation, + QueryInformationJobObject, +}; pub struct WindowsCpuStatsReader; impl CpuStatsReader for WindowsCpuStatsReader { fn read(&self) -> Option { - None + read_cpu_usage_from_job_object() + } +} + +fn read_cpu_usage_from_job_object() -> Option { + let mut info = JOBOBJECT_BASIC_ACCOUNTING_INFORMATION::default(); + let result = unsafe { + QueryInformationJobObject( + None, // If the handle is None, the current process's job object is used + JobObjectBasicAccountingInformation, // The type of info to retrieve + &mut info as *mut _ as *mut _, // Pointer to the struct that will store the info + std::mem::size_of::() as u32, + None, + ) + }; + match result { + Ok(()) => { + // TotalUserTime and TotalKernelTime are in 100-nanosecond units - multiply by 100 to get nanoseconds + let total_ns = (info.TotalUserTime + info.TotalKernelTime) as u64 * 100; + Some(CpuStats { total: total_ns }) + } + Err(_) => { + debug!("Failed to read CPU usage from Job Object"); + None + } } } diff --git a/crates/datadog-serverless-compat/src/main.rs b/crates/datadog-serverless-compat/src/main.rs index a0fccc2..69bfb9d 100644 --- a/crates/datadog-serverless-compat/src/main.rs +++ b/crates/datadog-serverless-compat/src/main.rs @@ -120,17 +120,11 @@ pub async fn main() { .ok() .and_then(|val| parse_metric_namespace(&val)); - // Only enable enhanced metrics for Linux Azure Functions - #[cfg(not(windows))] let dd_enhanced_metrics = env_type == EnvironmentType::AzureFunction && env::var("DD_ENHANCED_METRICS_ENABLED") .map(|val| val.to_lowercase() != "false") .unwrap_or(true); - // Enhanced metrics are not yet supported in Windows environments - #[cfg(all(windows, feature = "windows-enhanced-metrics"))] - let dd_enhanced_metrics = false; - let https_proxy = env::var("DD_PROXY_HTTPS") .or_else(|_| env::var("HTTPS_PROXY")) .ok(); From 0e97d783d7fc41f004fc7f592d1037070a987063 Mon Sep 17 00:00:00 2001 From: Kathie Huang Date: Mon, 18 May 2026 15:00:09 -0400 Subject: [PATCH 2/7] Guard against overflow, add safety comment for QueryInformationJobObject, log error --- .../src/azure_linux.rs | 2 +- .../src/azure_windows.rs | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/crates/datadog-metrics-collector/src/azure_linux.rs b/crates/datadog-metrics-collector/src/azure_linux.rs index 8c435e7..ed8874e 100644 --- a/crates/datadog-metrics-collector/src/azure_linux.rs +++ b/crates/datadog-metrics-collector/src/azure_linux.rs @@ -6,7 +6,7 @@ //! This module provides functionality to read raw CPU statistics from cgroup v1 files //! and compute the CPU usage in Linux environments. //! -//! All CPU metrics are reported in nanocores (1 core = 1,000,000,000 nanocores). +//! Raw CPU time is read in nanoseconds. The CPU metric is reported in nanocores (1 core = 1,000,000,000 nanocores). use crate::azure_cpu::{CpuStats, CpuStatsReader}; use std::fs; diff --git a/crates/datadog-metrics-collector/src/azure_windows.rs b/crates/datadog-metrics-collector/src/azure_windows.rs index 800bd37..2986a1d 100644 --- a/crates/datadog-metrics-collector/src/azure_windows.rs +++ b/crates/datadog-metrics-collector/src/azure_windows.rs @@ -5,7 +5,7 @@ //! //! This module provides functionality to read CPU usage from Windows Job Objects. //! -//! All CPU metrics are reported in nanocores (1 core = 1,000,000,000 nanocores). +//! Raw CPU time is stored in nanoseconds. The CPU metric is reported in nanocores (1 core = 1,000,000,000 nanocores). use crate::azure_cpu::{CpuStats, CpuStatsReader}; use tracing::debug; @@ -24,11 +24,14 @@ impl CpuStatsReader for WindowsCpuStatsReader { fn read_cpu_usage_from_job_object() -> Option { let mut info = JOBOBJECT_BASIC_ACCOUNTING_INFORMATION::default(); + // SAFETY: `info` is a stack-allocated `JOBOBJECT_BASIC_ACCOUNTING_INFORMATION` initialized via `default()`, so the compiler guarantees its alignment. + // The buffer size argument is `size_of::()`, which exactly matches `info`, so the API cannot write out of bounds. + // Passing `None` for the job handle is documented to use the current process's job object. let result = unsafe { QueryInformationJobObject( - None, // If the handle is None, the current process's job object is used + None, JobObjectBasicAccountingInformation, // The type of info to retrieve - &mut info as *mut _ as *mut _, // Pointer to the struct that will store the info + &mut info as *mut _ as *mut _, // Pointer to the struct that will store the info std::mem::size_of::() as u32, None, ) @@ -36,11 +39,15 @@ fn read_cpu_usage_from_job_object() -> Option { match result { Ok(()) => { // TotalUserTime and TotalKernelTime are in 100-nanosecond units - multiply by 100 to get nanoseconds - let total_ns = (info.TotalUserTime + info.TotalKernelTime) as u64 * 100; + let total_user_ns = u64::try_from(info.TotalUserTime).ok()?; + let total_kernel_ns = u64::try_from(info.TotalKernelTime).ok()?; + let total_ns = total_user_ns + .checked_add(total_kernel_ns)? + .checked_mul(100)?; Some(CpuStats { total: total_ns }) } - Err(_) => { - debug!("Failed to read CPU usage from Job Object"); + Err(e) => { + debug!("Failed to read CPU usage from Job Object: {}", e); None } } From 9cb4483eed0ebd0f973cbf90f12cd17d5dd6aefc Mon Sep 17 00:00:00 2001 From: Kathie Huang Date: Mon, 18 May 2026 15:03:56 -0400 Subject: [PATCH 3/7] Update license --- LICENSE-3rdparty.csv | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 9c0a9be..a0368b7 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -304,11 +304,21 @@ web-time,https://github.com/daxpedda/web-time,MIT OR Apache-2.0,The web-time Aut webpki-roots,https://github.com/rustls/webpki-roots,CDLA-Permissive-2.0,The webpki-roots Authors which,https://github.com/harryfei/which-rs,MIT,Harry Fei windows,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows Authors +windows-collections,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-collections Authors +windows-core,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-core Authors +windows-future,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-future Authors +windows-implement,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-implement Authors +windows-interface,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-interface Authors windows-link,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-link Authors +windows-numerics,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-numerics Authors +windows-result,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-result Authors +windows-strings,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-strings Authors 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-targets,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-targets Authors +windows-threading,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-threading Authors windows_aarch64_gnullvm,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,The windows_aarch64_gnullvm Authors windows_aarch64_msvc,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft From e5cf36972a76e32ba5c8a06fd7f14abddde54d86 Mon Sep 17 00:00:00 2001 From: Kathie Huang Date: Mon, 18 May 2026 15:12:25 -0400 Subject: [PATCH 4/7] nit: whitespace --- crates/datadog-metrics-collector/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/datadog-metrics-collector/Cargo.toml b/crates/datadog-metrics-collector/Cargo.toml index aefa85d..cd77d17 100644 --- a/crates/datadog-metrics-collector/Cargo.toml +++ b/crates/datadog-metrics-collector/Cargo.toml @@ -17,4 +17,4 @@ windows = { version = "0.62", features = ["Win32_System_JobObjects"], optional = tokio = { version = "1", default-features = false, features = ["macros", "rt-multi-thread"] } [features] -windows-enhanced-metrics = ["windows"] \ No newline at end of file +windows-enhanced-metrics = ["windows"] From a75f3b5f2c8ecd87fc2ffc815c0914f416b0637a Mon Sep 17 00:00:00 2001 From: Kathie Huang Date: Tue, 19 May 2026 12:00:15 -0400 Subject: [PATCH 5/7] Add unit tests for CPU time conversion logic --- .../src/azure_windows.rs | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/crates/datadog-metrics-collector/src/azure_windows.rs b/crates/datadog-metrics-collector/src/azure_windows.rs index 2986a1d..cd1167c 100644 --- a/crates/datadog-metrics-collector/src/azure_windows.rs +++ b/crates/datadog-metrics-collector/src/azure_windows.rs @@ -39,11 +39,7 @@ fn read_cpu_usage_from_job_object() -> Option { match result { Ok(()) => { // TotalUserTime and TotalKernelTime are in 100-nanosecond units - multiply by 100 to get nanoseconds - let total_user_ns = u64::try_from(info.TotalUserTime).ok()?; - let total_kernel_ns = u64::try_from(info.TotalKernelTime).ok()?; - let total_ns = total_user_ns - .checked_add(total_kernel_ns)? - .checked_mul(100)?; + let total_ns = cpu_time_to_nanoseconds(info.TotalUserTime, info.TotalKernelTime)?; Some(CpuStats { total: total_ns }) } Err(e) => { @@ -52,3 +48,40 @@ fn read_cpu_usage_from_job_object() -> Option { } } } + +/// Convert CPU time from 100-nanosecond units to nanoseconds +fn cpu_time_to_nanoseconds(user_time: i64, kernel_time: i64) -> Option { + let total_user = u64::try_from(user_time).ok()?; + let total_kernel = u64::try_from(kernel_time).ok()?; + total_user.checked_add(total_kernel)?.checked_mul(100) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_normal_values() { + assert_eq!(cpu_time_to_nanoseconds(100, 200), Some(30_000)); + } + + #[test] + fn test_negative_user_time_returns_none() { + assert!(cpu_time_to_nanoseconds(-1, 100).is_none()); + } + + #[test] + fn test_negative_kernel_time_returns_none() { + assert!(cpu_time_to_nanoseconds(100, -1).is_none()); + } + + #[test] + fn test_overflow_user_time_returns_none() { + assert!(cpu_time_to_nanoseconds(i64::MAX, 100).is_none()); + } + + #[test] + fn test_overflow_kernel_time_returns_none() { + assert!(cpu_time_to_nanoseconds(100, i64::MAX).is_none()); + } +} From c404f846e4442d69a67f63d1e53fb0fa57c6aee6 Mon Sep 17 00:00:00 2001 From: Kathie Huang Date: Tue, 19 May 2026 15:35:00 -0400 Subject: [PATCH 6/7] Use windows-sys instead of windows --- Cargo.lock | 108 +----------------- crates/datadog-metrics-collector/Cargo.toml | 6 +- .../src/azure_windows.rs | 38 +++--- 3 files changed, 24 insertions(+), 128 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a3304ba..fdc446c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -495,7 +495,7 @@ dependencies = [ "libdd-common 4.0.0", "tokio", "tracing", - "windows 0.62.2", + "windows-sys 0.61.2", ] [[package]] @@ -3765,107 +3765,12 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" -dependencies = [ - "windows-collections", - "windows-core", - "windows-future", - "windows-numerics", -] - -[[package]] -name = "windows-collections" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" -dependencies = [ - "windows-core", -] - -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-future" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" -dependencies = [ - "windows-core", - "windows-link", - "windows-threading", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" -[[package]] -name = "windows-numerics" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" -dependencies = [ - "windows-core", - "windows-link", -] - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -3950,15 +3855,6 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] -[[package]] -name = "windows-threading" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" -dependencies = [ - "windows-link", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -4103,7 +3999,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e0e7162b9e282fd75a0a832cce93994bdb21208d848a418cd05a5fdd9b9ab33" dependencies = [ - "windows 0.48.0", + "windows", ] [[package]] diff --git a/crates/datadog-metrics-collector/Cargo.toml b/crates/datadog-metrics-collector/Cargo.toml index cd77d17..b73c828 100644 --- a/crates/datadog-metrics-collector/Cargo.toml +++ b/crates/datadog-metrics-collector/Cargo.toml @@ -11,10 +11,10 @@ tracing = { version = "0.1", default-features = false } libdd-common = { git = "https://github.com/DataDog/libdatadog", rev = "4ae8ebe252451374c292efd159ce254c3f5a72e0", default-features = false } [target.'cfg(windows)'.dependencies] -windows = { version = "0.62", features = ["Win32_System_JobObjects"], optional = true } +windows-sys = { version = "0.61", features = ["Win32_System_JobObjects"], optional = true, default-features = false } [dev-dependencies] -tokio = { version = "1", default-features = false, features = ["macros", "rt-multi-thread"] } +tokio = { version = "1", features = ["macros", "rt-multi-thread"], default-features = false } [features] -windows-enhanced-metrics = ["windows"] +windows-enhanced-metrics = ["windows-sys"] diff --git a/crates/datadog-metrics-collector/src/azure_windows.rs b/crates/datadog-metrics-collector/src/azure_windows.rs index cd1167c..62b6127 100644 --- a/crates/datadog-metrics-collector/src/azure_windows.rs +++ b/crates/datadog-metrics-collector/src/azure_windows.rs @@ -9,7 +9,7 @@ use crate::azure_cpu::{CpuStats, CpuStatsReader}; use tracing::debug; -use windows::Win32::System::JobObjects::{ +use windows_sys::Win32::System::JobObjects::{ JOBOBJECT_BASIC_ACCOUNTING_INFORMATION, JobObjectBasicAccountingInformation, QueryInformationJobObject, }; @@ -23,27 +23,32 @@ impl CpuStatsReader for WindowsCpuStatsReader { } fn read_cpu_usage_from_job_object() -> Option { - let mut info = JOBOBJECT_BASIC_ACCOUNTING_INFORMATION::default(); - // SAFETY: `info` is a stack-allocated `JOBOBJECT_BASIC_ACCOUNTING_INFORMATION` initialized via `default()`, so the compiler guarantees its alignment. + // SAFETY: `info` is a stack-allocated `JOBOBJECT_BASIC_ACCOUNTING_INFORMATION` initialized via `zeroed()`, so the compiler guarantees its alignment. // The buffer size argument is `size_of::()`, which exactly matches `info`, so the API cannot write out of bounds. - // Passing `None` for the job handle is documented to use the current process's job object. + // Passing a null handle for the job handle is documented to use the current process's job object. let result = unsafe { - QueryInformationJobObject( - None, - JobObjectBasicAccountingInformation, // The type of info to retrieve - &mut info as *mut _ as *mut _, // Pointer to the struct that will store the info + let mut info = std::mem::MaybeUninit::::zeroed(); + let success = QueryInformationJobObject( + std::ptr::null_mut(), + JobObjectBasicAccountingInformation, + info.as_mut_ptr().cast(), std::mem::size_of::() as u32, - None, - ) + std::ptr::null_mut(), + ); + if success != 0 { + Some(info.assume_init()) + } else { + None + } }; match result { - Ok(()) => { + Some(info) => { // TotalUserTime and TotalKernelTime are in 100-nanosecond units - multiply by 100 to get nanoseconds let total_ns = cpu_time_to_nanoseconds(info.TotalUserTime, info.TotalKernelTime)?; Some(CpuStats { total: total_ns }) } - Err(e) => { - debug!("Failed to read CPU usage from Job Object: {}", e); + None => { + debug!("Failed to read CPU usage from Job Object"); None } } @@ -76,12 +81,7 @@ mod tests { } #[test] - fn test_overflow_user_time_returns_none() { + fn test_mul_overflow_returns_none() { assert!(cpu_time_to_nanoseconds(i64::MAX, 100).is_none()); } - - #[test] - fn test_overflow_kernel_time_returns_none() { - assert!(cpu_time_to_nanoseconds(100, i64::MAX).is_none()); - } } From 001bc157fa27c59d56c4ae46d5c25f4f9e681c46 Mon Sep 17 00:00:00 2001 From: Kathie Huang Date: Tue, 19 May 2026 15:38:38 -0400 Subject: [PATCH 7/7] Update license --- LICENSE-3rdparty.csv | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index a0368b7..9c0a9be 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -304,21 +304,11 @@ web-time,https://github.com/daxpedda/web-time,MIT OR Apache-2.0,The web-time Aut webpki-roots,https://github.com/rustls/webpki-roots,CDLA-Permissive-2.0,The webpki-roots Authors which,https://github.com/harryfei/which-rs,MIT,Harry Fei windows,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft -windows,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows Authors -windows-collections,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-collections Authors -windows-core,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-core Authors -windows-future,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-future Authors -windows-implement,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-implement Authors -windows-interface,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-interface Authors windows-link,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-link Authors -windows-numerics,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-numerics Authors -windows-result,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-result Authors -windows-strings,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-strings Authors 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-targets,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-targets Authors -windows-threading,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-threading Authors windows_aarch64_gnullvm,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,The windows_aarch64_gnullvm Authors windows_aarch64_msvc,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft