diff --git a/Cargo.lock b/Cargo.lock index ee971a4..b8b3e46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,6 +152,7 @@ dependencies = [ "log", "log4rs", "nix 0.28.0", + "owo-colors", "procfs", "ratatui", "uzers", @@ -708,6 +709,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "owo-colors" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" + [[package]] name = "parking_lot" version = "0.12.1" diff --git a/Cargo.toml b/Cargo.toml index 67639d4..74f6100 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,9 @@ rust-version = "1.74.1" [[bin]] name = "brt" +[[bin]] +name = "processbar" +path = "src/processbar.rs" [dependencies] crossterm = "0.27.0" @@ -29,6 +32,7 @@ procfs = "0.16.0" uzers = "0.11.3" nix = "0.28.0" humansize = "2.1.3" +owo-colors = "4.0.0" [dev-dependencies.cargo-husky] diff --git a/Makefile.toml b/Makefile.toml index 73170e3..f3f184d 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -36,6 +36,8 @@ toolchain = "nightly" command = "cargo" args = [ "rustdoc", + "--bin", + "brt", "--no-default-features", "--", "-Zunstable-options", diff --git a/src/main.rs b/src/main.rs index a178f46..f77cf2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ use crossterm::{ }; use log::{debug, info}; use procfs::process::Process; +use procfs::{ticks_per_second, Current, Uptime, WithCurrentSystemInfo}; use ratatui::layout::Constraint::Percentage; use ratatui::widgets::block::Position; use ratatui::widgets::{ @@ -26,6 +27,7 @@ use ratatui::{ mod logger; mod model; +mod processbar; const NAME: &str = env!("CARGO_PKG_NAME"); const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -118,6 +120,7 @@ impl App { } } +#[allow(dead_code)] fn get_current_process() -> Process { let me = Process::myself().unwrap(); let resident_mem = get_memory(&me); @@ -126,16 +129,28 @@ fn get_current_process() -> Process { } fn get_memory(process: &Process) -> u64 { - let stat = process.statm().unwrap(); + let statm = process.statm().unwrap(); let page_size = procfs::page_size(); - stat.resident * page_size + statm.resident * page_size +} + +fn get_cpu(process: &Process) -> f64 { + let stat = process.stat().unwrap(); + info!("{}: starttime: {}", process.pid, stat.starttime); + info!("utime: {}", (stat.utime / ticks_per_second()) as f64); + info!("stime: {}", stat.stime / ticks_per_second()); + info!("u+s: {}", (stat.utime + stat.stime) / ticks_per_second()); + + info!("Uptime: {:?}", Uptime::current().unwrap().uptime_duration()); + info!("rss_bytes: {}", stat.rss_bytes().get()); + 0.0 } fn main() -> Result<()> { logger::initialize_logging(); initialize_panic_handler(); + info!("{NAME} ({VERSION}) started."); - get_current_process(); let _cli = Cli::parse(); diff --git a/src/model.rs b/src/model.rs index e8570fa..d0d278c 100644 --- a/src/model.rs +++ b/src/model.rs @@ -76,6 +76,7 @@ pub struct BrtProcess { number_of_threads: i64, user: Option, resident_memory: u64, + cpu: f64, } impl Default for BrtProcess { @@ -88,6 +89,7 @@ impl Default for BrtProcess { number_of_threads: -1, user: None, resident_memory: 0, + cpu: 0.0, } } } @@ -136,6 +138,10 @@ fn create_process(process: &Process) -> Option { // memory let resident_memory = crate::get_memory(process); brt_process.resident_memory = resident_memory; + + // cpu + let cpu = crate::get_cpu(process); + brt_process.cpu = cpu } Err(_e) => { warn!("Stat not found for process {}.", process.pid().to_string()); diff --git a/src/processbar.rs b/src/processbar.rs new file mode 100644 index 0000000..7291857 --- /dev/null +++ b/src/processbar.rs @@ -0,0 +1,47 @@ +use anyhow::{Context, Result}; +use clap::Parser; +use log::debug; +use owo_colors::OwoColorize; +use procfs::process::Process; +use procfs::{page_size, ticks_per_second, Current, Uptime}; + +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Args { + #[arg(long)] + pid: i32, +} + +#[allow(dead_code)] +fn main() -> Result<()> { + let args = Args::parse(); + + let pid = args.pid; + + debug!("Checking pid {}...", pid); + let process = Process::new(pid).with_context(|| format!("Pid {pid} not found."))?; + let stat = process.stat().unwrap(); + + debug!("ticks per second: {}", ticks_per_second()); + debug!("pagesize: {}", page_size()); + let usage = stat.utime / ticks_per_second() + stat.stime / ticks_per_second(); + debug!("usage {} ", usage); + + let uptime = Uptime::current().unwrap().uptime_duration().as_secs(); + debug!("Uptime: {}", uptime); + let starttime = stat.starttime / ticks_per_second(); + debug!("Starttime: {}", starttime); + let runtime = uptime - starttime; + debug!("runtime: {}", runtime); + let percentage = usage * 100 / runtime; + println!( + "{} ({}) has used {}% of the cpu.", + stat.comm.green(), + pid.yellow(), + percentage.red(), + ); + Ok(()) +} + +#[derive(Debug)] +struct ProcessbarError(String);