pumo-system-info/src/cli.rs

173 lines
4.7 KiB
Rust

// Gather and display system information
// Copyright (C) 2021 Lucien Cartier-Tilet <lucien@phundrak.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::sysinfo::{Machine, Memory};
use crate::args::Args;
fn get_uptime(mut uptime: u64, seconds: bool) -> String {
let mut uptime_str = String::new();
let minute_length = 60_u64;
let hour_length = minute_length * 60;
let day_length = hour_length * 24;
let days = uptime / day_length;
uptime %= day_length;
if days > 0 {
uptime_str.push_str(format!("{} days ", days).as_str());
}
let hours = uptime / hour_length;
uptime %= hour_length;
if days > 0 || hours > 0 {
uptime_str.push_str(format!("{} hours ", hours).as_str());
}
let minutes = uptime / minute_length;
uptime_str.push_str(format!("{} minutes", minutes).as_str());
if seconds {
uptime %= minute_length;
uptime_str.push_str(format!(" {} seconds", uptime).as_str());
}
uptime_str
}
fn get_name_max_width(disks: &[Memory]) -> usize {
disks
.iter()
.max_by(|x, y| x.name.len().cmp(&y.name.len()))
.unwrap()
.name
.len()
}
fn print_ramp(
memory: &Memory,
left_margin: usize,
total_width: usize,
) -> String {
use ansi_term::{Color, Style};
use humansize::{FileSize, file_size_opts as foptions};
let humansize_option = foptions::FileSizeOpts {
decimal_places: 1,
decimal_zeroes: 1,
space: false,
..foptions::CONVENTIONAL
};
let ramp_length = total_width - left_margin - 28;
let full = (ramp_length as f32 * memory.percentage()) as usize;
let empty = ramp_length - full;
let percentage = memory.percentage() * 100_f32;
let warning = percentage >= 75_f32;
let critical = percentage >= 90_f32;
let fg = if critical {
Color::Red
} else if warning {
Color::Yellow
} else {
Color::Green
};
let mut ramp = String::from("[");
for _ in 0..full {
ramp.push_str(Style::new().fg(fg).paint("=").to_string().as_str());
}
for _ in 0..empty {
ramp.push('=');
}
ramp.push_str(
format!(
"] {:>6} / {:>6} ",
memory
.used()
.file_size(&humansize_option)
.unwrap()
.replace("B", ""),
memory
.size
.file_size(&humansize_option)
.unwrap()
.replace("B", "")
)
.as_str(),
);
let percentage_str = Style::new().fg(fg).paint(format!("{:3.0}%", percentage)).to_string();
ramp.push_str(format!("({}%)", percentage_str).as_str());
ramp
}
pub fn print_cli(machine: Machine, args: Args) {
let width = args.width;
let mut separator = String::from("");
for _ in 0..width {
separator.push('=');
}
let left_max_width = "Hostname".len().max(get_name_max_width(&machine.disks));
let uptime = get_uptime(machine.uptime, args.seconds);
let right_width = machine.kernel.len().max(uptime.len()) + 3;
println!("{}", separator);
println!("{0:.<1$}: {2}{3:>4$}.: {5}",
"OS",
left_max_width,
machine.os,
"Kernel",
width as usize - (left_max_width + 2 + machine.os.len()) - right_width,
machine.kernel
);
println!("{0:.<1$}: {2}{3:>4$}.: {5}",
"Hostname",
left_max_width,
machine.hostname,
"Uptime",
width as usize - (left_max_width + 2 + machine.hostname.len()) - right_width,
uptime
);
println!("{0:.<1$}: {2}",
"Mem",
left_max_width,
print_ramp(&machine.ram, left_max_width, width)
);
println!("{0:.<1$}: {2}",
"Swap",
left_max_width,
print_ramp(&machine.swap, left_max_width, width)
);
for disk in machine.disks {
println!("{0:.<1$}: {2}",
disk.name,
left_max_width,
print_ramp(&disk, left_max_width, width)
);
}
println!("{}", separator);
}