diff options
author | Clement Tsang <34804052+ClementTsang@users.noreply.github.com> | 2021-05-15 18:57:02 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-15 21:57:02 -0400 |
commit | 6847f2ff0ce5827c0779a1dfcb9e6a8a657652b1 (patch) | |
tree | 2b957d6701f06720baf2cab836303400f340e6f2 /src/app | |
parent | 39c5ee991e8a02a72da398433c62f4a1b8c7acbb (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')
27 files changed, 795 insertions, 608 deletions
diff --git a/src/app/data_farmer.rs b/src/app/data_farmer.rs index c58e4f1b..73830842 100644 --- a/src/app/data_farmer.rs +++ b/src/app/data_farmer.rs @@ -16,9 +16,8 @@ use once_cell::sync::Lazy; use std::{time::Instant, vec::Vec}; -use crate::app::data_harvester::load_avg::LoadAvgHarvest; use crate::{ - data_harvester::{batteries, cpu, disks, load_avg, mem, network, processes, temperature, Data}, + data_harvester::{batteries, cpu, disks, memory, network, processes, temperature, Data}, utils::gen_util::{get_decimal_bytes, GIGA_LIMIT}, }; use regex::Regex; @@ -51,10 +50,10 @@ pub struct DataCollection { pub frozen_instant: Option<Instant>, pub timed_data_vec: Vec<(Instant, TimedData)>, pub network_harvest: network::NetworkHarvest, - pub memory_harvest: mem::MemHarvest, - pub swap_harvest: mem::MemHarvest, + pub memory_harvest: memory::MemHarvest, + pub swap_harvest: memory::MemHarvest, pub cpu_harvest: cpu::CpuHarvest, - pub load_avg_harvest: load_avg::LoadAvgHarvest, + pub load_avg_harvest: cpu::LoadAvgHarvest, pub process_harvest: Vec<processes::ProcessHarvest>, pub disk_harvest: Vec<disks::DiskHarvest>, pub io_harvest: disks::IoHarvest, @@ -71,10 +70,10 @@ impl Default for DataCollection { frozen_instant: None, timed_data_vec: Vec::default(), network_harvest: network::NetworkHarvest::default(), - memory_harvest: mem::MemHarvest::default(), - swap_harvest: mem::MemHarvest::default(), + memory_harvest: memory::MemHarvest::default(), + swap_harvest: memory::MemHarvest::default(), cpu_harvest: cpu::CpuHarvest::default(), - load_avg_harvest: load_avg::LoadAvgHarvest::default(), + load_avg_harvest: cpu::LoadAvgHarvest::default(), process_harvest: Vec::default(), disk_harvest: Vec::default(), io_harvest: disks::IoHarvest::default(), @@ -90,8 +89,8 @@ impl DataCollection { pub fn reset(&mut self) { self.timed_data_vec = Vec::default(); self.network_harvest = network::NetworkHarvest::default(); - self.memory_harvest = mem::MemHarvest::default(); - self.swap_harvest = mem::MemHarvest::default(); + self.memory_harvest = memory::MemHarvest::default(); + self.swap_harvest = memory::MemHarvest::default(); self.cpu_harvest = cpu::CpuHarvest::default(); self.process_harvest = Vec::default(); self.disk_harvest = Vec::default(); @@ -180,7 +179,7 @@ impl DataCollection { } fn eat_memory_and_swap( - &mut self, memory: mem::MemHarvest, swap: mem::MemHarvest, new_entry: &mut TimedData, + &mut self, memory: memory::MemHarvest, swap: memory::MemHarvest, new_entry: &mut TimedData, ) { // trace!("Eating mem and swap."); // Memory @@ -230,7 +229,7 @@ impl DataCollection { self.cpu_harvest = cpu.to_vec(); } - fn eat_load_avg(&mut self, load_avg: LoadAvgHarvest, new_entry: &mut TimedData) { + fn eat_load_avg(&mut self, load_avg: cpu::LoadAvgHarvest, new_entry: &mut TimedData) { new_entry.load_avg_data = load_avg; self.load_avg_harvest = load_avg; diff --git a/src/app/data_harvester.rs b/src/app/data_harvester.rs index 60ff5a2a..feab6005 100644 --- a/src/app/data_harvester.rs +++ b/src/app/data_harvester.rs @@ -19,8 +19,7 @@ use super::DataFilters; pub mod batteries; pub mod cpu; pub mod disks; -pub mod load_avg; -pub mod mem; +pub mod memory; pub mod network; pub mod processes; pub mod temperature; @@ -29,9 +28,9 @@ pub mod temperature; pub struct Data { pub last_collection_time: Instant, pub cpu: Option<cpu::CpuHarvest>, - pub load_avg: Option<load_avg::LoadAvgHarvest>, - pub memory: Option<mem::MemHarvest>, - pub swap: Option<mem::MemHarvest>, + pub load_avg: Option<cpu::LoadAvgHarvest>, + pub memory: Option<memory::MemHarvest>, + pub swap: Option<memory::MemHarvest>, pub temperature_sensors: Option<Vec<temperature::TempHarvest>>, pub network: Option<network::NetworkHarvest>, pub list_of_processes: Option<Vec<processes::ProcessHarvest>>, @@ -232,7 +231,7 @@ impl DataCollector { #[cfg(target_family = "unix")] { // Load Average - if let Ok(load_avg_data) = load_avg::get_load_avg().await { + if let Ok(load_avg_data) = cpu::get_load_avg().await { self.data.load_avg = Some(load_avg_data); } } @@ -299,7 +298,7 @@ impl DataCollector { ) } }; - let mem_data_fut = mem::get_mem_data(self.widgets_to_harvest.use_mem); + let mem_data_fut = memory::get_mem_data(self.widgets_to_harvest.use_mem); let disk_data_fut = disks::get_disk_usage( self.widgets_to_harvest.use_disk, &self.filters.disk_filter, 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, - |