diff --git a/src/app.rs b/src/app.rs index 8b09d343..2ac16ad9 100644 --- a/src/app.rs +++ b/src/app.rs @@ -50,6 +50,7 @@ pub struct Data { pub struct DataState { pub data : Data, + first_run : bool, sys : System, stale_max_seconds : u64, prev_pid_stats : HashMap, // TODO: Purge list? @@ -62,6 +63,7 @@ impl Default for DataState { fn default() -> Self { DataState { data : Data::default(), + first_run : true, sys : System::new(), stale_max_seconds : 60, prev_pid_stats : HashMap::new(), @@ -108,6 +110,11 @@ impl DataState { push_if_valid(&disks::get_io_usage_list(true).await, &mut self.data.list_of_physical_io); set_if_valid(&temperature::get_temperature_data().await, &mut self.data.list_of_temperature_sensor); + if self.first_run { + self.data = Data::default(); + self.first_run = false; + } + // Filter out stale timed entries // TODO: ideally make this a generic function! let current_instant = std::time::Instant::now(); diff --git a/src/canvas.rs b/src/canvas.rs index fc326b75..d4e42932 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -1,7 +1,7 @@ use std::io; use tui::{ layout::{Constraint, Direction, Layout}, - style::{Color, Style}, + style::{Color, Modifier, Style}, widgets::{Axis, Block, Borders, Chart, Dataset, Marker, Row, Table, Widget}, Terminal, }; @@ -46,7 +46,7 @@ pub fn draw_data(terminal : &mut Terminal, canvas_ let middle_chunks = Layout::default() .direction(Direction::Horizontal) .margin(0) - .constraints([Constraint::Percentage(70), Constraint::Percentage(30)].as_ref()) + .constraints([Constraint::Percentage(75), Constraint::Percentage(25)].as_ref()) .split(vertical_chunks[1]); let _middle_divided_chunk_1 = Layout::default() .direction(Direction::Vertical) @@ -84,7 +84,7 @@ pub fn draw_data(terminal : &mut Terminal, canvas_ // CPU usage graph { - let x_axis : Axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 60.0]); + let x_axis : Axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 600_000.0]); let y_axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 100.0]).labels(&["0.0", "50.0", "100.0"]); let mut dataset_vector : Vec = Vec::new(); @@ -92,7 +92,7 @@ pub fn draw_data(terminal : &mut Terminal, canvas_ dataset_vector.push( Dataset::default() .name(&cpu.0) - .marker(Marker::Braille) + .marker(Marker::Dot) .style(Style::default().fg(COLOUR_LIST[i % COLOUR_LIST.len()])) .data(&(cpu.1)), ); @@ -108,8 +108,8 @@ pub fn draw_data(terminal : &mut Terminal, canvas_ //Memory usage graph { - let x_axis : Axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 60.0]); - let y_axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 100.0]).labels(&["0.0", "50.0", "100.0"]); + let x_axis : Axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 600_000.0]); + let y_axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 100.0]).labels(&["0", "50", "100"]); Chart::default() .block(Block::default().title("Memory Usage").borders(Borders::ALL).border_style(border_style)) .x_axis(x_axis) @@ -117,12 +117,12 @@ pub fn draw_data(terminal : &mut Terminal, canvas_ .datasets(&[ Dataset::default() .name(&("MEM :".to_string() + &format!("{:3}%", (canvas_data.mem_data.last().unwrap_or(&(0_f64, 0_f64)).1.round() as u64)))) - .marker(Marker::Braille) + .marker(Marker::Dot) .style(Style::default().fg(Color::LightRed)) .data(&canvas_data.mem_data), Dataset::default() .name(&("SWAP:".to_string() + &format!("{:3}%", (canvas_data.swap_data.last().unwrap_or(&(0_f64, 0_f64)).1.round() as u64)))) - .marker(Marker::Braille) + .marker(Marker::Dot) .style(Style::default().fg(Color::LightGreen)) .data(&canvas_data.swap_data), ]) @@ -142,7 +142,7 @@ pub fn draw_data(terminal : &mut Terminal, canvas_ // Disk usage table Table::new(["Disk", "Mount", "Used", "Total", "Free"].iter(), disk_rows) .block(Block::default().title("Disk Usage").borders(Borders::ALL).border_style(border_style)) - .header_style(Style::default().fg(Color::LightBlue)) + .header_style(Style::default().fg(Color::LightBlue).modifier(Modifier::BOLD)) .widths(&[15, 10, 5, 5, 5]) .render(&mut f, bottom_divided_chunk_1_2[0]); diff --git a/src/main.rs b/src/main.rs index e1e85322..bfb13768 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,7 @@ enum Event { Update(Box), } -const STALE_MAX_SECONDS : u64 = 60; +const STALE_MAX_MILLISECONDS : u64 = 60 * 1000; #[tokio::main] async fn main() -> Result<(), io::Error> { @@ -30,7 +30,7 @@ async fn main() -> Result<(), io::Error> { let mut terminal = Terminal::new(backend)?; let tick_rate_in_milliseconds : u64 = 250; - let update_rate_in_milliseconds : u64 = 1000; // TODO: Must set a check to prevent this from going into negatives! + let update_rate_in_milliseconds : u64 = 500; // TODO: Must set a check to prevent this from going into negatives! let mut app = app::App::new("rustop"); @@ -57,7 +57,7 @@ async fn main() -> Result<(), io::Error> { // Event loop let mut data_state = app::DataState::default(); data_state.init(); - data_state.set_stale_max_seconds(STALE_MAX_SECONDS); + data_state.set_stale_max_seconds(STALE_MAX_MILLISECONDS); data_state.set_temperature_type(app.temperature_type.clone()); { let tx = tx.clone(); @@ -195,15 +195,18 @@ fn update_cpu_data_points(app_data : &app::Data) -> Vec<(String, Vec<(f64, f64)> if !app_data.list_of_cpu_packages.is_empty() { // Initially, populate the cpu_collection. We want to inject elements in between if possible. - let current_time = std::time::Instant::now(); for cpu_num in 1..app_data.list_of_cpu_packages.last().unwrap().cpu_vec.len() { - // 1 to skip total cpu + // TODO: 1 to skip total cpu? Or no? let mut this_cpu_data : Vec<(f64, f64)> = Vec::new(); - for cpu in &app_data.list_of_cpu_packages { - let current_cpu_usage = cpu.cpu_vec[cpu_num].cpu_usage; - this_cpu_data.push((STALE_MAX_SECONDS as f64 - current_time.duration_since(cpu.instant).as_secs_f64().floor(), current_cpu_usage)); + for data in &app_data.list_of_cpu_packages { + let current_time = std::time::Instant::now(); + let current_cpu_usage = data.cpu_vec[cpu_num].cpu_usage; + this_cpu_data.push(( + ((STALE_MAX_MILLISECONDS as f64 - current_time.duration_since(data.instant).as_millis() as f64) * 10_f64).floor(), + current_cpu_usage, + )); } cpu_collection.push(this_cpu_data); @@ -212,7 +215,8 @@ fn update_cpu_data_points(app_data : &app::Data) -> Vec<(String, Vec<(f64, f64)> // Finally, add it all onto the end for (i, data) in cpu_collection.iter().enumerate() { cpu_data_vector.push(( - (&*(app_data.list_of_cpu_packages.last().unwrap().cpu_vec[i].cpu_name)).to_string() + " " + &format!("{:.2}", data.last().unwrap_or(&(0_f64, 0_f64)).1.to_string()), + // + 1 to skip total CPU... + (&*(app_data.list_of_cpu_packages.last().unwrap().cpu_vec[i + 1].cpu_name)).to_string() + " " + &format!("{:3}%", (data.last().unwrap_or(&(0_f64, 0_f64)).1.round() as u64)), data.clone(), )) } @@ -231,13 +235,15 @@ fn update_swap_data_points(app_data : &app::Data) -> Vec<(f64, f64)> { fn convert_mem_data(mem_data : &[app::data_collection::mem::MemData]) -> Vec<(f64, f64)> { let mut result : Vec<(f64, f64)> = Vec::new(); - let current_time = std::time::Instant::now(); for data in mem_data { + let current_time = std::time::Instant::now(); + result.push(( - STALE_MAX_SECONDS as f64 - current_time.duration_since(data.instant).as_secs() as f64, + ((STALE_MAX_MILLISECONDS as f64 - current_time.duration_since(data.instant).as_millis() as f64) * 10_f64).floor(), data.mem_used_in_mb as f64 / data.mem_total_in_mb as f64 * 100_f64, )); + debug!("Pushed: ({}, {})", result.last().unwrap().0, result.last().unwrap().1); } result diff --git a/src/utils/error.rs b/src/utils/error.rs index 1d5c9e9f..411af11f 100644 --- a/src/utils/error.rs +++ b/src/utils/error.rs @@ -1 +1,2 @@ +#[allow(dead_code)] pub struct RustopError {} diff --git a/src/utils/logging.rs b/src/utils/logging.rs index af4cf302..f3afea42 100644 --- a/src/utils/logging.rs +++ b/src/utils/logging.rs @@ -3,7 +3,7 @@ pub fn init_logger() -> Result<(), fern::InitError> { .format(|out, message, record| { out.finish(format_args!( "{}[{}][{}] {}", - chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"), + chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S:%f]"), record.target(), record.level(), message