Skip to content

Commit

Permalink
adding more stats, network traffic and disk usage + few tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
Abdenasser committed Nov 6, 2024
1 parent 33628d7 commit b179b0a
Show file tree
Hide file tree
Showing 4 changed files with 437 additions and 175 deletions.
109 changes: 82 additions & 27 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,42 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use sysinfo::{CpuExt, SystemExt, ProcessExt, System, PidExt, ProcessStatus};
use sysinfo::{
System,
ProcessStatus,
NetworksExt,
NetworkExt,
DiskExt,
SystemExt,
CpuExt,
ProcessExt,
PidExt,
};
use tauri::State;
use std::sync::Mutex;
use std::collections::HashMap;
use std::time::{Instant};

struct AppState {
sys: Mutex<System>,
process_cache: Mutex<HashMap<u32, ProcessStaticInfo>>,
last_network_update: Mutex<(Instant, u64, u64)>,
}

impl AppState {
pub fn new() -> Self {
let mut sys = System::new();
sys.refresh_all();

// Initialize network stats
let initial_rx = sys.networks().iter().map(|(_, data)| data.total_received()).sum();
let initial_tx = sys.networks().iter().map(|(_, data)| data.total_transmitted()).sum();

Self {
sys: Mutex::new(sys),
process_cache: Mutex::new(HashMap::new()),
last_network_update: Mutex::new((Instant::now(), initial_rx, initial_tx)),
}
}
}

#[derive(Clone)]
Expand All @@ -31,14 +60,19 @@ struct ProcessInfo {
}

#[derive(serde::Serialize)]
struct SystemStats {
cpu_usage: Vec<f32>,
memory_total: u64,
memory_used: u64,
memory_free:u64,
memory_cached: u64,
uptime: u64,
load_avg: [f64; 3],
pub struct SystemStats {
pub cpu_usage: Vec<f32>,
pub memory_total: u64,
pub memory_used: u64,
pub memory_free: u64,
pub memory_cached: u64,
pub uptime: u64,
pub load_avg: [f64; 3],
pub network_rx_bytes: u64,
pub network_tx_bytes: u64,
pub disk_total_bytes: u64,
pub disk_used_bytes: u64,
pub disk_free_bytes: u64,
}

#[tauri::command]
Expand All @@ -50,7 +84,10 @@ async fn get_processes(state: State<'_, AppState>) -> Result<(Vec<ProcessInfo>,
{
let mut sys = state.sys.lock().map_err(|_| "Failed to lock system state")?;
sys.refresh_all();

sys.refresh_networks();
sys.refresh_disks_list();
sys.refresh_disks();

// Collect all the process data we need while holding sys lock
processes_data = sys
.processes()
Expand All @@ -69,22 +106,43 @@ async fn get_processes(state: State<'_, AppState>) -> Result<(Vec<ProcessInfo>,
})
.collect::<Vec<_>>();

// Get system stats while we still have the sys lock
let cpu_usage: Vec<f32> = sys.cpus().iter().map(|cpu| cpu.cpu_usage()).collect();
let load_avg = sys.load_average();
let memory_total = sys.total_memory();
let memory_used = sys.used_memory();
let memory_free = memory_total - memory_used;
let memory_cached = memory_total - (memory_used + memory_free); // Estimated
// Calculate total network I/O
let mut last_update = state.last_network_update.lock().map_err(|_| "Failed to lock network state")?;
let elapsed = last_update.0.elapsed().as_secs_f64();
let current_time = Instant::now();

let current_rx: u64 = sys.networks().iter().map(|(_, data)| data.total_received()).sum();
let current_tx: u64 = sys.networks().iter().map(|(_, data)| data.total_transmitted()).sum();

let network_stats = (
((current_rx - last_update.1) as f64 / elapsed) as u64,
((current_tx - last_update.2) as f64 / elapsed) as u64,
);

*last_update = (current_time, current_rx, current_tx);

// Calculate total disk usage
let disk_stats = sys.disks().iter().fold((0, 0, 0), |acc, disk| {
(
acc.0 + disk.total_space(),
acc.1 + disk.total_space() - disk.available_space(),
acc.2 + disk.available_space()
)
});

system_stats = SystemStats {
cpu_usage,
memory_total,
memory_used,
memory_free,
memory_cached,
cpu_usage: sys.cpus().iter().map(|cpu| cpu.cpu_usage()).collect(),
memory_total: sys.total_memory(),
memory_used: sys.used_memory(),
memory_free: sys.total_memory() - sys.used_memory(),
memory_cached: sys.total_memory() - (sys.used_memory() + (sys.total_memory() - sys.used_memory())),
uptime: sys.uptime(),
load_avg: [load_avg.one, load_avg.five, load_avg.fifteen],
load_avg: [sys.load_average().one, sys.load_average().five, sys.load_average().fifteen],
network_rx_bytes: network_stats.0,
network_tx_bytes: network_stats.1,
disk_total_bytes: disk_stats.0,
disk_used_bytes: disk_stats.1,
disk_free_bytes: disk_stats.2,
};
} // sys lock is automatically dropped here

Expand Down Expand Up @@ -139,10 +197,7 @@ async fn kill_process(pid: u32, state: State<'_, AppState>) -> Result<bool, Stri

fn main() {
tauri::Builder::default()
.manage(AppState {
sys: Mutex::new(System::new_all()),
process_cache: Mutex::new(HashMap::new()),
})
.manage(AppState::new())
.invoke_handler(tauri::generate_handler![
get_processes,
kill_process
Expand Down
6 changes: 3 additions & 3 deletions src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@
"windows": [
{
"fullscreen": false,
"height": 800,
"height": 900,
"resizable": true,
"title": "NeoHtop",
"width": 1280,
"minWidth": 1180,
"minHeight": 600
"minWidth": 1280,
"minHeight": 900
}
]
}
Expand Down
Loading

0 comments on commit b179b0a

Please sign in to comment.