From 4e07a28e172f0767edbb9d508f4fa9e2af7b25cd Mon Sep 17 00:00:00 2001 From: Clement Tsang <34804052+ClementTsang@users.noreply.github.com> Date: Fri, 16 Jul 2021 01:16:18 -0400 Subject: bug: Fix swap calculation for Linux (#546) Workaround for Linux heim memory units not being correct for swap. --- src/app/data_farmer.rs | 14 +------ src/app/data_harvester/memory/heim.rs | 69 +++++++++++++++++++++++------------ src/data_conversion.rs | 8 +--- 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/app/data_farmer.rs b/src/app/data_farmer.rs index 31c247ca..931ab96f 100644 --- a/src/app/data_farmer.rs +++ b/src/app/data_farmer.rs @@ -180,20 +180,10 @@ impl DataCollection { &mut self, memory: memory::MemHarvest, swap: memory::MemHarvest, new_entry: &mut TimedData, ) { // Memory - let mem_percent = if memory.mem_total_in_kib > 0 { - Some((memory.mem_used_in_kib as f64) / (memory.mem_total_in_kib as f64) * 100.0) - } else { - None - }; - new_entry.mem_data = mem_percent; + new_entry.mem_data = memory.use_percent; // Swap - let swap_percent = if swap.mem_total_in_kib > 0 { - Some((swap.mem_used_in_kib as f64) / (swap.mem_total_in_kib as f64) * 100.0) - } else { - None - }; - new_entry.swap_data = swap_percent; + new_entry.swap_data = swap.use_percent; // In addition copy over latest data for easy reference self.memory_harvest = memory; diff --git a/src/app/data_harvester/memory/heim.rs b/src/app/data_harvester/memory/heim.rs index e0d9c2c9..29f16910 100644 --- a/src/app/data_harvester/memory/heim.rs +++ b/src/app/data_harvester/memory/heim.rs @@ -1,18 +1,10 @@ //! Data collection for memory via heim. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct MemHarvest { pub mem_total_in_kib: u64, pub mem_used_in_kib: u64, -} - -impl Default for MemHarvest { - fn default() -> Self { - MemHarvest { - mem_total_in_kib: 0, - mem_used_in_kib: 0, - } - } + pub use_percent: Option, } pub async fn get_mem_data( @@ -36,37 +28,36 @@ pub async fn get_ram_data() -> crate::utils::error::Result> { let (mem_total_in_kib, mem_used_in_kib) = { #[cfg(target_os = "linux")] { + use heim::memory::os::linux::MemoryExt; + use heim::units::information::kilobyte; + // For Linux, the "kilobyte" value in the .total call is actually kibibytes - see // https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-meminfo // // Heim parses this as kilobytes (https://github.com/heim-rs/heim/blob/master/heim-memory/src/sys/linux/memory.rs#L82) // even though it probably shouldn't... - use heim::memory::os::linux::MemoryExt; - ( - memory.total().get::(), - memory.used().get::(), + memory.total().get::(), + memory.used().get::(), ) } #[cfg(target_os = "macos")] { use heim::memory::os::macos::MemoryExt; + use heim::units::information::kibibyte; ( - memory.total().get::(), - memory.active().get::() - + memory.wire().get::(), + memory.total().get::(), + memory.active().get::() + memory.wire().get::(), ) } #[cfg(target_os = "windows")] { - let mem_total_in_kib = memory.total().get::(); + use heim::units::information::kibibyte; + let mem_total_in_kib = memory.total().get::(); ( mem_total_in_kib, - mem_total_in_kib - - memory - .available() - .get::(), + mem_total_in_kib - memory.available().get::(), ) } }; @@ -74,14 +65,44 @@ pub async fn get_ram_data() -> crate::utils::error::Result> { Ok(Some(MemHarvest { mem_total_in_kib, mem_used_in_kib, + use_percent: if mem_total_in_kib == 0 { + None + } else { + Some(mem_used_in_kib as f64 / mem_total_in_kib as f64 * 100.0) + }, })) } pub async fn get_swap_data() -> crate::utils::error::Result> { let memory = heim::memory::swap().await?; + let (mem_total_in_kib, mem_used_in_kib) = { + #[cfg(target_os = "linux")] + { + // Similar story to above - heim parses this information incorrectly as far as I can tell, so kilobytes = kibibytes here. + use heim::units::information::kilobyte; + ( + memory.total().get::(), + memory.used().get::(), + ) + } + #[cfg(any(target_os = "windows", target_os = "macos"))] + { + use heim::units::information::kibibyte; + ( + memory.total().get::(), + memory.used().get::(), + ) + } + }; + Ok(Some(MemHarvest { - mem_total_in_kib: memory.total().get::(), - mem_used_in_kib: memory.used().get::(), + mem_total_in_kib, + mem_used_in_kib, + use_percent: if mem_total_in_kib == 0 { + None + } else { + Some(mem_used_in_kib as f64 / mem_total_in_kib as f64 * 100.0) + }, })) } diff --git a/src/data_conversion.rs b/src/data_conversion.rs index 6548e0b6..fce34145 100644 --- a/src/data_conversion.rs +++ b/src/data_conversion.rs @@ -321,9 +321,7 @@ pub fn convert_mem_labels( Some(( format!( "{:3.0}%", - current_data.memory_harvest.mem_used_in_kib as f64 - / current_data.memory_harvest.mem_total_in_kib as f64 - * 100.0 + current_data.memory_harvest.use_percent.unwrap_or(0.0) ), { let (unit, denominator) = return_unit_and_denominator_for_mem_kib( @@ -346,9 +344,7 @@ pub fn convert_mem_labels( Some(( format!( "{:3.0}%", - current_data.swap_harvest.mem_used_in_kib as f64 - / current_data.swap_harvest.mem_total_in_kib as f64 - * 100.0 + current_data.swap_harvest.use_percent.unwrap_or(0.0) ), { let (unit, denominator) = return_unit_and_denominator_for_mem_kib( -- cgit v1.2.3