diff options
author | ClementTsang <clementjhtsang@gmail.com> | 2020-01-26 20:14:14 -0500 |
---|---|---|
committer | ClementTsang <clementjhtsang@gmail.com> | 2020-01-26 20:14:14 -0500 |
commit | 57aa15978ce2678c196f8ee93d9d45b9ff6f568d (patch) | |
tree | 6459ffebe862df987272d24fde16ebb27dd66ee9 /src | |
parent | c5cd431e2e82e58526dc990de584d661c3a3ff89 (diff) |
Moved CPU over
Diffstat (limited to 'src')
-rw-r--r-- | src/app.rs | 27 | ||||
-rw-r--r-- | src/app/data_harvester.rs | 25 | ||||
-rw-r--r-- | src/app/data_harvester/cpu.rs | 21 | ||||
-rw-r--r-- | src/app/data_janitor.rs | 42 | ||||
-rw-r--r-- | src/canvas.rs | 2 | ||||
-rw-r--r-- | src/data_conversion.rs | 97 | ||||
-rw-r--r-- | src/main.rs | 21 |
7 files changed, 104 insertions, 131 deletions
@@ -639,15 +639,8 @@ impl App { self.currently_selected_disk_position = self.data.list_of_disks.len() as i64 - 1 } ApplicationPosition::Cpu => { - if let Some(cpu_package) = self.data.list_of_cpu_packages.last() { - if self.show_average_cpu { - self.currently_selected_cpu_table_position = - cpu_package.cpu_vec.len() as i64; - } else { - self.currently_selected_cpu_table_position = - cpu_package.cpu_vec.len() as i64 - 1; - } - } + self.currently_selected_cpu_table_position = + self.canvas_data.cpu_data.len() as i64 - 1; } _ => {} } @@ -685,17 +678,11 @@ impl App { } fn change_cpu_table_position(&mut self, num_to_change_by: i64) { - if let Some(cpu_package) = self.data.list_of_cpu_packages.last() { - if self.currently_selected_cpu_table_position + num_to_change_by >= 0 - && self.currently_selected_cpu_table_position + num_to_change_by - < if self.show_average_cpu { - cpu_package.cpu_vec.len() - } else { - cpu_package.cpu_vec.len() - 1 - } as i64 - { - self.currently_selected_cpu_table_position += num_to_change_by; - } + if self.currently_selected_cpu_table_position + num_to_change_by >= 0 + && self.currently_selected_cpu_table_position + num_to_change_by + < self.canvas_data.cpu_data.len() as i64 + { + self.currently_selected_cpu_table_position += num_to_change_by; } } diff --git a/src/app/data_harvester.rs b/src/app/data_harvester.rs index 100c3a9c..4127f09f 100644 --- a/src/app/data_harvester.rs +++ b/src/app/data_harvester.rs @@ -25,7 +25,7 @@ fn push_if_valid<T: std::clone::Clone>(result: &Result<T>, vector_to_push: &mut #[derive(Clone, Debug)] pub struct Data { - pub list_of_cpu_packages: Vec<cpu::CPUPackage>, + pub cpu: cpu::CPUHarvest, pub list_of_io: Vec<disks::IOPackage>, pub memory: mem::MemHarvest, pub swap: mem::MemHarvest, @@ -40,7 +40,7 @@ pub struct Data { impl Default for Data { fn default() -> Self { Data { - list_of_cpu_packages: Vec::default(), + cpu: cpu::CPUHarvest::default(), list_of_io: Vec::default(), memory: mem::MemHarvest::default(), swap: mem::MemHarvest::default(), @@ -56,7 +56,6 @@ impl Default for Data { impl Data { pub fn first_run_cleanup(&mut self) { - self.list_of_cpu_packages = Vec::new(); self.list_of_io = Vec::new(); self.list_of_temperature_sensor = Vec::new(); self.list_of_processes = Vec::new(); @@ -66,6 +65,7 @@ impl Data { self.network.first_run_cleanup(); self.memory = mem::MemHarvest::default(); self.swap = mem::MemHarvest::default(); + self.cpu = cpu::CPUHarvest::default(); } } @@ -112,6 +112,7 @@ impl DataState { self.sys.refresh_all(); self.mem_total_kb = self.sys.get_total_memory(); futures::executor::block_on(self.update_data()); + std::thread::sleep(std::time::Duration::from_millis(250)); self.data.first_run_cleanup(); } @@ -145,11 +146,10 @@ impl DataState { self.data.swap = swap; } + // CPU + self.data.cpu = cpu::get_cpu_data_list(&self.sys); + // What we want to do: For timed data, if there is an error, just do not add. For other data, just don't update! - push_if_valid( - &cpu::get_cpu_data_list(&self.sys, ¤t_instant), - &mut self.data.list_of_cpu_packages, - ); set_if_valid( &processes::get_sorted_processes_list( &self.sys, @@ -192,17 +192,6 @@ impl DataState { for stale in stale_list { self.prev_pid_stats.remove(&stale); } - - self.data.list_of_cpu_packages = self - .data - .list_of_cpu_packages - .iter() - .cloned() - .filter(|entry| { - clean_instant.duration_since(entry.instant).as_secs() <= self.stale_max_seconds - }) - .collect::<Vec<_>>(); - self.data.list_of_io = self .data .list_of_io diff --git a/src/app/data_harvester/cpu.rs b/src/app/data_harvester/cpu.rs index 4987a6a3..c3276827 100644 --- a/src/app/data_harvester/cpu.rs +++ b/src/app/data_harvester/cpu.rs @@ -1,33 +1,26 @@ -use std::time::Instant; use sysinfo::{ProcessorExt, System, SystemExt}; -#[derive(Debug, Clone)] +#[derive(Default, Debug, Clone)] pub struct CPUData { - pub cpu_name: Box<str>, + pub cpu_name: String, pub cpu_usage: f64, } -#[derive(Debug, Clone)] -pub struct CPUPackage { +#[derive(Default, Debug, Clone)] +pub struct CPUHarvest { pub cpu_vec: Vec<CPUData>, - pub instant: Instant, } -pub fn get_cpu_data_list( - sys: &System, curr_time: &Instant, -) -> crate::utils::error::Result<CPUPackage> { +pub fn get_cpu_data_list(sys: &System) -> CPUHarvest { let cpu_data = sys.get_processor_list(); let mut cpu_vec = Vec::new(); for cpu in cpu_data { cpu_vec.push(CPUData { - cpu_name: Box::from(cpu.get_name()), + cpu_name: cpu.get_name().to_string(), cpu_usage: f64::from(cpu.get_cpu_usage()) * 100_f64, }); } - Ok(CPUPackage { - cpu_vec, - instant: *curr_time, - }) + CPUHarvest { cpu_vec } } diff --git a/src/app/data_janitor.rs b/src/app/data_janitor.rs index d361ffc0..e6e5f336 100644 --- a/src/app/data_janitor.rs +++ b/src/app/data_janitor.rs @@ -1,4 +1,4 @@ -use crate::data_harvester::{mem, network, Data}; +use crate::data_harvester::{cpu, mem, network, Data}; /// In charge of cleaning and managing data. I couldn't think of a better /// name for the file. use std::time::Instant; @@ -12,7 +12,7 @@ pub type JoinedDataPoints = (Value, Vec<(TimeOffset, Value)>); pub struct TimedData { pub rx_data: JoinedDataPoints, pub tx_data: JoinedDataPoints, - pub cpu_data: JoinedDataPoints, + pub cpu_data: Vec<JoinedDataPoints>, pub mem_data: JoinedDataPoints, pub swap_data: JoinedDataPoints, pub temp_data: JoinedDataPoints, @@ -35,7 +35,7 @@ pub struct DataCollection { pub network_harvest: network::NetworkHarvest, pub memory_harvest: mem::MemHarvest, pub swap_harvest: mem::MemHarvest, - // pub process_data: ProcessData, + pub cpu_harvest: cpu::CPUHarvest, } impl Default for DataCollection { @@ -46,7 +46,7 @@ impl Default for DataCollection { network_harvest: network::NetworkHarvest::default(), memory_harvest: mem::MemHarvest::default(), swap_harvest: mem::MemHarvest::default(), - // process_data: ProcessData::default(), + cpu_harvest: cpu::CPUHarvest::default(), } } } @@ -64,6 +64,9 @@ impl DataCollection { // Memory and Swap self.eat_memory_and_swap(&harvested_data, &harvested_time, &mut new_entry); + // CPU + self.eat_cpu(&harvested_data, &harvested_time, &mut new_entry); + // And we're done eating. self.current_instant = harvested_time; self.timed_data_vec.push((harvested_time, new_entry)); @@ -137,6 +140,31 @@ impl DataCollection { // In addition copy over latest data for easy reference self.network_harvest = harvested_data.network.clone(); } + + fn eat_cpu( + &mut self, harvested_data: &Data, harvested_time: &Instant, new_entry: &mut TimedData, + ) { + // Note this only pre-calculates the data points - the names will be + // within the local copy of cpu_harvest. Since it's all sequential + // it probably doesn't matter anyways. + for (itx, cpu) in harvested_data.cpu.cpu_vec.iter().enumerate() { + let cpu_joining_pts = if let Some((time, last_pt)) = self.timed_data_vec.last() { + generate_joining_points( + &time, + last_pt.cpu_data[itx].0, + &harvested_time, + cpu.cpu_usage, + ) + } else { + Vec::new() + }; + + let cpu_pt = (cpu.cpu_usage, cpu_joining_pts); + new_entry.cpu_data.push(cpu_pt); + } + + self.cpu_harvest = harvested_data.cpu.clone(); + } } pub fn generate_joining_points( @@ -151,13 +179,13 @@ pub fn generate_joining_points( // Let's generate... about this many points! let num_points = std::cmp::min( std::cmp::max( - (value_difference.abs() / (time_difference + 0.0001) * 1000.0) as u64, + (value_difference.abs() / (time_difference + 0.0001) * 500.0) as u64, 100, ), - 1000, + 500, ); - for itx in 0..num_points { + for itx in (0..num_points).step_by(1) { points.push(( time_difference - (itx as f64 / num_points as f64 * time_difference), start_y + (itx as f64 / num_points as f64 * value_difference), diff --git a/src/canvas.rs b/src/canvas.rs index 3111ef24..1cb7e4b6 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -391,7 +391,7 @@ fn draw_cpu_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, d // CPU usage graph let x_axis: Axis<String> = Axis::default() .style(Style::default().fg(GRAPH_COLOUR)) - .bounds([0.0, constants::TIME_STARTS_FROM as f64 * 10.0]); + .bounds([0.0, constants::TIME_STARTS_FROM as f64]); let y_axis = Axis::default() .style(Style::default().fg(GRAPH_COLOUR)) .bounds([-0.5, 100.5]) diff --git a/src/data_conversion.rs b/src/data_conversion.rs index 3618c8d2..1b5dd0ee 100644 --- a/src/data_conversion.rs +++ b/src/data_conversion.rs @@ -9,7 +9,6 @@ use crate::{ }; use constants::*; use regex::Regex; -use std::time::Instant; #[derive(Default, Debug)] pub struct ConvertedNetworkData { @@ -238,78 +237,48 @@ fn return_mapped_process(process: &data_harvester::processes::ProcessData) -> Co } pub fn update_cpu_data_points( - show_avg_cpu: bool, app_data: &data_harvester::Data, + show_avg_cpu: bool, current_data: &data_janitor::DataCollection, ) -> Vec<ConvertedCpuData> { let mut cpu_data_vector: Vec<ConvertedCpuData> = Vec::new(); - let mut cpu_collection: Vec<Vec<CpuPoint>> = Vec::new(); - - if !app_data.list_of_cpu_packages.is_empty() { - // I'm sorry for the following if statement but I couldn't be bothered here... - for cpu_num in (if show_avg_cpu { 0 } else { 1 }) - ..app_data.list_of_cpu_packages.last().unwrap().cpu_vec.len() - { - let mut this_cpu_data: Vec<CpuPoint> = Vec::new(); - - for data in &app_data.list_of_cpu_packages { - let current_time = Instant::now(); - let current_cpu_usage = data.cpu_vec[cpu_num].cpu_usage; - - let new_entry = CpuPoint { - time: ((TIME_STARTS_FROM as f64 - - current_time.duration_since(data.instant).as_millis() as f64) - * 10_f64) - .floor(), - usage: current_cpu_usage, - }; + let current_time = current_data.current_instant; + let cpu_listing_offset = if show_avg_cpu { 0 } else { 1 }; - // Now, inject our joining points... - if let Some(previous_element_data) = this_cpu_data.last().cloned() { - for idx in 0..50 { - this_cpu_data.push(CpuPoint { - time: previous_element_data.time - + ((new_entry.time - previous_element_data.time) / 50.0 - * f64::from(idx)), - usage: previous_element_data.usage - + ((new_entry.usage - previous_element_data.usage) / 50.0 - * f64::from(idx)), - }); - } - } + for (time, data) in ¤t_data.timed_data_vec { + let time_from_start: f64 = (TIME_STARTS_FROM as f64 + - current_time.duration_since(*time).as_millis() as f64) + .floor(); - this_cpu_data.push(new_entry); + for (itx, cpu) in data.cpu_data.iter().enumerate() { + if !show_avg_cpu && itx == 0 { + continue; } - cpu_collection.push(this_cpu_data); - } + // Check if the vector exists yet + let itx_offset = itx - cpu_listing_offset; + if cpu_data_vector.len() <= itx_offset { + cpu_data_vector.push(ConvertedCpuData::default()); + cpu_data_vector[itx_offset].cpu_name = if show_avg_cpu && itx_offset == 0 { + "AVG".to_string() + } else { + current_data.cpu_harvest.cpu_vec[itx] + .cpu_name + .to_uppercase() + }; + } - // Finally, add it all onto the end - for (i, data) in cpu_collection.iter().enumerate() { - if !app_data.list_of_cpu_packages.is_empty() { - // Commented out: this version includes the percentage in the label... - // cpu_data_vector.push(( - // // + 1 to skip total CPU if show_avg_cpu is false - // format!( - // "{:4}: ", - // &*(app_data.list_of_cpu_packages.last().unwrap().cpu_vec[i + if show_avg_cpu { 0 } else { 1 }].cpu_name) - // ) - // .to_uppercase() + &format!("{:3}%", (data.last().unwrap_or(&(0_f64, 0_f64)).1.round() as u64)), - // data.clone(), - // )) - cpu_data_vector.push(ConvertedCpuData { - cpu_name: format!( - "{} ", - if show_avg_cpu && i == 0 { - "AVG" - } else { - &*(app_data.list_of_cpu_packages.last().unwrap().cpu_vec - [i + if show_avg_cpu { 0 } else { 1 }] - .cpu_name) - } - ) - .to_uppercase(), - cpu_data: data.clone(), + //Insert joiner points + for &(joiner_offset, joiner_val) in &cpu.1 { + let offset_time = time_from_start - joiner_offset as f64; + cpu_data_vector[itx_offset].cpu_data.push(CpuPoint { + time: offset_time, + usage: joiner_val, }); } + + cpu_data_vector[itx_offset].cpu_data.push(CpuPoint { + time: time_from_start, + usage: cpu.0, + }); } } diff --git a/src/main.rs b/src/main.rs index 4ac4e7f8..2e40c3cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -264,16 +264,13 @@ fn main() -> error::Result<()> { _ => {} }, Event::Update(data) => { - // NOTE TO SELF - data is refreshed into app state HERE! That means, if it is - // frozen, then, app.data is never refreshed, until unfrozen! if !app.is_frozen { app.data_collection.eat_data(&data); + app.data = *data; // TODO: [OPT] remove this - app.data = *data; + // Convert all data into tui-compliant components - handle_process_sorting(&mut app); - - // Convert all data into tui components + // Network let network_data = convert_network_data_points(&app.data_collection); app.canvas_data.network_data_rx = network_data.rx; app.canvas_data.network_data_tx = network_data.tx; @@ -281,16 +278,26 @@ fn main() -> error::Result<()> { app.canvas_data.tx_display = network_data.tx_display; app.canvas_data.total_rx_display = network_data.total_rx_display; app.canvas_data.total_tx_display = network_data.total_tx_display; + + // Disk app.canvas_data.disk_data = update_disk_row(&app.data); + + // Temperatures app.canvas_data.temp_sensor_data = update_temp_row(&app.data, &app.temperature_type); + // Memory app.canvas_data.mem_data = update_mem_data_points(&app.data_collection); app.canvas_data.swap_data = update_swap_data_points(&app.data_collection); let memory_and_swap_labels = update_mem_labels(&app.data_collection); app.canvas_data.mem_label = memory_and_swap_labels.0; app.canvas_data.swap_label = memory_and_swap_labels.1; + + // CPU app.canvas_data.cpu_data = - update_cpu_data_points(app.show_average_cpu, &app.data); + update_cpu_data_points(app.show_average_cpu, &app.data_collection); + + // Processes + handle_process_sorting(&mut app); } } } |