summaryrefslogtreecommitdiffstats
path: root/src/data_collection/processes/freebsd.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/data_collection/processes/freebsd.rs')
-rw-r--r--src/data_collection/processes/freebsd.rs71
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)
+}