feat: Implement core system monitoring functionality

- Create SystemMonitor as main monitoring orchestrator
- Implement CPU usage tracking with accurate sampling
- Implement memory info collection (total, used, available, percent)
- Implement disk usage across all mounted disks
- Implement network statistics (bytes sent/received, packets)
- Add display_stats() for formatted output
- Define data structures: MemoryInfo, DiskInfo, NetworkStats
- Integrate with logger for metric recording
- Use sysinfo's System, Disks, and Networks APIs
This commit is contained in:
m1ngsama 2025-12-03 16:30:00 +08:00
parent 32ecbd8aff
commit 3af5a6182e

171
src/monitor.rs Normal file
View file

@ -0,0 +1,171 @@
use crate::config::Config;
use crate::process::ProcessMonitor;
use crate::logger::TrackerLogger;
use sysinfo::{System, Disks, Networks};
use chrono::Local;
pub struct SystemMonitor {
config: Config,
sys: System,
disks: Disks,
networks: Networks,
process_monitor: ProcessMonitor,
logger: TrackerLogger,
}
impl SystemMonitor {
pub fn new(config: Config) -> Self {
SystemMonitor {
config,
sys: System::new_all(),
disks: Disks::new_with_refreshed_list(),
networks: Networks::new_with_refreshed_list(),
process_monitor: ProcessMonitor::new(),
logger: TrackerLogger::default(),
}
}
pub fn get_cpu_usage(&mut self) -> f32 {
self.sys.refresh_cpu_all();
std::thread::sleep(std::time::Duration::from_millis(200));
self.sys.refresh_cpu_all();
self.sys.global_cpu_usage()
}
pub fn get_memory_info(&mut self) -> MemoryInfo {
self.sys.refresh_memory();
let total = self.sys.total_memory();
let used = self.sys.used_memory();
let available = self.sys.available_memory();
let percent = if total > 0 {
(used as f32 / total as f32) * 100.0
} else {
0.0
};
MemoryInfo {
total,
used,
available,
percent,
}
}
pub fn get_disk_usage(&mut self) -> DiskInfo {
self.disks.refresh();
let mut total: u64 = 0;
let mut available: u64 = 0;
for disk in &self.disks {
total += disk.total_space();
available += disk.available_space();
}
let used = total.saturating_sub(available);
let percent = if total > 0 {
(used as f32 / total as f32) * 100.0
} else {
0.0
};
DiskInfo {
total,
used,
free: available,
percent,
}
}
pub fn get_network_stats(&mut self) -> NetworkStats {
self.networks.refresh();
let mut bytes_sent = 0;
let mut bytes_recv = 0;
let mut packets_sent = 0;
let mut packets_recv = 0;
for (_, network) in &self.networks {
bytes_sent += network.total_transmitted();
bytes_recv += network.total_received();
packets_sent += network.total_packets_transmitted();
packets_recv += network.total_packets_received();
}
NetworkStats {
bytes_sent,
bytes_recv,
packets_sent,
packets_recv,
}
}
pub fn display_stats(&mut self) {
println!("\n{}", "=".repeat(50));
println!("System Tracker - {}", Local::now().format("%Y-%m-%d %H:%M:%S"));
println!("{}\n", "=".repeat(50));
if self.config.display.show_cpu {
let cpu_usage = self.get_cpu_usage();
println!("CPU Usage: {:.2}%", cpu_usage);
self.logger.log_stats("CPU", &format!("{:.2}%", cpu_usage));
}
if self.config.display.show_memory {
let mem = self.get_memory_info();
println!("Memory: {:.2}% ({:.2}GB / {:.2}GB)",
mem.percent,
mem.used as f64 / (1024_f64.powi(3)),
mem.total as f64 / (1024_f64.powi(3))
);
self.logger.log_stats("Memory", &format!("{:.2}%", mem.percent));
}
if self.config.display.show_disk {
let disk = self.get_disk_usage();
println!("Disk: {:.2}% ({:.2}GB / {:.2}GB)",
disk.percent,
disk.used as f64 / (1024_f64.powi(3)),
disk.total as f64 / (1024_f64.powi(3))
);
self.logger.log_stats("Disk", &format!("{:.2}%", disk.percent));
}
if self.config.display.show_network {
let net = self.get_network_stats();
println!("Network: Sent {:.2}MB | Recv {:.2}MB",
net.bytes_sent as f64 / (1024_f64.powi(2)),
net.bytes_recv as f64 / (1024_f64.powi(2))
);
self.logger.log_stats("Network", &format!("Sent: {} Recv: {}", net.bytes_sent, net.bytes_recv));
}
if self.config.display.show_processes {
self.process_monitor.display_processes(self.config.process_limit);
}
}
}
#[derive(Debug)]
pub struct MemoryInfo {
pub total: u64,
pub used: u64,
pub available: u64,
pub percent: f32,
}
#[derive(Debug)]
pub struct DiskInfo {
pub total: u64,
pub used: u64,
pub free: u64,
pub percent: f32,
}
#[derive(Debug)]
pub struct NetworkStats {
pub bytes_sent: u64,
pub bytes_recv: u64,
pub packets_sent: u64,
pub packets_recv: u64,
}