mirror of
https://github.com/ClementTsang/bottom
synced 2024-11-10 14:44:18 +00:00
feature: Add zfs feature flag for arc memory (#784)
* freebsd clippy * add arc support * Code Review: moved runtime cfg checks to compile time and formatting * remove compile platform checks * add zfs feature flag to get_arc_data
This commit is contained in:
parent
11657aa0ab
commit
6e0bc96093
16 changed files with 375 additions and 8 deletions
34
Cargo.lock
generated
34
Cargo.lock
generated
|
@ -236,6 +236,7 @@ dependencies = [
|
|||
"serde_json",
|
||||
"smol",
|
||||
"starship-battery",
|
||||
"sysctl",
|
||||
"sysinfo",
|
||||
"thiserror",
|
||||
"time",
|
||||
|
@ -1358,6 +1359,15 @@ version = "1.0.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
|
@ -1511,6 +1521,19 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysctl"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225e483f02d0ad107168dc57381a8a40c3aeea6abe47f37506931f861643cfa8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"libc",
|
||||
"thiserror",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.23.10"
|
||||
|
@ -1681,6 +1704,17 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
|
|
|
@ -41,11 +41,12 @@ opt-level = 3
|
|||
codegen-units = 1
|
||||
|
||||
[features]
|
||||
default = ["fern", "log", "battery", "gpu"]
|
||||
default = ["fern", "log", "battery", "gpu", "zfs"]
|
||||
battery = ["starship-battery"]
|
||||
deploy = ["battery", "gpu"]
|
||||
gpu = ["nvidia"]
|
||||
nvidia = ["nvml-wrapper"]
|
||||
zfs = ["sysctl"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.57"
|
||||
|
@ -96,6 +97,7 @@ winapi = "0.3.9"
|
|||
|
||||
[target.'cfg(target_os = "freebsd")'.dependencies]
|
||||
serde_json = { version = "1.0.82" }
|
||||
sysctl = { version = "0.4.6", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_cmd = "2.0.4"
|
||||
|
|
|
@ -41,6 +41,8 @@ pub struct TimedData {
|
|||
pub load_avg_data: [f32; 3],
|
||||
pub mem_data: Option<Value>,
|
||||
pub swap_data: Option<Value>,
|
||||
#[cfg(feature = "zfs")]
|
||||
pub arc_data: Option<Value>,
|
||||
}
|
||||
|
||||
pub type StringPidMap = FxHashMap<String, Vec<Pid>>;
|
||||
|
@ -161,6 +163,8 @@ pub struct DataCollection {
|
|||
pub temp_harvest: Vec<temperature::TempHarvest>,
|
||||
#[cfg(feature = "battery")]
|
||||
pub battery_harvest: Vec<batteries::BatteryHarvest>,
|
||||
#[cfg(feature = "zfs")]
|
||||
pub arc_harvest: memory::MemHarvest,
|
||||
}
|
||||
|
||||
impl Default for DataCollection {
|
||||
|
@ -182,6 +186,8 @@ impl Default for DataCollection {
|
|||
temp_harvest: Vec::default(),
|
||||
#[cfg(feature = "battery")]
|
||||
battery_harvest: Vec::default(),
|
||||
#[cfg(feature = "zfs")]
|
||||
arc_harvest: memory::MemHarvest::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -202,6 +208,10 @@ impl DataCollection {
|
|||
{
|
||||
self.battery_harvest = Vec::default();
|
||||
}
|
||||
#[cfg(feature = "zfs")]
|
||||
{
|
||||
self.arc_harvest = memory::MemHarvest::default();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn freeze(&mut self) {
|
||||
|
@ -247,6 +257,12 @@ impl DataCollection {
|
|||
self.eat_memory_and_swap(memory, swap, &mut new_entry);
|
||||
}
|
||||
|
||||
#[cfg(feature = "zfs")]
|
||||
{
|
||||
if let Some(arc) = harvested_data.arc {
|
||||
self.eat_arc(arc, &mut new_entry);
|
||||
}
|
||||
}
|
||||
// CPU
|
||||
if let Some(cpu) = harvested_data.cpu {
|
||||
self.eat_cpu(cpu, &mut new_entry);
|
||||
|
@ -427,4 +443,11 @@ impl DataCollection {
|
|||
fn eat_battery(&mut self, list_of_batteries: Vec<batteries::BatteryHarvest>) {
|
||||
self.battery_harvest = list_of_batteries;
|
||||
}
|
||||
|
||||
#[cfg(feature = "zfs")]
|
||||
fn eat_arc(&mut self, arc: memory::MemHarvest, new_entry: &mut TimedData) {
|
||||
// Arc
|
||||
new_entry.arc_data = arc.use_percent;
|
||||
self.arc_harvest = arc;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,8 @@ pub struct Data {
|
|||
pub io: Option<disks::IoHarvest>,
|
||||
#[cfg(feature = "battery")]
|
||||
pub list_of_batteries: Option<Vec<batteries::BatteryHarvest>>,
|
||||
#[cfg(feature = "zfs")]
|
||||
pub arc: Option<memory::MemHarvest>,
|
||||
}
|
||||
|
||||
impl Default for Data {
|
||||
|
@ -57,6 +59,8 @@ impl Default for Data {
|
|||
network: None,
|
||||
#[cfg(feature = "battery")]
|
||||
list_of_batteries: None,
|
||||
#[cfg(feature = "zfs")]
|
||||
arc: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +79,10 @@ impl Data {
|
|||
if let Some(network) = &mut self.network {
|
||||
network.first_run_cleanup();
|
||||
}
|
||||
#[cfg(feature = "zfs")]
|
||||
{
|
||||
self.arc = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,6 +429,11 @@ impl DataCollector {
|
|||
self.data.swap = swap;
|
||||
}
|
||||
|
||||
#[cfg(feature = "zfs")]
|
||||
if let Ok(arc) = mem_res.2 {
|
||||
self.data.arc = arc;
|
||||
}
|
||||
|
||||
if let Ok(disks) = disk_res {
|
||||
self.data.disks = disks;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::app::data_harvester::cpu::LoadAvgHarvest;
|
|||
|
||||
pub async fn get_cpu_data_list(
|
||||
sys: &sysinfo::System, show_average_cpu: bool,
|
||||
_previous_cpu_times: &mut Vec<(PastCpuWork, PastCpuTotal)>,
|
||||
_previous_cpu_times: &mut [(PastCpuWork, PastCpuTotal)],
|
||||
_previous_average_cpu_time: &mut Option<(PastCpuWork, PastCpuTotal)>,
|
||||
) -> crate::error::Result<CpuHarvest> {
|
||||
let mut cpu_deque: VecDeque<_> = sys
|
||||
|
|
|
@ -7,13 +7,14 @@ pub async fn get_mem_data(
|
|||
) -> (
|
||||
crate::utils::error::Result<Option<MemHarvest>>,
|
||||
crate::utils::error::Result<Option<MemHarvest>>,
|
||||
crate::utils::error::Result<Option<MemHarvest>>,
|
||||
) {
|
||||
use futures::join;
|
||||
|
||||
if !actually_get {
|
||||
(Ok(None), Ok(None))
|
||||
(Ok(None), Ok(None), Ok(None))
|
||||
} else {
|
||||
join!(get_ram_data(), get_swap_data())
|
||||
join!(get_ram_data(), get_swap_data(), get_arc_data())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,3 +169,81 @@ pub async fn get_swap_data() -> crate::utils::error::Result<Option<MemHarvest>>
|
|||
},
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn get_arc_data() -> crate::utils::error::Result<Option<MemHarvest>> {
|
||||
#[cfg(not(feature = "zfs"))]
|
||||
let (mem_total_in_kib, mem_used_in_kib) = (0, 0);
|
||||
|
||||
#[cfg(feature = "zfs")]
|
||||
let (mem_total_in_kib, mem_used_in_kib) = {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let mut mem_arc = 0;
|
||||
let mut mem_total = 0;
|
||||
use smol::fs::read_to_string;
|
||||
let arcinfo = read_to_string("/proc/spl/kstat/zfs/arcstats").await?;
|
||||
for line in arcinfo.lines() {
|
||||
if let Some((label, value)) = line.split_once(' ') {
|
||||
let to_write = match label {
|
||||
"size" => &mut mem_arc,
|
||||
"memory_all_bytes" => &mut mem_total,
|
||||
_ => {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let mut zfs_keys_read: u8 = 0;
|
||||
const ZFS_KEYS_NEEDED: u8 = 2;
|
||||
if let Some((_type, number)) = value.trim_start().rsplit_once(' ') {
|
||||
// Parse the value, remember it's in bytes!
|
||||
if let Ok(number) = number.parse::<u64>() {
|
||||
*to_write = number;
|
||||
// We only need a few keys, so we can bail early.
|
||||
zfs_keys_read += 1;
|
||||
if zfs_keys_read == ZFS_KEYS_NEEDED {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
(mem_total / 1024, mem_arc / 1024)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
{
|
||||
use sysctl::Sysctl;
|
||||
if let (Ok(mem_arc_value), Ok(mem_sys_value)) = (
|
||||
sysctl::Ctl::new("kstat.zfs.misc.arcstats.size"),
|
||||
sysctl::Ctl::new("hw.physmem"),
|
||||
) {
|
||||
if let (Ok(sysctl::CtlValue::U64(arc)), Ok(sysctl::CtlValue::Ulong(mem))) =
|
||||
(mem_arc_value.value(), mem_sys_value.value())
|
||||
{
|
||||
(mem / 1024, arc / 1024)
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
(0, 0)
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
(0, 0)
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -8,13 +8,14 @@ pub async fn get_mem_data(
|
|||
) -> (
|
||||
crate::utils::error::Result<Option<MemHarvest>>,
|
||||
crate::utils::error::Result<Option<MemHarvest>>,
|
||||
crate::utils::error::Result<Option<MemHarvest>>,
|
||||
) {
|
||||
use futures::join;
|
||||
|
||||
if !actually_get {
|
||||
(Ok(None), Ok(None))
|
||||
(Ok(None), Ok(None), Ok(None))
|
||||
} else {
|
||||
join!(get_ram_data(sys), get_swap_data(sys))
|
||||
join!(get_ram_data(sys), get_swap_data(sys), get_arc_data())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,3 +46,39 @@ pub async fn get_swap_data(sys: &System) -> crate::utils::error::Result<Option<M
|
|||
},
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn get_arc_data() -> crate::utils::error::Result<Option<MemHarvest>> {
|
||||
#[cfg(not(feature = "zfs"))]
|
||||
let (mem_total_in_kib, mem_used_in_kib) = (0, 0);
|
||||
|
||||
#[cfg(feature = "zfs")]
|
||||
let (mem_total_in_kib, mem_used_in_kib) = {
|
||||
#[cfg(target_os = "freebsd")]
|
||||
{
|
||||
use sysctl::Sysctl;
|
||||
if let (Ok(mem_arc_value), Ok(mem_sys_value)) = (
|
||||
sysctl::Ctl::new("kstat.zfs.misc.arcstats.size"),
|
||||
sysctl::Ctl::new("hw.physmem"),
|
||||
) {
|
||||
if let (Ok(sysctl::CtlValue::U64(arc)), Ok(sysctl::CtlValue::Ulong(mem))) =
|
||||
(mem_arc_value.value(), mem_sys_value.value())
|
||||
{
|
||||
(mem / 1024, arc / 1024)
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
}
|
||||
};
|
||||
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)
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -191,11 +191,21 @@ fn main() -> Result<()> {
|
|||
convert_mem_data_points(&app.data_collection);
|
||||
app.converted_data.swap_data =
|
||||
convert_swap_data_points(&app.data_collection);
|
||||
#[cfg(feature = "zfs")]
|
||||
{
|
||||
app.converted_data.arc_data =
|
||||
convert_arc_data_points(&app.data_collection);
|
||||
}
|
||||
let (memory_labels, swap_labels) =
|
||||
convert_mem_labels(&app.data_collection);
|
||||
|
||||
app.converted_data.mem_labels = memory_labels;
|
||||
app.converted_data.swap_labels = swap_labels;
|
||||
#[cfg(feature = "zfs")]
|
||||
{
|
||||
let arc_labels = convert_arc_labels(&app.data_collection);
|
||||
app.converted_data.arc_labels = arc_labels;
|
||||
}
|
||||
}
|
||||
|
||||
if app.used_widgets.use_cpu {
|
||||
|
|
|
@ -502,12 +502,26 @@ impl Painter {
|
|||
}
|
||||
};
|
||||
|
||||
let mut mem_rows = 0;
|
||||
|
||||
#[cfg(feature = "zfs")]
|
||||
{
|
||||
let arc_data: &[(f64, f64)] = &app_state.converted_data.arc_data;
|
||||
if let Some(arc) = arc_data.last() {
|
||||
if arc.1 != 0.0 {
|
||||
mem_rows += 1; // add row for arc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mem_rows += 2; // add rows for SWAP and MEM
|
||||
|
||||
let vertical_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.margin(0)
|
||||
.constraints([
|
||||
Constraint::Length(cpu_height),
|
||||
Constraint::Length(2),
|
||||
Constraint::Length(mem_rows),
|
||||
Constraint::Length(2),
|
||||
Constraint::Min(5),
|
||||
])
|
||||
|
|
|
@ -11,6 +11,7 @@ pub struct CanvasColours {
|
|||
pub table_header_style: Style,
|
||||
pub ram_style: Style,
|
||||
pub swap_style: Style,
|
||||
pub arc_style: Style,
|
||||
pub rx_style: Style,
|
||||
pub tx_style: Style,
|
||||
pub total_rx_style: Style,
|
||||
|
@ -43,6 +44,7 @@ impl Default for CanvasColours {
|
|||
table_header_style: Style::default().fg(STANDARD_HIGHLIGHT_COLOUR),
|
||||
ram_style: Style::default().fg(STANDARD_FIRST_COLOUR),
|
||||
swap_style: Style::default().fg(STANDARD_SECOND_COLOUR),
|
||||
arc_style: Style::default().fg(STANDARD_THIRD_COLOUR),
|
||||
rx_style: Style::default().fg(STANDARD_FIRST_COLOUR),
|
||||
tx_style: Style::default().fg(STANDARD_SECOND_COLOUR),
|
||||
total_rx_style: Style::default().fg(STANDARD_THIRD_COLOUR),
|
||||
|
@ -117,6 +119,11 @@ impl CanvasColours {
|
|||
.context("Update 'swap_color' in your config file..")?;
|
||||
}
|
||||
|
||||
if let Some(arc_color) = &colours.arc_color {
|
||||
self.set_arc_colour(arc_color)
|
||||
.context("Update 'arc_color' in your config file..")?;
|
||||
}
|
||||
|
||||
if let Some(rx_color) = &colours.rx_color {
|
||||
self.set_rx_colour(rx_color)
|
||||
.context("Update 'rx_color' in your config file..")?;
|
||||
|
@ -220,6 +227,11 @@ impl CanvasColours {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_arc_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.arc_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_rx_colour(&mut self, colour: &str) -> error::Result<()> {
|
||||
self.rx_style = get_style_from_config(colour)?;
|
||||
Ok(())
|
||||
|
|
|
@ -105,6 +105,41 @@ impl Painter {
|
|||
let mem_text = vec![
|
||||
Spans::from(Span::styled(mem_label, self.colours.ram_style)),
|
||||
Spans::from(Span::styled(swap_label, self.colours.swap_style)),
|
||||
#[cfg(feature = "zfs")]
|
||||
{
|
||||
let arc_data: &[(f64, f64)] = &app_state.converted_data.arc_data;
|
||||
let arc_use_percentage = if let Some(arc) = arc_data.last() {
|
||||
arc.1
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
let trimmed_arc_frac = if let Some((_label_percent, label_frac)) =
|
||||
&app_state.converted_data.arc_labels
|
||||
{
|
||||
label_frac.trim()
|
||||
} else {
|
||||
EMPTY_MEMORY_FRAC_STRING
|
||||
};
|
||||
let arc_bar_length = usize::from(draw_loc.width.saturating_sub(7))
|
||||
.saturating_sub(trimmed_arc_frac.len());
|
||||
let num_bars_arc = calculate_basic_use_bars(arc_use_percentage, arc_bar_length);
|
||||
let arc_label = if app_state.basic_mode_use_percent {
|
||||
format!(
|
||||
"ARC[{}{}{:3.0}%]",
|
||||
"|".repeat(num_bars_arc),
|
||||
" ".repeat(arc_bar_length - num_bars_arc + trimmed_arc_frac.len() - 4),
|
||||
arc_use_percentage.round()
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"ARC[{}{}{}]",
|
||||
"|".repeat(num_bars_arc),
|
||||
" ".repeat(arc_bar_length - num_bars_arc),
|
||||
trimmed_arc_frac
|
||||
)
|
||||
};
|
||||
Spans::from(Span::styled(arc_label, self.colours.arc_style))
|
||||
},
|
||||
];
|
||||
|
||||
f.render_widget(
|
||||
|
|
|
@ -29,7 +29,20 @@ impl Painter {
|
|||
draw_loc,
|
||||
);
|
||||
let points = {
|
||||
let mut points = Vec::with_capacity(2);
|
||||
let mut size = 0;
|
||||
#[cfg(feature = "zfs")]
|
||||
{
|
||||
let arc_data: &[(f64, f64)] = &app_state.converted_data.arc_data;
|
||||
if let Some(arc) = arc_data.last() {
|
||||
if arc.1 != 0.0 {
|
||||
size += 1; // add capacity for ARC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size += 2; // add capacity for RAM and SWP
|
||||
|
||||
let mut points = Vec::with_capacity(size);
|
||||
if let Some((label_percent, label_frac)) = &app_state.converted_data.mem_labels {
|
||||
let mem_label = format!("RAM:{}{}", label_percent, label_frac);
|
||||
points.push(GraphData {
|
||||
|
@ -46,6 +59,20 @@ impl Painter {
|
|||
name: Some(swap_label.into()),
|
||||
});
|
||||
}
|
||||
#[cfg(feature = "zfs")]
|
||||
if let Some((label_percent, label_frac)) = &app_state.converted_data.arc_labels {
|
||||
let arc_data: &[(f64, f64)] = &app_state.converted_data.arc_data;
|
||||
if let Some(arc) = arc_data.last() {
|
||||
if arc.1 != 0.0 {
|
||||
let arc_label = format!("ARC:{}{}", label_percent, label_frac);
|
||||
points.push(GraphData {
|
||||
points: &app_state.converted_data.arc_data,
|
||||
style: self.colours.arc_style,
|
||||
name: Some(arc_label.into()),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
points
|
||||
};
|
||||
|
|
|
@ -40,6 +40,7 @@ pub static DEFAULT_LIGHT_MODE_COLOUR_PALETTE: Lazy<ConfigColours> = Lazy::new(||
|
|||
disabled_text_color: Some("gray".to_string()),
|
||||
ram_color: Some("blue".to_string()),
|
||||
swap_color: Some("red".to_string()),
|
||||
arc_color: Some("LightBlue".to_string()),
|
||||
rx_color: Some("blue".to_string()),
|
||||
tx_color: Some("red".to_string()),
|
||||
rx_total_color: Some("LightBlue".to_string()),
|
||||
|
@ -84,6 +85,7 @@ pub static GRUVBOX_COLOUR_PALETTE: Lazy<ConfigColours> = Lazy::new(|| ConfigColo
|
|||
]),
|
||||
ram_color: Some("#8ec07c".to_string()),
|
||||
swap_color: Some("#fabd2f".to_string()),
|
||||
arc_color: Some("#689d6a".to_string()),
|
||||
rx_color: Some("#8ec07c".to_string()),
|
||||
tx_color: Some("#fabd2f".to_string()),
|
||||
rx_total_color: Some("#689d6a".to_string()),
|
||||
|
@ -129,6 +131,7 @@ pub static GRUVBOX_LIGHT_COLOUR_PALETTE: Lazy<ConfigColours> = Lazy::new(|| Conf
|
|||
]),
|
||||
ram_color: Some("#427b58".to_string()),
|
||||
swap_color: Some("#cc241d".to_string()),
|
||||
arc_color: Some("#689d6a".to_string()),
|
||||
rx_color: Some("#427b58".to_string()),
|
||||
tx_color: Some("#cc241d".to_string()),
|
||||
rx_total_color: Some("#689d6a".to_string()),
|
||||
|
@ -162,6 +165,7 @@ pub static NORD_COLOUR_PALETTE: Lazy<ConfigColours> = Lazy::new(|| ConfigColours
|
|||
]),
|
||||
ram_color: Some("#88c0d0".to_string()),
|
||||
swap_color: Some("#d08770".to_string()),
|
||||
arc_color: Some("#5e81ac".to_string()),
|
||||
rx_color: Some("#88c0d0".to_string()),
|
||||
tx_color: Some("#d08770".to_string()),
|
||||
rx_total_color: Some("#5e81ac".to_string()),
|
||||
|
@ -195,6 +199,7 @@ pub static NORD_LIGHT_COLOUR_PALETTE: Lazy<ConfigColours> = Lazy::new(|| ConfigC
|
|||
]),
|
||||
ram_color: Some("#81a1c1".to_string()),
|
||||
swap_color: Some("#d08770".to_string()),
|
||||
arc_color: Some("#5e81ac".to_string()),
|
||||
rx_color: Some("#81a1c1".to_string()),
|
||||
tx_color: Some("#d08770".to_string()),
|
||||
rx_total_color: Some("#5e81ac".to_string()),
|
||||
|
@ -513,6 +518,8 @@ pub const CONFIG_TEXT: &str = r##"# This is a default config file for bottom. A
|
|||
#ram_color="LightMagenta"
|
||||
# Represents the colour SWAP will use in the memory legend and graph.
|
||||
#swap_color="LightYellow"
|
||||
# Represents the colour ARC will use in the memory legend and graph.
|
||||
#arc_color="LightCyan"
|
||||
# Represents the colour rx will use in the network legend and graph.
|
||||
#rx_color="LightCyan"
|
||||
# Represents the colour tx will use in the network legend and graph.
|
||||
|
|
|
@ -89,9 +89,11 @@ pub struct ConvertedData {
|
|||
|
||||
pub mem_labels: Option<(String, String)>,
|
||||
pub swap_labels: Option<(String, String)>,
|
||||
pub arc_labels: Option<(String, String)>,
|
||||
|
||||
pub mem_data: Vec<Point>, // TODO: Switch this and all data points over to a better data structure...
|
||||
pub swap_data: Vec<Point>,
|
||||
pub arc_data: Vec<Point>,
|
||||
pub load_avg_data: [f32; 3],
|
||||
pub cpu_data: Vec<ConvertedCpuData>,
|
||||
pub battery_data: Vec<ConvertedBatteryData>,
|
||||
|
@ -654,6 +656,73 @@ pub fn convert_battery_harvest(
|
|||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(feature = "zfs")]
|
||||
pub fn convert_arc_labels(current_data: &data_farmer::DataCollection) -> Option<(String, String)> {
|
||||
/// 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) {
|
||||
if mem_total_kib < 1024 {
|
||||
// Stay with KiB
|
||||
("KiB", 1.0)
|
||||
} else if mem_total_kib < MEBI_LIMIT {
|
||||
// Use MiB
|
||||
("MiB", KIBI_LIMIT_F64)
|
||||
} else if mem_total_kib < GIBI_LIMIT {
|
||||
// Use GiB
|
||||
("GiB", MEBI_LIMIT_F64)
|
||||
} else {
|
||||
// Use TiB
|
||||
("TiB", GIBI_LIMIT_F64)
|
||||
}
|
||||
}
|
||||
|
||||
if current_data.arc_harvest.mem_total_in_kib > 0 {
|
||||
Some((
|
||||
format!(
|
||||
"{:3.0}%",
|
||||
current_data.arc_harvest.use_percent.unwrap_or(0.0)
|
||||
),
|
||||
{
|
||||
let (unit, denominator) = return_unit_and_denominator_for_mem_kib(
|
||||
current_data.arc_harvest.mem_total_in_kib,
|
||||
);
|
||||
|
||||
format!(
|
||||
" {:.1}{}/{:.1}{}",
|
||||
current_data.arc_harvest.mem_used_in_kib as f64 / denominator,
|
||||
unit,
|
||||
(current_data.arc_harvest.mem_total_in_kib as f64 / denominator),
|
||||
unit
|
||||
)
|
||||
},
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "zfs")]
|
||||
pub fn convert_arc_data_points(current_data: &data_farmer::DataCollection) -> Vec<Point> {
|
||||
let mut result: Vec<Point> = Vec::new();
|
||||
let current_time = if let Some(frozen_instant) = current_data.frozen_instant {
|
||||
frozen_instant
|
||||
} else {
|
||||
current_data.current_instant
|
||||
};
|
||||
|
||||
for (time, data) in ¤t_data.timed_data_vec {
|
||||
if let Some(arc_data) = data.arc_data {
|
||||
let time_from_start: f64 =
|
||||
(current_time.duration_since(*time).as_millis() as f64).floor();
|
||||
result.push((-time_from_start, arc_data));
|
||||
if *time == current_time {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
|
|
@ -339,6 +339,10 @@ pub fn update_data(app: &mut App) {
|
|||
if app.mem_state.force_update.is_some() {
|
||||
app.converted_data.mem_data = convert_mem_data_points(&app.data_collection);
|
||||
app.converted_data.swap_data = convert_swap_data_points(&app.data_collection);
|
||||
#[cfg(feature = "zfs")]
|
||||
{
|
||||
app.converted_data.arc_data = convert_arc_data_points(&app.data_collection);
|
||||
}
|
||||
app.mem_state.force_update = None;
|
||||
}
|
||||
|
||||
|
|
|
@ -199,6 +199,7 @@ pub struct ConfigColours {
|
|||
pub cpu_core_colors: Option<Vec<String>>,
|
||||
pub ram_color: Option<String>,
|
||||
pub swap_color: Option<String>,
|
||||
pub arc_color: Option<String>,
|
||||
pub rx_color: Option<String>,
|
||||
pub tx_color: Option<String>,
|
||||
pub rx_total_color: Option<String>, // These only affect basic mode.
|
||||
|
|
Loading…
Reference in a new issue