mirror of
https://github.com/ClementTsang/bottom.git
synced 2024-11-13 08:50:58 +03:00
Moved CPU over
This commit is contained in:
parent
c5cd431e2e
commit
57aa15978c
27
src/app.rs
27
src/app.rs
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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])
|
||||
|
@ -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 ¤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();
|
||||
|
||||
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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
21
src/main.rs
21
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user