mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-07-23 13:45:12 +02:00
First implementation of cache memory data collection, mostly copied from RAM and swap implementations
This commit is contained in:
parent
7f4e762921
commit
ba94509bef
@ -37,6 +37,7 @@ pub struct TimedData {
|
|||||||
pub cpu_data: Vec<Value>,
|
pub cpu_data: Vec<Value>,
|
||||||
pub load_avg_data: [f32; 3],
|
pub load_avg_data: [f32; 3],
|
||||||
pub mem_data: Option<Value>,
|
pub mem_data: Option<Value>,
|
||||||
|
pub cache_data: Option<Value>,
|
||||||
pub swap_data: Option<Value>,
|
pub swap_data: Option<Value>,
|
||||||
#[cfg(feature = "zfs")]
|
#[cfg(feature = "zfs")]
|
||||||
pub arc_data: Option<Value>,
|
pub arc_data: Option<Value>,
|
||||||
@ -110,6 +111,7 @@ pub struct DataCollection {
|
|||||||
pub timed_data_vec: Vec<(Instant, TimedData)>,
|
pub timed_data_vec: Vec<(Instant, TimedData)>,
|
||||||
pub network_harvest: network::NetworkHarvest,
|
pub network_harvest: network::NetworkHarvest,
|
||||||
pub memory_harvest: memory::MemHarvest,
|
pub memory_harvest: memory::MemHarvest,
|
||||||
|
pub cache_harvest: memory::MemHarvest,
|
||||||
pub swap_harvest: memory::MemHarvest,
|
pub swap_harvest: memory::MemHarvest,
|
||||||
pub cpu_harvest: cpu::CpuHarvest,
|
pub cpu_harvest: cpu::CpuHarvest,
|
||||||
pub load_avg_harvest: cpu::LoadAvgHarvest,
|
pub load_avg_harvest: cpu::LoadAvgHarvest,
|
||||||
@ -134,6 +136,7 @@ impl Default for DataCollection {
|
|||||||
timed_data_vec: Vec::default(),
|
timed_data_vec: Vec::default(),
|
||||||
network_harvest: network::NetworkHarvest::default(),
|
network_harvest: network::NetworkHarvest::default(),
|
||||||
memory_harvest: memory::MemHarvest::default(),
|
memory_harvest: memory::MemHarvest::default(),
|
||||||
|
cache_harvest: memory::MemHarvest::default(),
|
||||||
swap_harvest: memory::MemHarvest::default(),
|
swap_harvest: memory::MemHarvest::default(),
|
||||||
cpu_harvest: cpu::CpuHarvest::default(),
|
cpu_harvest: cpu::CpuHarvest::default(),
|
||||||
load_avg_harvest: cpu::LoadAvgHarvest::default(),
|
load_avg_harvest: cpu::LoadAvgHarvest::default(),
|
||||||
@ -209,8 +212,8 @@ impl DataCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Memory and Swap
|
// Memory and Swap
|
||||||
if let (Some(memory), Some(swap)) = (harvested_data.memory, harvested_data.swap) {
|
if let (Some(memory), Some(cache), Some(swap)) = (harvested_data.memory, harvested_data.cache, harvested_data.swap) {
|
||||||
self.eat_memory_and_swap(memory, swap, &mut new_entry);
|
self.eat_memory_and_swap(memory, cache, swap, &mut new_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "zfs")]
|
#[cfg(feature = "zfs")]
|
||||||
@ -264,16 +267,20 @@ impl DataCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn eat_memory_and_swap(
|
fn eat_memory_and_swap(
|
||||||
&mut self, memory: memory::MemHarvest, swap: memory::MemHarvest, new_entry: &mut TimedData,
|
&mut self, memory: memory::MemHarvest, cache: memory::MemHarvest, swap: memory::MemHarvest, new_entry: &mut TimedData,
|
||||||
) {
|
) {
|
||||||
// Memory
|
// Memory
|
||||||
new_entry.mem_data = memory.use_percent;
|
new_entry.mem_data = memory.use_percent;
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
new_entry.cache_data = cache.use_percent;
|
||||||
|
|
||||||
// Swap
|
// Swap
|
||||||
new_entry.swap_data = swap.use_percent;
|
new_entry.swap_data = swap.use_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;
|
||||||
|
self.cache_harvest = cache;
|
||||||
self.swap_harvest = swap;
|
self.swap_harvest = swap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ pub struct Data {
|
|||||||
pub cpu: Option<cpu::CpuHarvest>,
|
pub cpu: Option<cpu::CpuHarvest>,
|
||||||
pub load_avg: Option<cpu::LoadAvgHarvest>,
|
pub load_avg: Option<cpu::LoadAvgHarvest>,
|
||||||
pub memory: Option<memory::MemHarvest>,
|
pub memory: Option<memory::MemHarvest>,
|
||||||
|
pub cache: Option<memory::MemHarvest>,
|
||||||
pub swap: Option<memory::MemHarvest>,
|
pub swap: Option<memory::MemHarvest>,
|
||||||
pub temperature_sensors: Option<Vec<temperature::TempHarvest>>,
|
pub temperature_sensors: Option<Vec<temperature::TempHarvest>>,
|
||||||
pub network: Option<network::NetworkHarvest>,
|
pub network: Option<network::NetworkHarvest>,
|
||||||
@ -55,6 +56,7 @@ impl Default for Data {
|
|||||||
cpu: None,
|
cpu: None,
|
||||||
load_avg: None,
|
load_avg: None,
|
||||||
memory: None,
|
memory: None,
|
||||||
|
cache: None,
|
||||||
swap: None,
|
swap: None,
|
||||||
temperature_sensors: None,
|
temperature_sensors: None,
|
||||||
list_of_processes: None,
|
list_of_processes: None,
|
||||||
@ -397,6 +399,7 @@ impl DataCollector {
|
|||||||
fn update_memory_usage(&mut self) {
|
fn update_memory_usage(&mut self) {
|
||||||
if self.widgets_to_harvest.use_mem {
|
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);
|
||||||
|
self.data.cache = memory::get_cache_usage(&self.sys);
|
||||||
self.data.swap = memory::get_swap_usage(
|
self.data.swap = memory::get_swap_usage(
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
&self.sys,
|
&self.sys,
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
pub mod sysinfo;
|
pub mod sysinfo;
|
||||||
pub(crate) use self::sysinfo::get_ram_usage;
|
pub(crate) use self::sysinfo::get_ram_usage;
|
||||||
|
pub(crate) use self::sysinfo::get_cache_usage;
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(target_os = "windows")] {
|
if #[cfg(target_os = "windows")] {
|
||||||
|
@ -36,3 +36,19 @@ pub(crate) fn get_swap_usage(sys: &System) -> Option<MemHarvest> {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns cache usage.
|
||||||
|
pub(crate) fn get_cache_usage(sys: &System) -> Option<MemHarvest> {
|
||||||
|
let mem_used_in_kib = (sys.available_memory() - sys.free_memory()) / 1024;
|
||||||
|
let mem_total_in_kib = sys.total_memory() / 1024;
|
||||||
|
|
||||||
|
Some(MemHarvest {
|
||||||
|
total_kib: mem_total_in_kib,
|
||||||
|
used_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)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -68,9 +68,11 @@ pub struct ConvertedData {
|
|||||||
pub network_data_tx: Vec<Point>,
|
pub network_data_tx: Vec<Point>,
|
||||||
|
|
||||||
pub mem_labels: Option<(String, String)>,
|
pub mem_labels: Option<(String, String)>,
|
||||||
|
pub cache_labels: Option<(String, String)>,
|
||||||
pub swap_labels: Option<(String, String)>,
|
pub swap_labels: Option<(String, String)>,
|
||||||
|
|
||||||
pub mem_data: Vec<Point>, /* TODO: Switch this and all data points over to a better data structure... */
|
pub mem_data: Vec<Point>, /* TODO: Switch this and all data points over to a better data structure... */
|
||||||
|
pub cache_data: Vec<Point>,
|
||||||
pub swap_data: Vec<Point>,
|
pub swap_data: Vec<Point>,
|
||||||
|
|
||||||
#[cfg(feature = "zfs")]
|
#[cfg(feature = "zfs")]
|
||||||
@ -218,6 +220,24 @@ pub fn convert_mem_data_points(current_data: &DataCollection) -> Vec<Point> {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn convert_cache_data_points(current_data: &DataCollection) -> Vec<Point> {
|
||||||
|
let mut result: Vec<Point> = Vec::new();
|
||||||
|
let current_time = current_data.current_instant;
|
||||||
|
|
||||||
|
for (time, data) in ¤t_data.timed_data_vec {
|
||||||
|
if let Some(cache_data) = data.cache_data {
|
||||||
|
let time_from_start: f64 =
|
||||||
|
(current_time.duration_since(*time).as_millis() as f64).floor();
|
||||||
|
result.push((-time_from_start, cache_data));
|
||||||
|
if *time == current_time {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
pub fn convert_swap_data_points(current_data: &DataCollection) -> Vec<Point> {
|
pub fn convert_swap_data_points(current_data: &DataCollection) -> Vec<Point> {
|
||||||
let mut result: Vec<Point> = Vec::new();
|
let mut result: Vec<Point> = Vec::new();
|
||||||
let current_time = current_data.current_instant;
|
let current_time = current_data.current_instant;
|
||||||
@ -238,7 +258,7 @@ pub fn convert_swap_data_points(current_data: &DataCollection) -> Vec<Point> {
|
|||||||
|
|
||||||
pub fn convert_mem_labels(
|
pub fn convert_mem_labels(
|
||||||
current_data: &DataCollection,
|
current_data: &DataCollection,
|
||||||
) -> (Option<(String, String)>, Option<(String, String)>) {
|
) -> (Option<(String, String)>, Option<(String, String)>, Option<(String, String)>) {
|
||||||
/// Returns the unit type and denominator for given total amount of memory in kibibytes.
|
/// Returns the unit type and denominator for given total amount of memory in kibibytes.
|
||||||
fn return_unit_and_denominator_for_mem_kib(mem_total_kib: u64) -> (&'static str, f64) {
|
fn return_unit_and_denominator_for_mem_kib(mem_total_kib: u64) -> (&'static str, f64) {
|
||||||
if mem_total_kib < 1024 {
|
if mem_total_kib < 1024 {
|
||||||
@ -280,6 +300,29 @@ pub fn convert_mem_labels(
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
if current_data.cache_harvest.total_kib > 0 {
|
||||||
|
Some((
|
||||||
|
format!(
|
||||||
|
"{:3.0}%",
|
||||||
|
current_data.cache_harvest.use_percent.unwrap_or(0.0)
|
||||||
|
),
|
||||||
|
{
|
||||||
|
let (unit, denominator) = return_unit_and_denominator_for_mem_kib(
|
||||||
|
current_data.cache_harvest.total_kib,
|
||||||
|
);
|
||||||
|
|
||||||
|
format!(
|
||||||
|
" {:.1}{}/{:.1}{}",
|
||||||
|
current_data.cache_harvest.used_kib as f64 / denominator,
|
||||||
|
unit,
|
||||||
|
(current_data.cache_harvest.total_kib as f64 / denominator),
|
||||||
|
unit
|
||||||
|
)
|
||||||
|
},
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
if current_data.swap_harvest.total_kib > 0 {
|
if current_data.swap_harvest.total_kib > 0 {
|
||||||
Some((
|
Some((
|
||||||
format!(
|
format!(
|
||||||
|
@ -386,6 +386,7 @@ pub fn update_data(app: &mut App) {
|
|||||||
// TODO: [OPT] Prefer reassignment over new vectors?
|
// TODO: [OPT] Prefer reassignment over new vectors?
|
||||||
if app.mem_state.force_update.is_some() {
|
if app.mem_state.force_update.is_some() {
|
||||||
app.converted_data.mem_data = convert_mem_data_points(data_source);
|
app.converted_data.mem_data = convert_mem_data_points(data_source);
|
||||||
|
app.converted_data.cache_data = convert_cache_data_points(data_source);
|
||||||
app.converted_data.swap_data = convert_swap_data_points(data_source);
|
app.converted_data.swap_data = convert_swap_data_points(data_source);
|
||||||
#[cfg(feature = "zfs")]
|
#[cfg(feature = "zfs")]
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user