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.
 | 
			
		||||
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]]
 | 
			
		||||
name = "atty"
 | 
			
		||||
version = "0.2.14"
 | 
			
		||||
@ -140,6 +149,12 @@ dependencies = [
 | 
			
		||||
 "libc",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "humansize"
 | 
			
		||||
version = "1.1.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "indexmap"
 | 
			
		||||
version = "1.7.0"
 | 
			
		||||
@ -217,6 +232,15 @@ dependencies = [
 | 
			
		||||
 "memchr",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "output_vt100"
 | 
			
		||||
version = "0.1.2"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "winapi",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "proc-macro-error"
 | 
			
		||||
version = "1.0.4"
 | 
			
		||||
@ -254,7 +278,10 @@ dependencies = [
 | 
			
		||||
name = "pumo-system-info"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "ansi_term",
 | 
			
		||||
 "clap",
 | 
			
		||||
 "humansize",
 | 
			
		||||
 "output_vt100",
 | 
			
		||||
 "serde",
 | 
			
		||||
 "serde_json",
 | 
			
		||||
 "sysinfo",
 | 
			
		||||
@ -308,18 +335,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "serde"
 | 
			
		||||
version = "1.0.130"
 | 
			
		||||
version = "1.0.131"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
 | 
			
		||||
checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "serde_derive",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "serde_derive"
 | 
			
		||||
version = "1.0.130"
 | 
			
		||||
version = "1.0.131"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
 | 
			
		||||
checksum = "b710a83c4e0dff6a3d511946b95274ad9ca9e5d3ae497b63fda866ac955358d2"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,10 @@ publish = false
 | 
			
		||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
sysinfo = "0.21"
 | 
			
		||||
sysinfo = "0.21.2"
 | 
			
		||||
clap = { version = "3.0.0-rc.0", default-features = false, features = ["std", "derive", "color"] }
 | 
			
		||||
serde = { version = "1.0", features = ["derive"] }
 | 
			
		||||
serde_json = "1.0"
 | 
			
		||||
serde = { version = "1.0.131", features = ["derive"] }
 | 
			
		||||
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)]
 | 
			
		||||
#[clap(name="Pumo System Info",about,version,author,after_long_help=AFTER_HELP)]
 | 
			
		||||
pub struct Args {
 | 
			
		||||
    #[clap(short, long)]
 | 
			
		||||
    #[clap(short, long, help="JSON output")]
 | 
			
		||||
    pub json: bool,
 | 
			
		||||
 | 
			
		||||
    #[clap(short, long, default_value_t = 75)]
 | 
			
		||||
@ -33,6 +33,9 @@ pub struct Args {
 | 
			
		||||
    #[clap(short, long, default_value_t = 90)]
 | 
			
		||||
    pub critical_level: u8,
 | 
			
		||||
 | 
			
		||||
    #[clap(short = 'W', long, default_value_t = 72)]
 | 
			
		||||
    pub width: u8,
 | 
			
		||||
    #[clap(short = 'W', long, default_value_t = 72, help="Width of the console output")]
 | 
			
		||||
    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
 | 
			
		||||
// 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 args;
 | 
			
		||||
mod cli;
 | 
			
		||||
 | 
			
		||||
use clap::Parser;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    output_vt100::init();
 | 
			
		||||
 | 
			
		||||
    let args = args::Args::parse();
 | 
			
		||||
    let machine = sysinfo::Machine::new();
 | 
			
		||||
    if args.json {
 | 
			
		||||
        println!("{}", serde_json::to_string(&machine).unwrap());
 | 
			
		||||
    } else {
 | 
			
		||||
        cli::print_cli(machine, args);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -18,27 +18,35 @@ use serde::Serialize;
 | 
			
		||||
use sysinfo::{System, SystemExt, DiskExt};
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Serialize)]
 | 
			
		||||
struct Memory {
 | 
			
		||||
    name: String,
 | 
			
		||||
    size: u64,
 | 
			
		||||
    available: u64
 | 
			
		||||
pub struct Memory {
 | 
			
		||||
    pub name: String,
 | 
			
		||||
    pub size: u64,
 | 
			
		||||
    pub available: u64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Memory {
 | 
			
		||||
    pub fn new(name: String, size: u64, available: u64) -> Self {
 | 
			
		||||
        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)]
 | 
			
		||||
pub struct Machine {
 | 
			
		||||
    os: String,
 | 
			
		||||
    kernel: String,
 | 
			
		||||
    hostname: String,
 | 
			
		||||
    uptime: u64,
 | 
			
		||||
    ram: Memory,
 | 
			
		||||
    swap: Memory,
 | 
			
		||||
    disks: Vec<Memory>,
 | 
			
		||||
    pub os: String,
 | 
			
		||||
    pub kernel: String,
 | 
			
		||||
    pub hostname: String,
 | 
			
		||||
    pub uptime: u64,
 | 
			
		||||
    pub ram: Memory,
 | 
			
		||||
    pub swap: Memory,
 | 
			
		||||
    pub disks: Vec<Memory>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Machine {
 | 
			
		||||
@ -50,14 +58,14 @@ impl Machine {
 | 
			
		||||
            .iter()
 | 
			
		||||
            .map(|x| {
 | 
			
		||||
                Memory::new(
 | 
			
		||||
                    x.name().to_str().unwrap().to_string(),
 | 
			
		||||
                    x.mount_point().to_str().unwrap().to_string(),
 | 
			
		||||
                    x.total_space(),
 | 
			
		||||
                    x.available_space(),
 | 
			
		||||
                )
 | 
			
		||||
            })
 | 
			
		||||
            .collect::<Vec<Memory>>();
 | 
			
		||||
        let ram = Memory::new("RAM".into(), sys.available_memory(), sys.available_memory());
 | 
			
		||||
        let swap = Memory::new("Swap".into(), sys.total_swap(), sys.free_swap());
 | 
			
		||||
        let ram = Memory::new("RAM".into(), sys.total_memory() * 1000, sys.available_memory() * 1000);
 | 
			
		||||
        let swap = Memory::new("Swap".into(), sys.total_swap() * 1000, sys.free_swap() * 1000);
 | 
			
		||||
        Self {
 | 
			
		||||
            os: sys.name().unwrap(),
 | 
			
		||||
            kernel: sys.kernel_version().unwrap(),
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user