bug: Fix swap calculation for Linux (#546)

Workaround for Linux heim memory units not being correct for swap.
This commit is contained in:
Clement Tsang 2021-07-16 01:16:18 -04:00 committed by GitHub
parent 847027182b
commit 4e07a28e17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 42 deletions

View File

@ -180,20 +180,10 @@ impl DataCollection {
&mut self, memory: memory::MemHarvest, swap: memory::MemHarvest, new_entry: &mut TimedData, &mut self, memory: memory::MemHarvest, swap: memory::MemHarvest, new_entry: &mut TimedData,
) { ) {
// Memory // Memory
let mem_percent = if memory.mem_total_in_kib > 0 { new_entry.mem_data = memory.use_percent;
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;
// Swap // Swap
let swap_percent = if swap.mem_total_in_kib > 0 { new_entry.swap_data = swap.use_percent;
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;
// In addition copy over latest data for easy reference // In addition copy over latest data for easy reference
self.memory_harvest = memory; self.memory_harvest = memory;

View File

@ -1,18 +1,10 @@
//! Data collection for memory via heim. //! Data collection for memory via heim.
#[derive(Debug, Clone)] #[derive(Debug, Clone, Default)]
pub struct MemHarvest { pub struct MemHarvest {
pub mem_total_in_kib: u64, pub mem_total_in_kib: u64,
pub mem_used_in_kib: u64, pub mem_used_in_kib: u64,
} pub use_percent: Option<f64>,
impl Default for MemHarvest {
fn default() -> Self {
MemHarvest {
mem_total_in_kib: 0,
mem_used_in_kib: 0,
}
}
} }
pub async fn get_mem_data( pub async fn get_mem_data(
@ -36,37 +28,36 @@ pub async fn get_ram_data() -> crate::utils::error::Result<Option<MemHarvest>> {
let (mem_total_in_kib, mem_used_in_kib) = { let (mem_total_in_kib, mem_used_in_kib) = {
#[cfg(target_os = "linux")] #[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 // 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 // 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) // 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... // even though it probably shouldn't...
use heim::memory::os::linux::MemoryExt;
( (
memory.total().get::<heim::units::information::kilobyte>(), memory.total().get::<kilobyte>(),
memory.used().get::<heim::units::information::kilobyte>(), memory.used().get::<kilobyte>(),
) )
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
use heim::memory::os::macos::MemoryExt; use heim::memory::os::macos::MemoryExt;
use heim::units::information::kibibyte;
( (
memory.total().get::<heim::units::information::kibibyte>(), memory.total().get::<kibibyte>(),
memory.active().get::<heim::units::information::kibibyte>() memory.active().get::<kibibyte>() + memory.wire().get::<kibibyte>(),
+ memory.wire().get::<heim::units::information::kibibyte>(),
) )
} }
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
let mem_total_in_kib = memory.total().get::<heim::units::information::kibibyte>(); use heim::units::information::kibibyte;
let mem_total_in_kib = memory.total().get::<kibibyte>();
( (
mem_total_in_kib, mem_total_in_kib,
mem_total_in_kib mem_total_in_kib - memory.available().get::<kibibyte>(),
- memory
.available()
.get::<heim::units::information::kibibyte>(),
) )
} }
}; };
@ -74,14 +65,44 @@ pub async fn get_ram_data() -> crate::utils::error::Result<Option<MemHarvest>> {
Ok(Some(MemHarvest { Ok(Some(MemHarvest {
mem_total_in_kib, mem_total_in_kib,
mem_used_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<Option<MemHarvest>> { pub async fn get_swap_data() -> crate::utils::error::Result<Option<MemHarvest>> {
let memory = heim::memory::swap().await?; 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::<kilobyte>(),
memory.used().get::<kilobyte>(),
)
}
#[cfg(any(target_os = "windows", target_os = "macos"))]
{
use heim::units::information::kibibyte;
(
memory.total().get::<kibibyte>(),
memory.used().get::<kibibyte>(),
)
}
};
Ok(Some(MemHarvest { Ok(Some(MemHarvest {
mem_total_in_kib: memory.total().get::<heim::units::information::kibibyte>(), mem_total_in_kib,
mem_used_in_kib: memory.used().get::<heim::units::information::kibibyte>(), 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)
},
})) }))
} }

View File

@ -321,9 +321,7 @@ pub fn convert_mem_labels(
Some(( Some((
format!( format!(
"{:3.0}%", "{:3.0}%",
current_data.memory_harvest.mem_used_in_kib as f64 current_data.memory_harvest.use_percent.unwrap_or(0.0)
/ current_data.memory_harvest.mem_total_in_kib as f64
* 100.0
), ),
{ {
let (unit, denominator) = return_unit_and_denominator_for_mem_kib( let (unit, denominator) = return_unit_and_denominator_for_mem_kib(
@ -346,9 +344,7 @@ pub fn convert_mem_labels(
Some(( Some((
format!( format!(
"{:3.0}%", "{:3.0}%",
current_data.swap_harvest.mem_used_in_kib as f64 current_data.swap_harvest.use_percent.unwrap_or(0.0)
/ current_data.swap_harvest.mem_total_in_kib as f64
* 100.0
), ),
{ {
let (unit, denominator) = return_unit_and_denominator_for_mem_kib( let (unit, denominator) = return_unit_and_denominator_for_mem_kib(