It seems to somewhat work on my machine
This commit is contained in:
parent
7099e9d7df
commit
bb44f85e42
35
Cargo.lock
generated
35
Cargo.lock
generated
@ -2,6 +2,15 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ansi_term"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
@ -140,6 +149,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humansize"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.7.0"
|
version = "1.7.0"
|
||||||
@ -217,6 +232,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "output_vt100"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-error"
|
name = "proc-macro-error"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@ -254,7 +278,10 @@ dependencies = [
|
|||||||
name = "pumo-system-info"
|
name = "pumo-system-info"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ansi_term",
|
||||||
"clap",
|
"clap",
|
||||||
|
"humansize",
|
||||||
|
"output_vt100",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
@ -308,18 +335,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.130"
|
version = "1.0.131"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.130"
|
version = "1.0.131"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
checksum = "b710a83c4e0dff6a3d511946b95274ad9ca9e5d3ae497b63fda866ac955358d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -10,7 +10,10 @@ publish = false
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sysinfo = "0.21"
|
sysinfo = "0.21.2"
|
||||||
clap = { version = "3.0.0-rc.0", default-features = false, features = ["std", "derive", "color"] }
|
clap = { version = "3.0.0-rc.0", default-features = false, features = ["std", "derive", "color"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0.131", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0.72"
|
||||||
|
output_vt100 = "0.1.2"
|
||||||
|
ansi_term = "0.12.1"
|
||||||
|
humansize = "1.1.1"
|
||||||
|
@ -24,7 +24,7 @@ conditions; see the GPL-3.0 license or newer
|
|||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[clap(name="Pumo System Info",about,version,author,after_long_help=AFTER_HELP)]
|
#[clap(name="Pumo System Info",about,version,author,after_long_help=AFTER_HELP)]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
#[clap(short, long)]
|
#[clap(short, long, help="JSON output")]
|
||||||
pub json: bool,
|
pub json: bool,
|
||||||
|
|
||||||
#[clap(short, long, default_value_t = 75)]
|
#[clap(short, long, default_value_t = 75)]
|
||||||
@ -33,6 +33,9 @@ pub struct Args {
|
|||||||
#[clap(short, long, default_value_t = 90)]
|
#[clap(short, long, default_value_t = 90)]
|
||||||
pub critical_level: u8,
|
pub critical_level: u8,
|
||||||
|
|
||||||
#[clap(short = 'W', long, default_value_t = 72)]
|
#[clap(short = 'W', long, default_value_t = 72, help="Width of the console output")]
|
||||||
pub width: u8,
|
pub width: usize,
|
||||||
|
|
||||||
|
#[clap(short, long, help="Display seconds in uptime")]
|
||||||
|
pub seconds: bool,
|
||||||
}
|
}
|
||||||
|
155
src/cli.rs
155
src/cli.rs
@ -14,8 +14,159 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
mod sysinfo;
|
|
||||||
|
|
||||||
pub fn print_cli() {
|
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);
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,18 @@
|
|||||||
|
|
||||||
mod sysinfo;
|
mod sysinfo;
|
||||||
mod args;
|
mod args;
|
||||||
|
mod cli;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
output_vt100::init();
|
||||||
|
|
||||||
let args = args::Args::parse();
|
let args = args::Args::parse();
|
||||||
let machine = sysinfo::Machine::new();
|
let machine = sysinfo::Machine::new();
|
||||||
if args.json {
|
if args.json {
|
||||||
println!("{}", serde_json::to_string(&machine).unwrap());
|
println!("{}", serde_json::to_string(&machine).unwrap());
|
||||||
} else {
|
} else {
|
||||||
|
cli::print_cli(machine, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,27 +18,35 @@ use serde::Serialize;
|
|||||||
use sysinfo::{System, SystemExt, DiskExt};
|
use sysinfo::{System, SystemExt, DiskExt};
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
struct Memory {
|
pub struct Memory {
|
||||||
name: String,
|
pub name: String,
|
||||||
size: u64,
|
pub size: u64,
|
||||||
available: u64
|
pub available: u64
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Memory {
|
impl Memory {
|
||||||
pub fn new(name: String, size: u64, available: u64) -> Self {
|
pub fn new(name: String, size: u64, available: u64) -> Self {
|
||||||
Self { name, size, available }
|
Self { name, size, available }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn used(&self) -> u64 {
|
||||||
|
self.size - self.available
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn percentage(&self) -> f32 {
|
||||||
|
self.used() as f32 / self.size as f32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Machine {
|
pub struct Machine {
|
||||||
os: String,
|
pub os: String,
|
||||||
kernel: String,
|
pub kernel: String,
|
||||||
hostname: String,
|
pub hostname: String,
|
||||||
uptime: u64,
|
pub uptime: u64,
|
||||||
ram: Memory,
|
pub ram: Memory,
|
||||||
swap: Memory,
|
pub swap: Memory,
|
||||||
disks: Vec<Memory>,
|
pub disks: Vec<Memory>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Machine {
|
impl Machine {
|
||||||
@ -50,14 +58,14 @@ impl Machine {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
Memory::new(
|
Memory::new(
|
||||||
x.name().to_str().unwrap().to_string(),
|
x.mount_point().to_str().unwrap().to_string(),
|
||||||
x.total_space(),
|
x.total_space(),
|
||||||
x.available_space(),
|
x.available_space(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<Memory>>();
|
.collect::<Vec<Memory>>();
|
||||||
let ram = Memory::new("RAM".into(), sys.available_memory(), sys.available_memory());
|
let ram = Memory::new("RAM".into(), sys.total_memory() * 1000, sys.available_memory() * 1000);
|
||||||
let swap = Memory::new("Swap".into(), sys.total_swap(), sys.free_swap());
|
let swap = Memory::new("Swap".into(), sys.total_swap() * 1000, sys.free_swap() * 1000);
|
||||||
Self {
|
Self {
|
||||||
os: sys.name().unwrap(),
|
os: sys.name().unwrap(),
|
||||||
kernel: sys.kernel_version().unwrap(),
|
kernel: sys.kernel_version().unwrap(),
|
||||||
|
Loading…
Reference in New Issue
Block a user