Hopefully smoothed out curve a bit.

This commit is contained in:
ClementTsang 2019-09-13 16:15:00 -04:00
parent 71ac3313e4
commit a5989ad096
5 changed files with 35 additions and 21 deletions

View File

@ -50,6 +50,7 @@ pub struct Data {
pub struct DataState { pub struct DataState {
pub data : Data, pub data : Data,
first_run : bool,
sys : System, sys : System,
stale_max_seconds : u64, stale_max_seconds : u64,
prev_pid_stats : HashMap<String, f64>, // TODO: Purge list? prev_pid_stats : HashMap<String, f64>, // TODO: Purge list?
@ -62,6 +63,7 @@ impl Default for DataState {
fn default() -> Self { fn default() -> Self {
DataState { DataState {
data : Data::default(), data : Data::default(),
first_run : true,
sys : System::new(), sys : System::new(),
stale_max_seconds : 60, stale_max_seconds : 60,
prev_pid_stats : HashMap::new(), 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); 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); 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 // Filter out stale timed entries
// TODO: ideally make this a generic function! // TODO: ideally make this a generic function!
let current_instant = std::time::Instant::now(); let current_instant = std::time::Instant::now();

View File

@ -1,7 +1,7 @@
use std::io; use std::io;
use tui::{ use tui::{
layout::{Constraint, Direction, Layout}, layout::{Constraint, Direction, Layout},
style::{Color, Style}, style::{Color, Modifier, Style},
widgets::{Axis, Block, Borders, Chart, Dataset, Marker, Row, Table, Widget}, widgets::{Axis, Block, Borders, Chart, Dataset, Marker, Row, Table, Widget},
Terminal, Terminal,
}; };
@ -46,7 +46,7 @@ pub fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, canvas_
let middle_chunks = Layout::default() let middle_chunks = Layout::default()
.direction(Direction::Horizontal) .direction(Direction::Horizontal)
.margin(0) .margin(0)
.constraints([Constraint::Percentage(70), Constraint::Percentage(30)].as_ref()) .constraints([Constraint::Percentage(75), Constraint::Percentage(25)].as_ref())
.split(vertical_chunks[1]); .split(vertical_chunks[1]);
let _middle_divided_chunk_1 = Layout::default() let _middle_divided_chunk_1 = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
@ -84,7 +84,7 @@ pub fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, canvas_
// CPU usage graph // CPU usage graph
{ {
let x_axis : Axis<String> = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 60.0]); let x_axis : Axis<String> = 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 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<Dataset> = Vec::new(); let mut dataset_vector : Vec<Dataset> = Vec::new();
@ -92,7 +92,7 @@ pub fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, canvas_
dataset_vector.push( dataset_vector.push(
Dataset::default() Dataset::default()
.name(&cpu.0) .name(&cpu.0)
.marker(Marker::Braille) .marker(Marker::Dot)
.style(Style::default().fg(COLOUR_LIST[i % COLOUR_LIST.len()])) .style(Style::default().fg(COLOUR_LIST[i % COLOUR_LIST.len()]))
.data(&(cpu.1)), .data(&(cpu.1)),
); );
@ -108,8 +108,8 @@ pub fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, canvas_
//Memory usage graph //Memory usage graph
{ {
let x_axis : Axis<String> = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 60.0]); let x_axis : Axis<String> = 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 y_axis = Axis::default().style(Style::default().fg(GRAPH_COLOUR)).bounds([0.0, 100.0]).labels(&["0", "50", "100"]);
Chart::default() Chart::default()
.block(Block::default().title("Memory Usage").borders(Borders::ALL).border_style(border_style)) .block(Block::default().title("Memory Usage").borders(Borders::ALL).border_style(border_style))
.x_axis(x_axis) .x_axis(x_axis)
@ -117,12 +117,12 @@ pub fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, canvas_
.datasets(&[ .datasets(&[
Dataset::default() Dataset::default()
.name(&("MEM :".to_string() + &format!("{:3}%", (canvas_data.mem_data.last().unwrap_or(&(0_f64, 0_f64)).1.round() as u64)))) .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)) .style(Style::default().fg(Color::LightRed))
.data(&canvas_data.mem_data), .data(&canvas_data.mem_data),
Dataset::default() Dataset::default()
.name(&("SWAP:".to_string() + &format!("{:3}%", (canvas_data.swap_data.last().unwrap_or(&(0_f64, 0_f64)).1.round() as u64)))) .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)) .style(Style::default().fg(Color::LightGreen))
.data(&canvas_data.swap_data), .data(&canvas_data.swap_data),
]) ])
@ -142,7 +142,7 @@ pub fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, canvas_
// Disk usage table // Disk usage table
Table::new(["Disk", "Mount", "Used", "Total", "Free"].iter(), disk_rows) Table::new(["Disk", "Mount", "Used", "Total", "Free"].iter(), disk_rows)
.block(Block::default().title("Disk Usage").borders(Borders::ALL).border_style(border_style)) .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]) .widths(&[15, 10, 5, 5, 5])
.render(&mut f, bottom_divided_chunk_1_2[0]); .render(&mut f, bottom_divided_chunk_1_2[0]);

View File

@ -21,7 +21,7 @@ enum Event<I> {
Update(Box<app::Data>), Update(Box<app::Data>),
} }
const STALE_MAX_SECONDS : u64 = 60; const STALE_MAX_MILLISECONDS : u64 = 60 * 1000;
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), io::Error> { async fn main() -> Result<(), io::Error> {
@ -30,7 +30,7 @@ async fn main() -> Result<(), io::Error> {
let mut terminal = Terminal::new(backend)?; let mut terminal = Terminal::new(backend)?;
let tick_rate_in_milliseconds : u64 = 250; 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"); let mut app = app::App::new("rustop");
@ -57,7 +57,7 @@ async fn main() -> Result<(), io::Error> {
// Event loop // Event loop
let mut data_state = app::DataState::default(); let mut data_state = app::DataState::default();
data_state.init(); 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()); data_state.set_temperature_type(app.temperature_type.clone());
{ {
let tx = tx.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() { if !app_data.list_of_cpu_packages.is_empty() {
// Initially, populate the cpu_collection. We want to inject elements in between if possible. // 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() { 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(); let mut this_cpu_data : Vec<(f64, f64)> = Vec::new();
for cpu in &app_data.list_of_cpu_packages { for data in &app_data.list_of_cpu_packages {
let current_cpu_usage = cpu.cpu_vec[cpu_num].cpu_usage; let current_time = std::time::Instant::now();
this_cpu_data.push((STALE_MAX_SECONDS as f64 - current_time.duration_since(cpu.instant).as_secs_f64().floor(), current_cpu_usage)); 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); 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 // Finally, add it all onto the end
for (i, data) in cpu_collection.iter().enumerate() { for (i, data) in cpu_collection.iter().enumerate() {
cpu_data_vector.push(( 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(), 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)> { fn convert_mem_data(mem_data : &[app::data_collection::mem::MemData]) -> Vec<(f64, f64)> {
let mut result : Vec<(f64, f64)> = Vec::new(); let mut result : Vec<(f64, f64)> = Vec::new();
let current_time = std::time::Instant::now();
for data in mem_data { for data in mem_data {
let current_time = std::time::Instant::now();
result.push(( 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, 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 result

View File

@ -1 +1,2 @@
#[allow(dead_code)]
pub struct RustopError {} pub struct RustopError {}

View File

@ -3,7 +3,7 @@ pub fn init_logger() -> Result<(), fern::InitError> {
.format(|out, message, record| { .format(|out, message, record| {
out.finish(format_args!( 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.target(),
record.level(), record.level(),
message message