diff options
Diffstat (limited to 'src/data_collection/processes/freebsd.rs')
-rw-r--r-- | src/data_collection/processes/freebsd.rs | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/data_collection/processes/freebsd.rs b/src/data_collection/processes/freebsd.rs new file mode 100644 index 00000000..0da933f5 --- /dev/null +++ b/src/data_collection/processes/freebsd.rs @@ -0,0 +1,71 @@ +//! Process data collection for FreeBSD. Uses sysinfo. + +use std::io; +use std::process::Command; + +use hashbrown::HashMap; +use serde::{Deserialize, Deserializer}; + +use crate::data_collection::{deserialize_xo, processes::UnixProcessExt}; +use crate::Pid; + +#[derive(Deserialize, Debug, Default)] +#[serde(rename_all = "kebab-case")] +struct ProcessInformation { + process: Vec<ProcessRow>, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "kebab-case")] +struct ProcessRow { + #[serde(deserialize_with = "pid")] + pid: i32, + #[serde(deserialize_with = "percent_cpu")] + percent_cpu: f64, +} + +pub(crate) struct FreeBSDProcessExt; + +impl UnixProcessExt for FreeBSDProcessExt { + #[inline] + fn has_backup_proc_cpu_fn() -> bool { + true + } + + fn backup_proc_cpu(pids: &[Pid]) -> io::Result<HashMap<Pid, f64>> { + if pids.is_empty() { + return Ok(HashMap::new()); + } + + let output = Command::new("ps") + .args(["--libxo", "json", "-o", "pid,pcpu", "-p"]) + .args(pids.iter().map(i32::to_string)) + .output()?; + + deserialize_xo("process-information", &output.stdout).map( + |process_info: ProcessInformation| { + process_info + .process + .into_iter() + .map(|row| (row.pid, row.percent_cpu)) + .collect() + }, + ) + } +} + +fn pid<'de, D>(deserializer: D) -> Result<i32, D::Error> +where + D: Deserializer<'de>, +{ + let s = String::deserialize(deserializer)?; + s.parse().map_err(serde::de::Error::custom) +} + +fn percent_cpu<'de, D>(deserializer: D) -> Result<f64, D::Error> +where + D: Deserializer<'de>, +{ + let s = String::deserialize(deserializer)?; + s.parse().map_err(serde::de::Error::custom) +} |