summaryrefslogtreecommitdiffstats
path: root/src/app/data_harvester
diff options
context:
space:
mode:
authorClement Tsang <34804052+ClementTsang@users.noreply.github.com>2021-05-15 18:57:02 -0700
committerGitHub <noreply@github.com>2021-05-15 21:57:02 -0400
commit6847f2ff0ce5827c0779a1dfcb9e6a8a657652b1 (patch)
tree2b957d6701f06720baf2cab836303400f340e6f2 /src/app/data_harvester
parent39c5ee991e8a02a72da398433c62f4a1b8c7acbb (diff)
refactor: split up data collection by OS (#482)
Refactor to split up data collection by OS and/or the backing library. The goal is to make it easier to work with and add new OS support, as opposed to how it was prior where we stored OS-independent implementations all in the same file.
Diffstat (limited to 'src/app/data_harvester')
-rw-r--r--src/app/data_harvester/batteries/battery.rs (renamed from src/app/data_harvester/batteries.rs)11
-rw-r--r--src/app/data_harvester/batteries/mod.rs10
-rw-r--r--src/app/data_harvester/cpu/heim/linux.rs16
-rw-r--r--src/app/data_harvester/cpu/heim/mod.rs (renamed from src/app/data_harvester/cpu.rs)55
-rw-r--r--src/app/data_harvester/cpu/heim/unix.rs (renamed from src/app/data_harvester/load_avg.rs)5
-rw-r--r--src/app/data_harvester/cpu/heim/windows_macos.rs10
-rw-r--r--src/app/data_harvester/cpu/mod.rs14
-rw-r--r--src/app/data_harvester/disks/heim/linux.rs34
-rw-r--r--src/app/data_harvester/disks/heim/mod.rs (renamed from src/app/data_harvester/disks.rs)49
-rw-r--r--src/app/data_harvester/disks/heim/windows_macos.rs14
-rw-r--r--src/app/data_harvester/disks/mod.rs10
-rw-r--r--src/app/data_harvester/memory/heim.rs (renamed from src/app/data_harvester/mem.rs)2
-rw-r--r--src/app/data_harvester/memory/mod.rs10
-rw-r--r--src/app/data_harvester/network/heim.rs (renamed from src/app/data_harvester/network.rs)78
-rw-r--r--src/app/data_harvester/network/mod.rs30
-rw-r--r--src/app/data_harvester/network/sysinfo.rs60
-rw-r--r--src/app/data_harvester/processes/linux.rs (renamed from src/app/data_harvester/processes.rs)294
-rw-r--r--src/app/data_harvester/processes/macos.rs139
-rw-r--r--src/app/data_harvester/processes/mod.rs97
-rw-r--r--src/app/data_harvester/processes/unix.rs30
-rw-r--r--src/app/data_harvester/processes/windows.rs72
-rw-r--r--src/app/data_harvester/temperature.rs153
-rw-r--r--src/app/data_harvester/temperature/heim.rs54
-rw-r--r--src/app/data_harvester/temperature/mod.rs73
-rw-r--r--src/app/data_harvester/temperature/sysinfo.rs47
25 files changed, 778 insertions, 589 deletions
diff --git a/src/app/data_harvester/batteries.rs b/src/app/data_harvester/batteries/battery.rs
index 98cf6ae6..7e4644e9 100644
--- a/src/app/data_harvester/batteries.rs
+++ b/src/app/data_harvester/batteries/battery.rs
@@ -1,3 +1,14 @@
+//! Uses the battery crate from svartalf.
+//! Covers battery usage for:
+//! - Linux 2.6.39+
+//! - MacOS 10.10+
+//! - iOS
+//! - Windows 7+
+//! - FreeBSD
+//! - DragonFlyBSD
+//!
+//! For more information, see https://github.com/svartalf/rust-battery
+
use battery::{
units::{power::watt, ratio::percent, time::second},
Battery, Manager,
diff --git a/src/app/data_harvester/batteries/mod.rs b/src/app/data_harvester/batteries/mod.rs
new file mode 100644
index 00000000..8c0e4a92
--- /dev/null
+++ b/src/app/data_harvester/batteries/mod.rs
@@ -0,0 +1,10 @@
+//! Data collection for batteries.
+//!
+//! For Linux, macOS, Windows, FreeBSD, Dragonfly, and iOS, this is handled by the battery crate.
+
+cfg_if::cfg_if! {
+ if #[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "ios"))] {
+ pub mod battery;
+ pub use self::battery::*;
+ }
+}
diff --git a/src/app/data_harvester/cpu/heim/linux.rs b/src/app/data_harvester/cpu/heim/linux.rs
new file mode 100644
index 00000000..542685d4
--- /dev/null
+++ b/src/app/data_harvester/cpu/heim/linux.rs
@@ -0,0 +1,16 @@
+//! Linux-specific functions regarding CPU usage.
+
+use heim::cpu::os::linux::CpuTimeExt;
+pub fn convert_cpu_times(cpu_time: &heim::cpu::CpuTime) -> (f64, f64) {
+ let working_time: f64 = (cpu_time.user()
+ + cpu_time.nice()
+ + cpu_time.system()
+ + cpu_time.irq()
+ + cpu_time.soft_irq()
+ + cpu_time.steal())
+ .get::<heim::units::time::second>();
+ (
+ working_time,
+ working_time + (cpu_time.idle() + cpu_time.io_wait()).get::<heim::units::time::second>(),
+ )
+}
diff --git a/src/app/data_harvester/cpu.rs b/src/app/data_harvester/cpu/heim/mod.rs
index 61e79e28..73a97b5b 100644
--- a/src/app/data_harvester/cpu.rs
+++ b/src/app/data_harvester/cpu/heim/mod.rs
@@ -1,3 +1,23 @@
+//! CPU stats through heim.
+//! Supports macOS, Linux, and Windows.
+
+cfg_if::cfg_if! {
+ if #[cfg(target_os = "linux")] {
+ pub mod linux;
+ pub use linux::*;
+ } else if #[cfg(any(target_os = "macos", target_os = "windows"))] {
+ pub mod windows_macos;
+ pub use windows_macos::*;
+ }
+}
+
+cfg_if::cfg_if! {
+ if #[cfg(target_family = "unix")] {
+ pub mod unix;
+ pub use unix::*;
+ }
+}
+
#[derive(Default, Debug, Clone)]
pub struct CpuData {
pub cpu_prefix: String,
@@ -10,42 +30,13 @@ pub type CpuHarvest = Vec<CpuData>;
pub type PastCpuWork = f64;
pub type PastCpuTotal = f64;
+use futures::StreamExt;
+use std::collections::VecDeque;
+
pub async fn get_cpu_data_list(
show_average_cpu: bool, previous_cpu_times: &mut Vec<(PastCpuWork, PastCpuTotal)>,
previous_average_cpu_time: &mut Option<(PastCpuWork, PastCpuTotal)>,
) -> crate::error::Result<CpuHarvest> {
- use futures::StreamExt;
- #[cfg(target_os = "linux")]
- use heim::cpu::os::linux::CpuTimeExt;
- use std::collections::VecDeque;
-
- fn convert_cpu_times(cpu_time: &heim::cpu::CpuTime) -> (f64, f64) {
- #[cfg(not(target_os = "linux"))]
- {
- let working_time: f64 =
- (cpu_time.user() + cpu_time.system()).get::<heim::units::time::second>();
- (
- working_time,
- working_time + cpu_time.idle().get::<heim::units::time::second>(),
- )
- }
- #[cfg(target_os = "linux")]
- {
- let working_time: f64 = (cpu_time.user()
- + cpu_time.nice()
- + cpu_time.system()
- + cpu_time.irq()
- + cpu_time.soft_irq()
- + cpu_time.steal())
- .get::<heim::units::time::second>();
- (
- working_time,
- working_time
- + (cpu_time.idle() + cpu_time.io_wait()).get::<heim::units::time::second>(),
- )
- }
- }
-
fn calculate_cpu_usage_percentage(
(previous_working_time, previous_total_time): (f64, f64),
(current_working_time, current_total_time): (f64, f64),
diff --git a/src/app/data_harvester/load_avg.rs b/src/app/data_harvester/cpu/heim/unix.rs
index 0f58ea8b..74340951 100644
--- a/src/app/data_harvester/load_avg.rs
+++ b/src/app/data_harvester/cpu/heim/unix.rs
@@ -1,6 +1,7 @@
-pub type LoadAvgHarvest = [f32; 3];
+//! Unix-specific functions regarding CPU usage.
+
+use crate::app::data_harvester::cpu::LoadAvgHarvest;
-#[cfg(target_family = "unix")]
pub async fn get_load_avg() -> crate::error::Result<LoadAvgHarvest> {
let (one, five, fifteen) = heim::cpu::os::unix::loadavg().await?;
diff --git a/src/app/data_harvester/cpu/heim/windows_macos.rs b/src/app/data_harvester/cpu/heim/windows_macos.rs
new file mode 100644
index 00000000..34abc818
--- /dev/null
+++ b/src/app/data_harvester/cpu/heim/windows_macos.rs
@@ -0,0 +1,10 @@
+//! Windows and macOS-specific functions regarding CPU usage.
+
+pub fn convert_cpu_times(cpu_time: &heim::cpu::CpuTime) -> (f64, f64) {
+ let working_time: f64 =
+ (cpu_time.user() + cpu_time.system()).get::<heim::units::time::second>();
+ (
+ working_time,
+ working_time + cpu_time.idle().get::<heim::units::time::second>(),
+ )
+}
diff --git a/src/app/data_harvester/cpu/mod.rs b/src/app/data_harvester/cpu/mod.rs
new file mode 100644
index 00000000..81a0db4c
--- /dev/null
+++ b/src/app/data_harvester/cpu/mod.rs
@@ -0,0 +1,14 @@
+//! Data collection for CPU usage and load average.
+//!
+//! For CPU usage, Linux, macOS, and Windows are handled by Heim.
+//!
+//! For load average, macOS and Linux are supported through Heim.
+
+cfg_if::cfg_if! {
+ if #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] {
+ pub mod heim;
+ pub use self::heim::*;
+ }
+}
+
+pub type LoadAvgHarvest = [f32; 3];
diff --git a/src/app/data_harvester/disks/heim/linux.rs b/src/app/data_harvester/disks/heim/linux.rs
new file mode 100644
index 00000000..cbc99d9f
--- /dev/null
+++ b/src/app/data_harvester/disks/heim/linux.rs
@@ -0,0 +1,34 @@
+//! Linux-specific things for Heim disk data collection.
+
+use heim::disk::Partition;
+
+pub fn get_device_name(partition: &Partition) -> String {
+ if let Some(device) = partition.device() {
+ // See if this disk is actually mounted elsewhere on Linux...
+ // This is a workaround to properly map I/O in some cases (i.e. disk encryption), see
+ // https://github.com/ClementTsang/bottom/issues/419
+ if let Ok(path) = std::fs::read_link(device) {
+ if path.is_absolute() {
+ path.into_os_string()
+ } else {
+ let mut combined_path = std::path::PathBuf::new();
+ combined_path.push(device);
+ combined_path.pop(); // Pop the current file...
+ combined_path.push(path);
+
+ if let Ok(canon_path) = std::fs::canonicalize(combined_path) {
+ // Resolve the local path into an absolute one...
+ canon_path.into_os_string()
+ } else {
+ device.to_os_string()
+ }
+ }
+ } else {
+ device.to_os_string()
+ }
+ .into_string()
+ .unwrap_or_else(|_| "Name Unavailable".to_string())
+ } else {
+ "Name Unavailable".to_string()
+ }
+}
diff --git a/src/app/data_harvester/disks.rs b/src/app/data_harvester/disks/heim/mod.rs
index 103bb701..a79d00db 100644
--- a/src/app/data_harvester/disks.rs
+++ b/src/app/data_harvester/disks/heim/mod.rs
@@ -1,5 +1,15 @@
use crate::app::Filter;
+cfg_if::cfg_if! {
+ if #[cfg(target_os = "linux")] {
+ pub mod linux;
+ pub use linux::*;
+ } else if #[cfg(any(target_os = "macos", target_os = "windows"))] {
+ pub mod windows_macos;
+ pub use windows_macos::*;
+ }
+}
+
#[derive(Debug, Clone, Default)]
pub struct DiskHarvest {
pub name: String,
@@ -62,44 +72,7 @@ pub async fn get_disk_usage(
while let Some(part) = partitions_stream.next().await {
if let Ok(partition) = part {
- let symlink: std::ffi::OsString;
-
- let name = (if let Some(device) = partition.device() {
- // See if this disk is actually mounted elsewhere on Linux...
- // This is a workaround to properly map I/O in some cases (i.e. disk encryption), see
- // https://github.com/ClementTsang/bottom/issues/419
- if cfg!(target_os = "linux") {
- if let Ok(path) = std::fs::read_link(device) {
- if path.is_absolute() {
- symlink = path.into_os_string();
- symlink.as_os_str()
- } else {
- let mut combined_path = std::path::PathBuf::new();
- combined_path.push(device);
- combined_path.pop(); // Pop the current file...
- combined_path.push(path.clone());
-
- if let Ok(path) = std::fs::canonicalize(combined_path) {
- // Resolve the local path into an absolute one...
- symlink = path.into_os_string();
- symlink.as_os_str()
- } else {
- symlink = path.into_os_string();
- symlink.as_os_str()
- }
- }
- } else {
- device
- }
- } else {
- device
- }
- } else {
- std::ffi::OsStr::new("Name Unavailable")
- }
- .to_str()
- .unwrap_or("Name Unavailable"))
- .to_string();
+ let name = get_device_name(&partition);
let mount_point = (partition
.mount_point()
diff --git a/src/app/data_harvester/disks/heim/windows_macos.rs b/src/app/data_harvester/disks/heim/windows_macos.rs
new file mode 100644
index 00000000..428733bf
--- /dev/null
+++ b/src/app/data_harvester/disks/heim/windows_macos.rs
@@ -0,0 +1,14 @@
+//! macOS and Windows-specific things for Heim disk data collection.
+
+use heim::disk::Partition;
+
+pub fn get_device_name(partition: &Partition) -> String {
+ if let Some(device) = partition.device() {
+ device
+ .to_os_string()
+ .into_string()
+ .unwrap_or_else(|_| "Name Unavailable".to_string())
+ } else {
+ "Name Unavailable".to_string()
+ }
+}
diff --git a/src/app/data_harvester/disks/mod.rs b/src/app/data_harvester/disks/mod.rs
new file mode 100644
index 00000000..e5a52336
--- /dev/null
+++ b/src/app/data_harvester/disks/mod.rs
@@ -0,0 +1,10 @@
+//! Data collection for disks (IO, usage, space, etc.).
+//!
+//! For Linux, macOS, and Windows, this is handled by heim.
+
+cfg_if::cfg_if! {
+ if #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] {
+ pub mod heim;
+ pub use self::heim::*;
+ }
+}
diff --git a/src/app/data_harvester/mem.rs b/src/app/data_harvester/memory/heim.rs
index 014cbcdc..5319b1b3 100644
--- a/src/app/data_harvester/mem.rs
+++ b/src/app/data_harvester/memory/heim.rs
@@ -1,3 +1,5 @@
+//! Data collection for memory via heim.
+
#[derive(Debug, Clone)]
pub struct MemHarvest {
pub mem_total_in_kib: u64,
diff --git a/src/app/data_harvester/memory/mod.rs b/src/app/data_harvester/memory/mod.rs
new file mode 100644
index 00000000..588a3c3b
--- /dev/null
+++ b/src/app/data_harvester/memory/mod.rs
@@ -0,0 +1,10 @@
+//! Data collection for memory.
+//!
+//! For Linux, macOS, and Windows, this is handled by Heim.
+
+cfg_if::cfg_if! {
+ if #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] {
+ pub mod heim;
+ pub use self::heim::*;
+ }
+}
diff --git a/src/app/data_harvester/network.rs b/src/app/data_harvester/network/heim.rs
index 650a68e3..d18287c8 100644
--- a/src/app/data_harvester/network.rs
+++ b/src/app/data_harvester/network/heim.rs
@@ -1,81 +1,9 @@
-use std::time::Instant;
-
-#[derive(Default, Clone, Debug)]
-/// All units in bits.
-pub struct NetworkHarvest {
- pub rx: u64,
- pub tx: u64,
- pub total_rx: u64,
- pub total_tx: u64,
-}
-
-impl NetworkHarvest {
- pub fn first_run_cleanup(&mut self) {
- self.rx = 0;
- self.tx = 0;
- }
-}
-
-/// Separate Windows implementation required due to https://github.com/heim-rs/heim/issues/26.
-#[cfg(target_os = "windows")]
-pub async fn get_network_data(
- sys: &sysinfo::System, prev_net_access_time: Instant, prev_net_rx: &mut u64,
- prev_net_tx: &mut u64, curr_time: Instant, actually_get: bool,
- filter: &Option<crate::app::Filter>,
-) -> crate::utils::error::Result<Option<NetworkHarvest>> {
- use sysinfo::{NetworkExt, SystemExt};
-
- if !actually_get {
- return Ok(None);
- }
-
- let mut total_rx: u64 = 0;
- let mut total_tx: u64 = 0;
-
- let networks = sys.get_networks();
- for (name, network) in networks {
- let to_keep = if let Some(filter) = filter {
- let mut ret = filter.is_list_ignored;
- for r in &filter.list {
- if r.is_match(&name) {
- ret = !filter.is_list_ignored;
- break;
- }
- }
- ret
- } else {
- true
- };
-
- if to_keep {
- total_rx += network.get_total_received() * 8;
- total_tx += network.get_total_transmitted() * 8;
- }
- }
+//! Gets network data via heim.
- let elapsed_time = curr_time.duration_since(prev_net_access_time).as_secs_f64();
-
- let (rx, tx) = if elapsed_time == 0.0 {
- (0, 0)
- } else {
- (
- ((total_rx.saturating_sub(*prev_net_rx)) as f64 / elapsed_time) as u64,
- ((total_tx.saturating_sub(*prev_net_tx)) as f64 / elapsed_time) as u64,
- )
- };
-
- *prev_net_rx = total_rx;
- *prev_net_tx = total_tx;
- Ok(Some(NetworkHarvest {
- rx,
- tx,
- total_rx,
- total_tx,
- }))
-}
+use super::NetworkHarvest;
+use std::time::Instant;
// FIXME: Eventually make it so that this thing also takes individual usage into account, so we can allow for showing per-interface!
-#[cfg(not(target_os = "windows"))]
pub async fn get_network_data(
prev_net_access_time: Instant, prev_net_rx: &mut u64, prev_net_tx: &mut u64,
curr_time: Instant, actually_get: bool, filter: &Option<crate::app::Filter>,
diff --git a/src/app/data_harvester/network/mod.rs b/src/app/data_harvester/network/mod.rs
new file mode 100644
index 00000000..c717e6ac
--- /dev/null
+++ b/src/app/data_harvester/network/mod.rs
@@ -0,0 +1,30 @@
+//! Data collection for network usage/IO.
+//!
+//! For Linux and macOS, this is handled by Heim.
+//! For Windows, this is handled by sysinfo.
+
+cfg_if::cfg_if! {
+ if #[cfg(any(target_os = "linux", target_os = "macos"))] {
+ pub mod heim;
+ pub use self::heim::*;
+ } else if #[cfg(target_os = "windows")] {
+ pub mod sysinfo;
+ pub use self::sysinfo::*;
+ }
+}
+
+#[derive(Default, Clone, Debug)]
+/// All units in bits.
+pub struct NetworkHarvest {
+ pub rx: u64,
+ pub tx: u64,
+ pub total_rx: u64,
+ pub total_tx: u64,
+}
+
+impl NetworkHarvest {
+ pub fn first_run_cleanup(&mut self) {
+ self.rx = 0;
+ self.tx = 0;
+ }
+}
diff --git a/src/app/data_harvester/network/sysinfo.rs b/src/app/data_harvester/network/sysinfo.rs
new file mode 100644
index 00000000..c7a7db00
--- /dev/null
+++ b/src/app/data_harvester/network/sysinfo.rs
@@ -0,0 +1,60 @@
+//! Gets network data via sysinfo.
+
+use super::NetworkHarvest;
+use std::time::Instant;
+
+pub async fn get_network_data(
+ sys: &sysinfo::System, prev_net_access_time: Instant, prev_net_rx: &mut u64,
+ prev_net_tx: &mut u64, curr_time: Instant, actually_get: bool,
+ filter: &Option<crate::app::Filter>,
+) -> crate::utils::error::Result<Option<NetworkHarvest>> {
+ use sysinfo::{NetworkExt, SystemExt};
+
+ if !actually_get {
+ return Ok(None);
+ }
+
+ let mut total_rx: u64 = 0;
+ let mut total_tx: u64 = 0;
+
+ let networks = sys.get_networks();
+ for (name, network) in networks {
+ let to_keep = if let Some(filter) = filter {
+ let mut ret = filter.is_list_ignored;
+ for r in &filter.list {
+ if r.is_match(&name) {
+ ret = !filter.is_list_ignored;
+ break;
+ }
+ }
+ ret
+ } else {
+ true
+ };
+
+ if to_keep {
+ total_rx += network.get_total_received() * 8;
+ total_tx += network.get_total_transmitted() * 8;
+ }
+ }
+
+ let elapsed_time = curr_time.duration_since(prev_net_access_time).as_secs_f64();
+
+ let (rx, tx) = if elapsed_time == 0.0 {
+ (0, 0)
+ } else {
+ (
+ ((total_rx.saturating_sub(*prev_net_rx)) as f64 / elapsed_time) as u64,
+ ((total_tx.saturating_sub(*prev_net_tx)) as f64 / elapsed_time) as u64,
+ )
+ };
+
+ *prev_net_rx = total_rx;
+ *prev_net_tx = total_tx;
+ Ok(Some(NetworkHarvest {
+ rx,
+ tx,
+ total_rx,
+ total_tx,
+ }))
+}
diff --git a/src/app/data_harvester/processes.rs b/src/app/data_harvester/processes/linux.rs
index 94f6fb62..d6778ba3 100644
--- a/src/app/data_harvester/processes.rs
+++ b/src/app/data_harvester/processes/linux.rs
@@ -1,99 +1,20 @@
+//! Process data collection for Linux.
+
+use crate::utils::error::{self, BottomError};
use crate::Pid;
-use sysinfo::ProcessStatus;
+use super::ProcessHarvest;
-#[cfg(target_family = "unix")]
-use crate::utils::error;
+use sysinfo::ProcessStatus;
-#[cfg(target_os = "linux")]
use procfs::process::{Process, Stat};
-#[cfg(target_os = "linux")]
-use crate::utils::error::BottomError;
-
-#[cfg(target_os = "linux")]
use fxhash::{FxHashMap, FxHashSet};
-#[cfg(not(target_os = "linux"))]
-use sysinfo::{ProcessExt, ProcessorExt, System, SystemExt};
-
/// Maximum character length of a /proc/<PID>/stat process name.
/// If it's equal or greater, then we instead refer to the command for the name.
-#[cfg(target_os = "linux")]
const MAX_STAT_NAME_LEN: usize = 15;
-// TODO: Add value so we know if it's sorted ascending or descending by default?
-#[derive(Clone, PartialEq, Eq, Hash, Debug)]
-pub enum ProcessSorting {
- CpuPercent,
- Mem,
- MemPercent,
- Pid,
- ProcessName,
- Command,
- ReadPerSecond,
- WritePerSecond,
- TotalRead,
- TotalWrite,
- State,
- User,
- Count,
-}
-
-impl std::fmt::Display for ProcessSorting {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(
- f,
- "{}",
- match &self {
- ProcessSorting::CpuPercent => "CPU%",
- ProcessSorting::MemPercent => "Mem%",
- ProcessSorting::Mem => "Mem",
- ProcessSorting::ReadPerSecond => "R/s",
- ProcessSorting::WritePerSecond => "W/s",
- ProcessSorting::TotalRead => "T.Read",
- ProcessSorting::TotalWrite => "T.Write",
- ProcessSorting::State => "State",
- ProcessSorting::ProcessName => "Name",
- ProcessSorting::Command => "Command",
- ProcessSorting::Pid => "PID",
- ProcessSorting::Count => "Count",
- ProcessSorting::User => "User",
- }
- )
- }
-}
-
-impl Default for ProcessSorting {
- fn default() -> Self {
- ProcessSorting::CpuPercent
- }
-}
-
-#[derive(Debug, Clone, Default)]
-pub struct ProcessHarvest {
- pub pid: Pid,
- pub parent_pid: Option<Pid>, // Remember, parent_pid 0 is root...
- pub cpu_usage_percent: f64,
- pub mem_usage_percent: f64,
- pub mem_usage_bytes: u64,
- // pub rss_kb: u64,
- // pub virt_kb: u64,
- pub name: String,
- pub command: String,
- pub read_bytes_per_sec: u64,
- pub write_bytes_per_sec: u64,
- pub total_read_bytes: u64,
- pub total_write_bytes: u64,
- pub process_state: String,
- pub process_state_char: char,
-
- /// This is the *effective* user ID.
- #[cfg(target_family = "unix")]
- pub uid: Option<libc::uid_t>,
-}
-
-#[cfg(target_os = "linux")]
#[derive(Debug, Clone)]
pub struct PrevProcDetails {
pub total_read_bytes: u64,
@@ -102,7 +23,6 @@ pub struct PrevProcDetails {
pub process: Process,
}
-#[cfg(target_os = "linux")]
impl PrevProcDetails {
fn new(pid: Pid) -> error::Result<Self> {
Ok(Self {
@@ -114,36 +34,6 @@ impl PrevProcDetails {
}
}
-#[cfg(target_family = "unix")]
-#[derive(Debug, Default)]
-pub struct UserTable {
- pub uid_user_mapping: std::collections::HashMap<libc::uid_t, String>,
-}
-
-#[cfg(target_family = "unix")]
-impl UserTable {
- pub fn get_uid_to_username_mapping(&mut self, uid: libc::uid_t) -> error::Result<String> {
- if let Some(user) = self.uid_user_mapping.get(&uid) {
- Ok(user.clone())
- } else {
- // SAFETY: getpwuid returns a null pointer if no passwd entry is found for the uid
- let passwd = unsafe { libc::getpwuid(uid) };
-
- if passwd.is_null() {
- return Err(error::BottomError::QueryError("Missing passwd".into()));
- }
-
- let username = unsafe { std::ffi::CStr::from_ptr((*passwd).pw_name) }
- .to_str()?
- .to_string();
- self.uid_user_mapping.insert(uid, username.clone());
-
- Ok(username)
- }
- }
-}
-
-#[cfg(target_os = "linux")]
fn cpu_usage_calculation(
prev_idle: &mut f64, prev_non_idle: &mut f64,
) -> error::Result<(f64, f64)> {
@@ -204,7 +94,6 @@ fn cpu_usage_calculation(
}
/// Returns the usage and a new set of process times. Note: cpu_fraction should be represented WITHOUT the x100 factor!
-#[cfg(target_os = "linux")]
fn get_linux_cpu_usage(
stat: &Stat, cpu_usage: f64, cpu_fraction: f64, prev_proc_times: u64,
use_current_cpu_total: bool,
@@ -222,40 +111,7 @@ fn get_linux_cpu_usage(
}
}
-#[cfg(target_os = "macos")]
-fn get_macos_process_cpu_usage(
- pids: &[i32],
-) -> std::io::Result<std::collections::HashMap<i32, f64>> {
- use itertools::Itertools;
- let output = std::process::Command::new("ps")
- .args(&["-o", "pid=,pcpu=", "-p"])
- .arg(
- // Has to look like this since otherwise, it you hit a `unstable_name_collisions` warning.
- Itertools::intersperse(pids.iter().map(i32::to_string), ",".to_string())
- .collect::<String>(),
- )
- .output()?;
- let mut result = std::collections::HashMap::new();
- String::from_utf8_lossy(&output.stdout)
- .split_whitespace()
- .chunks(2)
- .into_iter()
- .for_each(|chunk| {
- let chunk: Vec<&str> = chunk.collect();
- if chunk.len() != 2 {
- panic!("Unexpected `ps` output");
- }
- let pid = chunk[0].parse();
- let usage = chunk[1].parse();
- if let (Ok(pid), Ok(usage)) = (pid, usage) {
- result.insert(pid, usage);
- }
- });
- Ok(result)
-}
-
#[allow(clippy::too_many_arguments)]
-#[cfg(target_os = "linux")]
fn read_proc(
prev_proc: &PrevProcDetails, stat: &Stat, cpu_usage: f64, cpu_fraction: f64,
use_current_cpu_total: bool, time_difference_in_secs: u64, mem_total_kb: u64,
@@ -361,7 +217,6 @@ fn read_proc(
))
}
-#[cfg(target_os = "linux")]
pub fn get_process_data(
prev_idle: &mut f64, prev_non_idle: &mut f64,
pid_mapping: &mut FxHashMap<Pid, PrevProcDetails>, use_current_cpu_total: bool,
@@ -437,142 +292,3 @@ pub fn get_process_data(
))
}
}
-
-#[cfg(not(target_os = "linux"))]
-pub fn get_process_data(
- sys: &System, use_current_cpu_total: bool, mem_total_kb: u64,
-) -> crate::utils::error::Result<Vec<ProcessHarvest>> {
- let mut process_vector: Vec<ProcessHarvest> = Vec::new();
- let process_hashmap = sys.get_processes();
- let cpu_usage = sys.get_global_processor_info().get_cpu_usage() as f64 / 100.0;
- let num_cpus = sys.get_processors().len() as f64;
- for process_val in process_hashmap.values() {
- let name = if process_val.name().is_empty() {
- let process_cmd = process_val.cmd();
- if process_cmd.len() > 1 {
- process_cmd[0].clone()
- } else {
- let process_exe = process_val.exe().file_stem();
- if let Some(exe) = process_exe {
- let process_exe_opt = exe.to_str();
- if let Some(exe_name) = process_exe_opt {
- exe_name.to_string()
- } else {
- "".to_string()
- }
- } else {
- "".to_string()
- }
- }
- } else {
- process_val.name().to_string()
- };
- let command = {
- let command = process_val.cmd().join(" ");
- if command.is_empty() {
- name.to_string()
- } else {
- command
- }
- };
-
- let pcu = if cfg!(target_os = "windows") || num_cpus == 0.0 {