mirror of
https://github.com/ClementTsang/bottom.git
synced 2024-09-11 03:35:35 +03:00
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
This commit is contained in:
parent
81e77c02a8
commit
f07994ef68
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -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]]
|
||||
|
@ -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"] }
|
||||
|
@ -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)
|
||||
|
@ -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<LoadAvgHarvest> {
|
||||
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])
|
||||
}
|
||||
|
@ -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<Vec<DiskHarvest>> {
|
||||
let disks = collector.sys.disks();
|
||||
let disks = &collector.sys.disks;
|
||||
let disk_filter = &collector.filters.disk_filter;
|
||||
let mount_filter = &collector.filters.mount_filter;
|
||||
|
||||
|
@ -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<Vec<IoCounters>> {
|
||||
}
|
||||
|
||||
pub(crate) fn get_disk_usage(collector: &DataCollector) -> anyhow::Result<Vec<DiskHarvest>> {
|
||||
let disks = collector.sys.disks();
|
||||
let disks = &collector.sys.disks;
|
||||
let disk_filter = &collector.filters.disk_filter;
|
||||
let mount_filter = &collector.filters.mount_filter;
|
||||
|
||||
|
@ -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<MemHarvest> {
|
||||
/// 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<MemHarvest> {
|
||||
|
@ -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<Filter>,
|
||||
) -> 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)
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -16,7 +16,7 @@ cfg_if! {
|
||||
use crate::utils::error;
|
||||
|
||||
pub fn sysinfo_process_data(collector: &mut DataCollector) -> error::Result<Vec<ProcessHarvest>> {
|
||||
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();
|
||||
|
@ -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()
|
||||
|
@ -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<Vec<ProcessHarvest>> {
|
||||
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
|
||||
|
@ -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<Filter>,
|
||||
components: &sysinfo::Components, temp_type: &TemperatureType, filter: &Option<Filter>,
|
||||
) -> Result<Option<Vec<TempHarvest>>> {
|
||||
use sysinfo::{ComponentExt, SystemExt};
|
||||
|
||||
let mut temperature_vec: Vec<TempHarvest> = 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) {
|
||||
|
Loading…
Reference in New Issue
Block a user