From f07994ef6837376a264467da114bfc9918810eb3 Mon Sep 17 00:00:00 2001 From: Clement Tsang <34804052+ClementTsang@users.noreply.github.com> Date: Mon, 15 Jan 2024 20:43:14 -0500 Subject: [PATCH] deps: bump sysinfo to =0.30.5 (#1390) * deps: bump sysinfo to =0.30.5 * fix an import * fix stuff for linux * fix temps * some fmt * disks * oops * fix some bugs --- Cargo.lock | 6 +- Cargo.toml | 2 +- src/data_collection.rs | 106 ++++++++++-------- src/data_collection/cpu/sysinfo.rs | 6 +- src/data_collection/disks/other.rs | 4 +- src/data_collection/disks/windows.rs | 3 +- src/data_collection/memory/sysinfo.rs | 4 +- src/data_collection/network/sysinfo.rs | 7 +- src/data_collection/processes/linux.rs | 3 +- src/data_collection/processes/macos.rs | 1 - src/data_collection/processes/unix.rs | 2 +- .../processes/unix/process_ext.rs | 19 ++-- src/data_collection/processes/windows.rs | 25 ++--- src/data_collection/temperature/sysinfo.rs | 7 +- 14 files changed, 97 insertions(+), 98 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index efeedde5..cdd58724 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1366,9 +1366,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.29.11" +version = "0.30.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666" +checksum = "1fb4f3438c8f6389c864e61221cbc97e9bca98b4daf39a5beb7bea660f528bb2" dependencies = [ "cfg-if", "core-foundation-sys", @@ -1376,7 +1376,7 @@ dependencies = [ "ntapi", "once_cell", "rayon", - "winapi", + "windows", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 48e71506..af2cfd2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,7 +94,7 @@ nvml-wrapper = { version = "0.9.0", optional = true, features = [ regex = "1.10.2" serde = { version = "=1.0.195", features = ["derive"] } starship-battery = { version = "0.8.2", optional = true } -sysinfo = "=0.29.11" +sysinfo = "=0.30.5" thiserror = "1.0.56" time = { version = "0.3.30", features = ["formatting", "macros"] } toml_edit = { version = "0.21.0", features = ["serde"] } diff --git a/src/data_collection.rs b/src/data_collection.rs index d00d88e0..7320a4f0 100644 --- a/src/data_collection.rs +++ b/src/data_collection.rs @@ -19,7 +19,6 @@ use std::time::{Duration, Instant}; use hashbrown::HashMap; #[cfg(feature = "battery")] use starship_battery::{Battery, Manager}; -use sysinfo::{System, SystemExt}; use self::temperature::TemperatureType; use super::DataFilters; @@ -97,10 +96,46 @@ impl Data { } } +/// A wrapper around the sysinfo data source. We use sysinfo for the following data: +/// - CPU usage +/// - Memory usage +/// - Network usage +/// - Processes (non-Linux) +/// - Disk (anything outside of Linux, macOS, and FreeBSD) +/// - Temperatures (non-Linux) +#[derive(Debug)] +pub struct SysinfoSource { + /// Handles CPU, memory, and processes. + pub(crate) system: sysinfo::System, + pub(crate) network: sysinfo::Networks, + #[cfg(not(target_os = "linux"))] + pub(crate) temps: sysinfo::Components, + #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "freebsd")))] + pub(crate) disks: sysinfo::Disks, + #[cfg(target_os = "windows")] + pub(crate) users: sysinfo::Users, +} + +impl Default for SysinfoSource { + fn default() -> Self { + use sysinfo::*; + Self { + system: System::new_with_specifics(RefreshKind::new()), + network: Networks::new(), + #[cfg(not(target_os = "linux"))] + temps: Components::new(), + #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "freebsd")))] + disks: Disks::new(), + #[cfg(target_os = "windows")] + users: Users::new(), + } + } +} + #[derive(Debug)] pub struct DataCollector { pub data: Data, - sys: System, + sys: SysinfoSource, temperature_type: TemperatureType, use_current_cpu_total: bool, unnormalized_cpu: bool, @@ -136,7 +171,7 @@ impl DataCollector { pub fn new(filters: DataFilters) -> Self { DataCollector { data: Data::default(), - sys: System::new_with_specifics(sysinfo::RefreshKind::new()), + sys: SysinfoSource::default(), #[cfg(target_os = "linux")] pid_mapping: HashMap::default(), #[cfg(target_os = "linux")] @@ -146,7 +181,7 @@ impl DataCollector { temperature_type: TemperatureType::Celsius, use_current_cpu_total: false, unnormalized_cpu: false, - last_collection_time: Instant::now(), + last_collection_time: Instant::now() - Duration::from_secs(600), // Initialize it to the past to force it to load on initialization. total_rx: 0, total_tx: 0, show_average_cpu: false, @@ -181,26 +216,6 @@ impl DataCollector { } } - // Sysinfo-related list refreshing. - if self.widgets_to_harvest.use_net { - self.sys.refresh_networks_list(); - } - - if self.widgets_to_harvest.use_temp { - self.sys.refresh_components_list(); - } - - #[cfg(target_os = "windows")] - { - if self.widgets_to_harvest.use_proc { - self.sys.refresh_users_list(); - } - - if self.widgets_to_harvest.use_disk { - self.sys.refresh_disks_list(); - } - } - self.update_data(); // Sleep a few seconds to avoid potentially weird data. @@ -238,23 +253,23 @@ impl DataCollector { /// - Disk (Windows) /// - Temperatures (non-Linux) fn refresh_sysinfo_data(&mut self) { - // Refresh once every minute. If it's too frequent it can cause segfaults. + // Refresh the list of objects once every minute. If it's too frequent it can cause segfaults. const LIST_REFRESH_TIME: Duration = Duration::from_secs(60); let refresh_start = Instant::now(); if self.widgets_to_harvest.use_cpu || self.widgets_to_harvest.use_proc { - self.sys.refresh_cpu(); + self.sys.system.refresh_cpu(); } if self.widgets_to_harvest.use_mem || self.widgets_to_harvest.use_proc { - self.sys.refresh_memory(); + self.sys.system.refresh_memory(); } if self.widgets_to_harvest.use_net { if refresh_start.duration_since(self.last_collection_time) > LIST_REFRESH_TIME { - self.sys.refresh_networks_list(); + self.sys.network.refresh_list(); } - self.sys.refresh_networks(); + self.sys.network.refresh(); } // sysinfo is used on non-Linux systems for the following: @@ -264,29 +279,29 @@ impl DataCollector { #[cfg(not(target_os = "linux"))] { if self.widgets_to_harvest.use_proc { + self.sys.system.refresh_processes(); + // For Windows, sysinfo also handles the users list. #[cfg(target_os = "windows")] if refresh_start.duration_since(self.last_collection_time) > LIST_REFRESH_TIME { - self.sys.refresh_users_list(); + self.sys.users.refresh_list(); } - - self.sys.refresh_processes(); } if self.widgets_to_harvest.use_temp { if refresh_start.duration_since(self.last_collection_time) > LIST_REFRESH_TIME { - self.sys.refresh_components_list(); + self.sys.temps.refresh_list(); } - self.sys.refresh_components(); + self.sys.temps.refresh(); } } #[cfg(target_os = "windows")] if self.widgets_to_harvest.use_disk { if refresh_start.duration_since(self.last_collection_time) > LIST_REFRESH_TIME { - self.sys.refresh_disks_list(); + self.sys.disks.refresh_list(); } - self.sys.refresh_disks(); + self.sys.disks.refresh(); } } @@ -298,10 +313,13 @@ impl DataCollector { self.update_cpu_usage(); self.update_memory_usage(); self.update_temps(); + #[cfg(feature = "battery")] self.update_batteries(); + #[cfg(feature = "gpu")] self.update_gpus(); // update_gpus before procs for gpu_pids but after temps for appending + self.update_processes(); self.update_network_usage(); self.update_disks(); @@ -341,7 +359,7 @@ impl DataCollector { #[inline] fn update_cpu_usage(&mut self) { if self.widgets_to_harvest.use_cpu { - self.data.cpu = cpu::get_cpu_data_list(&self.sys, self.show_average_cpu).ok(); + self.data.cpu = cpu::get_cpu_data_list(&self.sys.system, self.show_average_cpu).ok(); #[cfg(target_family = "unix")] { @@ -368,7 +386,7 @@ impl DataCollector { if self.widgets_to_harvest.use_temp { #[cfg(not(target_os = "linux"))] if let Ok(data) = temperature::get_temperature_data( - &self.sys, + &self.sys.temps, &self.temperature_type, &self.filters.temp_filter, ) { @@ -387,16 +405,16 @@ impl DataCollector { #[inline] fn update_memory_usage(&mut self) { if self.widgets_to_harvest.use_mem { - self.data.memory = memory::get_ram_usage(&self.sys); + self.data.memory = memory::get_ram_usage(&self.sys.system); #[cfg(not(target_os = "windows"))] if self.widgets_to_harvest.use_cache { - self.data.cache = memory::get_cache_usage(&self.sys); + self.data.cache = memory::get_cache_usage(&self.sys.system); } self.data.swap = memory::get_swap_usage( #[cfg(not(target_os = "windows"))] - &self.sys, + &self.sys.system, ); #[cfg(feature = "zfs")] @@ -412,7 +430,7 @@ impl DataCollector { if self.widgets_to_harvest.use_net { let net_data = network::get_network_data( - &self.sys, + &self.sys.network, self.last_collection_time, &mut self.total_rx, &mut self.total_tx, @@ -451,7 +469,7 @@ impl DataCollector { if let Some(memory) = &self.data.memory { memory.total_bytes } else { - self.sys.total_memory() + self.sys.system.total_memory() } } } @@ -467,7 +485,7 @@ impl DataCollector { const fn get_sleep_duration() -> Duration { const MIN_SLEEP: u64 = 10; const MAX_SLEEP: u64 = 250; - const INTERVAL: u64 = System::MINIMUM_CPU_UPDATE_INTERVAL.as_millis() as u64; + const INTERVAL: u64 = sysinfo::MINIMUM_CPU_UPDATE_INTERVAL.as_millis() as u64; if INTERVAL < MIN_SLEEP { Duration::from_millis(MIN_SLEEP) diff --git a/src/data_collection/cpu/sysinfo.rs b/src/data_collection/cpu/sysinfo.rs index 9970eadf..196e8a87 100644 --- a/src/data_collection/cpu/sysinfo.rs +++ b/src/data_collection/cpu/sysinfo.rs @@ -3,7 +3,7 @@ use std::collections::VecDeque; -use sysinfo::{CpuExt, LoadAvg, System, SystemExt}; +use sysinfo::{LoadAvg, System}; use super::{CpuData, CpuDataType, CpuHarvest}; use crate::data_collection::cpu::LoadAvgHarvest; @@ -32,8 +32,8 @@ pub fn get_cpu_data_list(sys: &System, show_average_cpu: bool) -> crate::error:: } pub fn get_load_avg() -> crate::error::Result { - let sys = System::new(); - let LoadAvg { one, five, fifteen } = sys.load_average(); + // The API for sysinfo apparently wants you to call it like this, rather than using a &System. + let LoadAvg { one, five, fifteen } = sysinfo::System::load_average(); Ok([one as f32, five as f32, fifteen as f32]) } diff --git a/src/data_collection/disks/other.rs b/src/data_collection/disks/other.rs index 86317160..9e91fbb1 100644 --- a/src/data_collection/disks/other.rs +++ b/src/data_collection/disks/other.rs @@ -1,12 +1,10 @@ //! Fallback disk info using sysinfo. -use sysinfo::{DiskExt, SystemExt}; - use super::{keep_disk_entry, DiskHarvest}; use crate::data_collection::DataCollector; pub(crate) fn get_disk_usage(collector: &DataCollector) -> anyhow::Result> { - let disks = collector.sys.disks(); + let disks = &collector.sys.disks; let disk_filter = &collector.filters.disk_filter; let mount_filter = &collector.filters.mount_filter; diff --git a/src/data_collection/disks/windows.rs b/src/data_collection/disks/windows.rs index 469bf4bf..da64f559 100644 --- a/src/data_collection/disks/windows.rs +++ b/src/data_collection/disks/windows.rs @@ -4,7 +4,6 @@ mod bindings; use bindings::*; use itertools::Itertools; -use sysinfo::{DiskExt, SystemExt}; use super::{keep_disk_entry, DiskHarvest}; use crate::data_collection::{disks::IoCounters, DataCollector}; @@ -27,7 +26,7 @@ pub(crate) fn io_stats() -> anyhow::Result> { } pub(crate) fn get_disk_usage(collector: &DataCollector) -> anyhow::Result> { - let disks = collector.sys.disks(); + let disks = &collector.sys.disks; let disk_filter = &collector.filters.disk_filter; let mount_filter = &collector.filters.mount_filter; diff --git a/src/data_collection/memory/sysinfo.rs b/src/data_collection/memory/sysinfo.rs index 58ec4e3a..86ef5381 100644 --- a/src/data_collection/memory/sysinfo.rs +++ b/src/data_collection/memory/sysinfo.rs @@ -1,6 +1,6 @@ //! Collecting memory data using sysinfo. -use sysinfo::{System, SystemExt}; +use sysinfo::System; use crate::data_collection::memory::MemHarvest; @@ -41,7 +41,7 @@ pub(crate) fn get_swap_usage(sys: &System) -> Option { /// between the available and free memory. Free memory is defined as memory not containing any data, /// which means cache and buffer memory are not "free". Available memory is defined as memory able /// to be allocated by processes, which includes cache and buffer memory. On Windows, this will -/// always be 0. For more information, see [docs](https://docs.rs/sysinfo/0.28.4/sysinfo/trait.SystemExt.html#tymethod.available_memory) +/// always be 0. For more information, see [docs](https://docs.rs/sysinfo/latest/sysinfo/struct.System.html#method.available_memory) /// and [memory explanation](https://askubuntu.com/questions/867068/what-is-available-memory-while-using-free-command) #[cfg(not(target_os = "windows"))] pub(crate) fn get_cache_usage(sys: &System) -> Option { diff --git a/src/data_collection/network/sysinfo.rs b/src/data_collection/network/sysinfo.rs index a5b85d9a..3949c4b8 100644 --- a/src/data_collection/network/sysinfo.rs +++ b/src/data_collection/network/sysinfo.rs @@ -2,20 +2,19 @@ use std::time::Instant; +use sysinfo::Networks; + use super::NetworkHarvest; use crate::app::filter::Filter; // TODO: Eventually make it so that this thing also takes individual usage into account, so we can show per-interface! pub fn get_network_data( - sys: &sysinfo::System, prev_net_access_time: Instant, prev_net_rx: &mut u64, + networks: &Networks, prev_net_access_time: Instant, prev_net_rx: &mut u64, prev_net_tx: &mut u64, curr_time: Instant, filter: &Option, ) -> NetworkHarvest { - use sysinfo::{NetworkExt, SystemExt}; - let mut total_rx: u64 = 0; let mut total_tx: u64 = 0; - let networks = sys.networks(); for (name, network) in networks { let to_keep = if let Some(filter) = filter { filter.keep_entry(name) diff --git a/src/data_collection/processes/linux.rs b/src/data_collection/processes/linux.rs index 18103f11..3533e63e 100644 --- a/src/data_collection/processes/linux.rs +++ b/src/data_collection/processes/linux.rs @@ -312,8 +312,7 @@ pub(crate) fn linux_process_data( }) = cpu_usage_calculation(prev_idle, prev_non_idle) { if unnormalized_cpu { - use sysinfo::SystemExt; - let num_processors = collector.sys.cpus().len() as f64; + let num_processors = collector.sys.system.cpus().len() as f64; // Note we *divide* here because the later calculation divides `cpu_usage` - in effect, // multiplying over the number of cores. diff --git a/src/data_collection/processes/macos.rs b/src/data_collection/processes/macos.rs index 42aae82a..8f3a09a8 100644 --- a/src/data_collection/processes/macos.rs +++ b/src/data_collection/processes/macos.rs @@ -6,7 +6,6 @@ use std::{io, process::Command}; use hashbrown::HashMap; use itertools::Itertools; -use sysinfo::{PidExt, ProcessExt}; use super::UnixProcessExt; use crate::Pid; diff --git a/src/data_collection/processes/unix.rs b/src/data_collection/processes/unix.rs index 4c79dc0f..ea1a3701 100644 --- a/src/data_collection/processes/unix.rs +++ b/src/data_collection/processes/unix.rs @@ -16,7 +16,7 @@ cfg_if! { use crate::utils::error; pub fn sysinfo_process_data(collector: &mut DataCollector) -> error::Result> { - let sys = &collector.sys; + let sys = &collector.sys.system; let use_current_cpu_total = collector.use_current_cpu_total; let unnormalized_cpu = collector.unnormalized_cpu; let total_memory = collector.total_memory(); diff --git a/src/data_collection/processes/unix/process_ext.rs b/src/data_collection/processes/unix/process_ext.rs index 4087c4da..feabfea1 100644 --- a/src/data_collection/processes/unix/process_ext.rs +++ b/src/data_collection/processes/unix/process_ext.rs @@ -3,7 +3,7 @@ use std::{io, time::Duration}; use hashbrown::HashMap; -use sysinfo::{CpuExt, PidExt, ProcessExt, ProcessStatus, System, SystemExt}; +use sysinfo::{ProcessStatus, System}; use super::ProcessHarvest; use crate::{data_collection::processes::UserTable, utils::error, Pid}; @@ -24,17 +24,12 @@ pub(crate) trait UnixProcessExt { 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() - } + process_val + .exe() + .and_then(|exe| exe.file_stem()) + .and_then(|stem| stem.to_str()) + .map(|s| s.to_string()) + .unwrap_or(String::new()) } } else { process_val.name().to_string() diff --git a/src/data_collection/processes/windows.rs b/src/data_collection/processes/windows.rs index 7ed79580..d8e3fea9 100644 --- a/src/data_collection/processes/windows.rs +++ b/src/data_collection/processes/windows.rs @@ -2,15 +2,15 @@ use std::time::Duration; -use sysinfo::{CpuExt, PidExt, ProcessExt, SystemExt, UserExt}; - use super::ProcessHarvest; use crate::data_collection::DataCollector; +// TODO: There's a lot of shared code with this and the unix impl. pub fn sysinfo_process_data( collector: &mut DataCollector, ) -> crate::utils::error::Result> { - let sys = &collector.sys; + let sys = &collector.sys.system; + let users = &collector.sys.users; let use_current_cpu_total = collector.use_current_cpu_total; let unnormalized_cpu = collector.unnormalized_cpu; let total_memory = collector.total_memory(); @@ -26,17 +26,12 @@ pub fn sysinfo_process_data( 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() - } + process_val + .exe() + .and_then(|exe| exe.file_stem()) + .and_then(|stem| stem.to_str()) + .map(|s| s.to_string()) + .unwrap_or(String::new()) } } else { process_val.name().to_string() @@ -105,7 +100,7 @@ pub fn sysinfo_process_data( process_state, user: process_val .user_id() - .and_then(|uid| sys.get_user_by_id(uid)) + .and_then(|uid| users.get_user_by_id(uid)) .map_or_else(|| "N/A".into(), |user| user.name().to_owned().into()), time: if process_val.start_time() == 0 { // Workaround for Windows occasionally returning a start time equal to UNIX epoch, giving a run time diff --git a/src/data_collection/temperature/sysinfo.rs b/src/data_collection/temperature/sysinfo.rs index 9a2ea403..c6feb0b8 100644 --- a/src/data_collection/temperature/sysinfo.rs +++ b/src/data_collection/temperature/sysinfo.rs @@ -6,14 +6,11 @@ use super::{is_temp_filtered, TempHarvest, TemperatureType}; use crate::app::filter::Filter; pub fn get_temperature_data( - sys: &sysinfo::System, temp_type: &TemperatureType, filter: &Option, + components: &sysinfo::Components, temp_type: &TemperatureType, filter: &Option, ) -> Result>> { - use sysinfo::{ComponentExt, SystemExt}; - let mut temperature_vec: Vec = Vec::new(); - let sensor_data = sys.components(); - for component in sensor_data { + for component in components { let name = component.label().to_string(); if is_temp_filtered(filter, &name) {