Redid some of the networking portion, changed cargo a bit, some refactoring

This commit is contained in:
ClementTsang 2019-12-25 23:02:21 -05:00
parent 395a3083c6
commit baf588be8a
11 changed files with 90 additions and 42 deletions

View file

@ -26,7 +26,7 @@ heim = "0.0.9"
log = "0.4" log = "0.4"
rayon = "1.3" rayon = "1.3"
regex = "1.3.1" regex = "1.3.1"
sysinfo = "0.10" sysinfo = "0.9" #0.9 seems to be the last working version for my Ryzen PC...
tokio = "0.2.6" tokio = "0.2.6"
winapi = "0.3" winapi = "0.3"
tui = {version = "0.8", features = ["crossterm"], default-features = false } tui = {version = "0.8", features = ["crossterm"], default-features = false }

View file

@ -1,6 +1,6 @@
//! This is the main file to house data collection functions. //! This is the main file to house data collection functions.
use crate::constants; use crate::{constants, utils::error::Result};
use std::{collections::HashMap, time::Instant}; use std::{collections::HashMap, time::Instant};
use sysinfo::{System, SystemExt}; use sysinfo::{System, SystemExt};
@ -11,19 +11,19 @@ pub mod network;
pub mod processes; pub mod processes;
pub mod temperature; pub mod temperature;
fn set_if_valid<T: std::clone::Clone>(result: &Result<T, crate::utils::error::BottomError>, value_to_set: &mut T) { fn set_if_valid<T: std::clone::Clone>(result: &Result<T>, value_to_set: &mut T) {
if let Ok(result) = result { if let Ok(result) = result {
*value_to_set = (*result).clone(); *value_to_set = (*result).clone();
} }
} }
fn push_if_valid<T: std::clone::Clone>(result: &Result<T, crate::utils::error::BottomError>, vector_to_push: &mut Vec<T>) { fn push_if_valid<T: std::clone::Clone>(result: &Result<T>, vector_to_push: &mut Vec<T>) {
if let Ok(result) = result { if let Ok(result) = result {
vector_to_push.push(result.clone()); vector_to_push.push(result.clone());
} }
} }
#[derive(Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct Data { pub struct Data {
pub list_of_cpu_packages: Vec<cpu::CPUPackage>, pub list_of_cpu_packages: Vec<cpu::CPUPackage>,
pub list_of_io: Vec<disks::IOPackage>, pub list_of_io: Vec<disks::IOPackage>,
@ -44,6 +44,9 @@ pub struct DataState {
prev_pid_stats: HashMap<String, (f64, Instant)>, prev_pid_stats: HashMap<String, (f64, Instant)>,
prev_idle: f64, prev_idle: f64,
prev_non_idle: f64, prev_non_idle: f64,
prev_net_rx_bytes: u64,
prev_net_tx_bytes: u64,
prev_net_access_time: Instant,
temperature_type: temperature::TemperatureType, temperature_type: temperature::TemperatureType,
last_clean: Instant, // Last time stale data was cleared last_clean: Instant, // Last time stale data was cleared
} }
@ -58,6 +61,9 @@ impl Default for DataState {
prev_pid_stats: HashMap::new(), prev_pid_stats: HashMap::new(),
prev_idle: 0_f64, prev_idle: 0_f64,
prev_non_idle: 0_f64, prev_non_idle: 0_f64,
prev_net_rx_bytes: 0,
prev_net_tx_bytes: 0,
prev_net_access_time: Instant::now(),
temperature_type: temperature::TemperatureType::Celsius, temperature_type: temperature::TemperatureType::Celsius,
last_clean: Instant::now(), last_clean: Instant::now(),
} }
@ -70,38 +76,40 @@ impl DataState {
} }
pub fn init(&mut self) { pub fn init(&mut self) {
self.sys.refresh_system(); self.sys.refresh_all();
self.sys.refresh_network();
if !cfg!(target_os = "linux") {
// For now, might be just windows tbh
self.sys.refresh_processes();
}
} }
pub async fn update_data(&mut self) { pub async fn update_data(&mut self) {
self.sys.refresh_system(); self.sys.refresh_system();
self.sys.refresh_network();
if !cfg!(target_os = "linux") { if !cfg!(target_os = "linux") {
// For now, might be just windows tbh // For now, might be just windows tbh
self.sys.refresh_processes(); self.sys.refresh_processes();
self.sys.refresh_network();
} }
// What we want to do: For timed data, if there is an error, just do not add. For other data, just don't update! // 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(&network::get_network_data(&self.sys), &mut self.data.network); push_if_valid(
&network::get_network_data(
&self.sys,
&mut self.prev_net_rx_bytes,
&mut self.prev_net_tx_bytes,
&mut self.prev_net_access_time,
)
.await,
&mut self.data.network,
);
push_if_valid(&cpu::get_cpu_data_list(&self.sys), &mut self.data.list_of_cpu_packages); push_if_valid(&cpu::get_cpu_data_list(&self.sys), &mut self.data.list_of_cpu_packages);
// TODO: We can convert this to a multi-threaded task...
push_if_valid(&mem::get_mem_data_list().await, &mut self.data.memory); push_if_valid(&mem::get_mem_data_list().await, &mut self.data.memory);
push_if_valid(&mem::get_swap_data_list().await, &mut self.data.swap); push_if_valid(&mem::get_swap_data_list().await, &mut self.data.swap);
set_if_valid( set_if_valid(
&processes::get_sorted_processes_list(&self.sys, &mut self.prev_idle, &mut self.prev_non_idle, &mut self.prev_pid_stats).await, &processes::get_sorted_processes_list(&self.sys, &mut self.prev_idle, &mut self.prev_non_idle, &mut self.prev_pid_stats),
&mut self.data.list_of_processes, &mut self.data.list_of_processes,
); );
set_if_valid(&disks::get_disk_usage_list().await, &mut self.data.list_of_disks); set_if_valid(&disks::get_disk_usage_list().await, &mut self.data.list_of_disks);
push_if_valid(&disks::get_io_usage_list(false).await, &mut self.data.list_of_io); push_if_valid(&disks::get_io_usage_list(false).await, &mut self.data.list_of_io);
//push_if_valid(&disks::get_io_usage_list(true).await, &mut self.data.list_of_physical_io); // Removed, seems irrelevant for now...
set_if_valid( set_if_valid(
&temperature::get_temperature_data(&self.sys, &self.temperature_type).await, &temperature::get_temperature_data(&self.sys, &self.temperature_type).await,
&mut self.data.list_of_temperature_sensor, &mut self.data.list_of_temperature_sensor,

View file

@ -1,13 +1,13 @@
use std::time::Instant; use std::time::Instant;
use sysinfo::{ProcessorExt, System, SystemExt}; use sysinfo::{ProcessorExt, System, SystemExt};
#[derive(Clone)] #[derive(Debug, Clone)]
pub struct CPUData { pub struct CPUData {
pub cpu_name: Box<str>, pub cpu_name: Box<str>,
pub cpu_usage: f64, pub cpu_usage: f64,
} }
#[derive(Clone)] #[derive(Debug, Clone)]
pub struct CPUPackage { pub struct CPUPackage {
pub cpu_vec: Vec<CPUData>, pub cpu_vec: Vec<CPUData>,
pub instant: Instant, pub instant: Instant,
@ -21,7 +21,7 @@ pub fn get_cpu_data_list(sys: &System) -> crate::utils::error::Result<CPUPackage
cpu_vec.push(CPUData { cpu_vec.push(CPUData {
cpu_name: Box::from(cpu.get_name()), cpu_name: Box::from(cpu.get_name()),
cpu_usage: f64::from(cpu.get_cpu_usage()) * 100_f64, cpu_usage: f64::from(cpu.get_cpu_usage()) * 100_f64,
}) });
} }
Ok(CPUPackage { Ok(CPUPackage {

View file

@ -2,7 +2,7 @@ use futures::stream::StreamExt;
use heim::units::information; use heim::units::information;
use std::time::Instant; use std::time::Instant;
#[derive(Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct DiskData { pub struct DiskData {
pub name: Box<str>, pub name: Box<str>,
pub mount_point: Box<str>, pub mount_point: Box<str>,
@ -18,7 +18,7 @@ pub struct IOData {
pub write_bytes: u64, pub write_bytes: u64,
} }
#[derive(Clone)] #[derive(Debug, Clone)]
pub struct IOPackage { pub struct IOPackage {
pub io_hash: std::collections::HashMap<String, IOData>, pub io_hash: std::collections::HashMap<String, IOData>,
pub instant: Instant, pub instant: Instant,

View file

@ -1,7 +1,7 @@
use heim::units::information; use heim::units::information;
use std::time::Instant; use std::time::Instant;
#[derive(Clone)] #[derive(Debug, Clone)]
pub struct MemData { pub struct MemData {
pub mem_total_in_mb: u64, pub mem_total_in_mb: u64,
pub mem_used_in_mb: u64, pub mem_used_in_mb: u64,

View file

@ -1,23 +1,59 @@
use futures::StreamExt;
use heim::net;
use heim::units::information::byte;
use std::time::Instant; use std::time::Instant;
use sysinfo::{NetworkExt, System, SystemExt}; use sysinfo::{NetworkExt, System, SystemExt};
#[derive(Clone)] #[derive(Debug, Clone)]
/// Note all values are in bytes... /// Note all values are in bytes...
pub struct NetworkData { pub struct NetworkData {
pub rx : u64, pub rx: u64,
pub tx : u64, pub tx: u64,
pub total_rx : u64, pub total_rx: u64,
pub total_tx : u64, pub total_tx: u64,
pub instant : Instant, pub instant: Instant,
} }
pub fn get_network_data(sys : &System) -> crate::utils::error::Result<NetworkData> { pub async fn get_network_data(
let network_data = sys.get_network(); sys: &System, prev_net_rx_bytes: &mut u64, prev_net_tx_bytes: &mut u64, prev_net_access_time: &mut std::time::Instant,
Ok(NetworkData { ) -> crate::utils::error::Result<NetworkData> {
rx : network_data.get_income(), if cfg!(target_os = "windows") {
tx : network_data.get_outcome(), let network_data = sys.get_network();
total_rx : 0,
total_tx : 0, *prev_net_access_time = Instant::now();
instant : Instant::now(), Ok(NetworkData {
}) rx: network_data.get_income(),
tx: network_data.get_outcome(),
total_rx: 0,
total_tx: 0,
instant: *prev_net_access_time,
})
} else {
let mut io_data = net::io_counters();
let mut net_rx: u64 = 0;
let mut net_tx: u64 = 0;
while let Some(io) = io_data.next().await {
if let Ok(io) = io {
net_rx += io.bytes_recv().get::<byte>();
net_tx += io.bytes_sent().get::<byte>();
}
}
let cur_time = Instant::now();
let elapsed_time = cur_time.duration_since(*prev_net_access_time).as_millis();
let rx = (((net_rx - *prev_net_rx_bytes) * 1000) as u128 / elapsed_time) as u64;
let tx = (((net_tx - *prev_net_tx_bytes) * 1000) as u128 / elapsed_time) as u64;
*prev_net_rx_bytes = net_rx;
*prev_net_tx_bytes = net_tx;
*prev_net_access_time = cur_time;
Ok(NetworkData {
rx,
tx,
total_rx: *prev_net_rx_bytes,
total_tx: *prev_net_tx_bytes,
instant: *prev_net_access_time,
})
}
} }

View file

@ -17,7 +17,7 @@ impl Default for ProcessSorting {
} }
// Possible process info struct? // Possible process info struct?
#[derive(Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct ProcessData { pub struct ProcessData {
pub pid: u32, pub pid: u32,
pub cpu_usage_percent: f64, pub cpu_usage_percent: f64,
@ -168,7 +168,7 @@ fn convert_ps(
}) })
} }
pub async fn get_sorted_processes_list( pub fn get_sorted_processes_list(
sys: &System, prev_idle: &mut f64, prev_non_idle: &mut f64, prev_pid_stats: &mut std::collections::HashMap<String, (f64, Instant)>, sys: &System, prev_idle: &mut f64, prev_non_idle: &mut f64, prev_pid_stats: &mut std::collections::HashMap<String, (f64, Instant)>,
) -> crate::utils::error::Result<Vec<ProcessData>> { ) -> crate::utils::error::Result<Vec<ProcessData>> {
let mut process_vector: Vec<ProcessData> = Vec::new(); let mut process_vector: Vec<ProcessData> = Vec::new();
@ -179,6 +179,7 @@ pub async fn get_sorted_processes_list(
let ps_result = Command::new("ps").args(&["-axo", "pid:10,comm:50,%mem:5", "--noheader"]).output()?; let ps_result = Command::new("ps").args(&["-axo", "pid:10,comm:50,%mem:5", "--noheader"]).output()?;
let ps_stdout = String::from_utf8_lossy(&ps_result.stdout); let ps_stdout = String::from_utf8_lossy(&ps_result.stdout);
let split_string = ps_stdout.split('\n'); let split_string = ps_stdout.split('\n');
//debug!("{:?}", split_string);
if let Ok((cpu_usage, cpu_percentage)) = cpu_usage_calculation(prev_idle, prev_non_idle) { if let Ok((cpu_usage, cpu_percentage)) = cpu_usage_calculation(prev_idle, prev_non_idle) {
let process_stream = split_string.collect::<Vec<&str>>(); let process_stream = split_string.collect::<Vec<&str>>();

View file

@ -3,7 +3,7 @@ use heim::units::thermodynamic_temperature;
use std::cmp::Ordering; use std::cmp::Ordering;
use sysinfo::{ComponentExt, System, SystemExt}; use sysinfo::{ComponentExt, System, SystemExt};
#[derive(Clone)] #[derive(Debug, Clone)]
pub struct TempData { pub struct TempData {
pub component_name: Box<str>, pub component_name: Box<str>,
pub temperature: f32, pub temperature: f32,

View file

@ -1,6 +1,8 @@
/// This file is meant to house (OS specific) implementations on how to kill processes. /// This file is meant to house (OS specific) implementations on how to kill processes.
use std::process::Command; use std::process::Command;
// TODO: Redo this, also make it update process list on freeze.
// Copied from SO: https://stackoverflow.com/a/55231715 // Copied from SO: https://stackoverflow.com/a/55231715
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
use winapi::{ use winapi::{

View file

@ -123,7 +123,7 @@ pub fn update_cpu_data_points(show_avg_cpu: bool, app_data: &data_collection::Da
let mut cpu_collection: Vec<Vec<(f64, f64)>> = Vec::new(); let mut cpu_collection: Vec<Vec<(f64, f64)>> = Vec::new();
if !app_data.list_of_cpu_packages.is_empty() { if !app_data.list_of_cpu_packages.is_empty() {
// I'm sorry for the if statement but I couldn't be bothered here... // 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() { 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<(f64, f64)> = Vec::new(); let mut this_cpu_data: Vec<(f64, f64)> = Vec::new();
@ -313,7 +313,7 @@ pub fn convert_network_data_points(network_data: &[data_collection::network::Net
format!("TX: {:5.*}GiB/s", 1, num_bytes as f64 / 1024.0 / 1024.0 / 1024.0) format!("TX: {:5.*}GiB/s", 1, num_bytes as f64 / 1024.0 / 1024.0 / 1024.0)
} }
} else { } else {
"0B.0/s".to_string() "0.0B/s".to_string()
}; };
ConvertedNetworkData { ConvertedNetworkData {

View file

@ -169,6 +169,7 @@ fn main() -> error::Result<()> {
} }
futures::executor::block_on(data_state.update_data()); futures::executor::block_on(data_state.update_data());
tx.send(Event::Update(Box::from(data_state.data.clone()))).unwrap(); tx.send(Event::Update(Box::from(data_state.data.clone()))).unwrap();
if first_run { if first_run {
// Fix for if you set a really long time for update periods (and just gives a faster first value) // Fix for if you set a really long time for update periods (and just gives a faster first value)
thread::sleep(Duration::from_millis(250)); thread::sleep(Duration::from_millis(250));