Moved CPU over

This commit is contained in:
ClementTsang 2020-01-26 20:14:14 -05:00
parent c5cd431e2e
commit 57aa15978c
7 changed files with 104 additions and 131 deletions

View File

@ -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;
}
}

View File

@ -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, &current_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

View File

@ -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 }
}

View File

@ -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),

View File

@ -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])

View File

@ -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();
let current_time = current_data.current_instant;
let cpu_listing_offset = if show_avg_cpu { 0 } else { 1 };
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 (time, data) in &current_data.timed_data_vec {
let time_from_start: f64 = (TIME_STARTS_FROM as f64
- current_time.duration_since(*time).as_millis() as f64)
.floor();
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,
};
// 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)),
});
}
}
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,
});
}
}

View File

@ -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);
}
}
}