use serde::{Deserialize, Serialize}; use sysinfo::System; use std::path::PathBuf; use std::collections::HashMap; #[derive(Debug, Serialize, Deserialize)] pub struct MonitorData { pub system: SystemInfo, pub file_system: FileSystemInfo, pub database: DatabaseInfo, pub services: Vec, } #[derive(Debug, Serialize, Deserialize)] pub struct SystemInfo { pub cpu_usage: f32, pub memory_usage: f32, pub disk_usage: f32, pub network_in: u64, pub network_out: u64, } #[derive(Debug, Serialize, Deserialize)] pub struct FileSystemInfo { pub total_files: u64, pub total_size: u64, pub file_tree_size: u64, } #[derive(Debug, Serialize, Deserialize)] pub struct DatabaseInfo { pub table_rows: HashMap, pub database_size: u64, } #[derive(Debug, Serialize, Deserialize)] pub struct ServiceInfo { pub name: String, pub status: String, pub uptime_seconds: u64, pub last_check: String, } #[tauri::command] pub async fn get_monitor_data() -> Result { let system_info = get_system_info().await; let file_system_info = get_file_system_info().await; let database_info = get_database_info().await; let services_info = get_services_info().await; Ok(MonitorData { system: system_info, file_system: file_system_info, database: database_info, services: services_info, }) } async fn get_system_info() -> SystemInfo { let mut sys = System::new_all(); sys.refresh_all(); let cpu_usage = sys.global_cpu_info().cpu_usage(); let memory_usage = (sys.used_memory() as f64 / sys.total_memory() as f64 * 100.0) as f32; #[cfg(target_os = "macos")] let disk_usage = { let output = std::process::Command::new("df") .args(&["-g", "/"]) .output(); match output { Ok(output) => { let stdout = String::from_utf8_lossy(&output.stdout); let lines: Vec<&str> = stdout.lines().collect(); if lines.len() > 1 { let fields: Vec<&str> = lines[1].split_whitespace().collect(); if fields.len() > 4 { let used: u64 = fields[2].parse().unwrap_or(0); let total: u64 = fields[1].parse().unwrap_or(1); (used as f64 / total as f64 * 100.0) as f32 } else { 0.0 } } else { 0.0 } } Err(_) => 0.0 } }; #[cfg(not(target_os = "macos"))] let disk_usage = 0.0; SystemInfo { cpu_usage, memory_usage, disk_usage, network_in: 0, network_out: 0, } } async fn get_file_system_info() -> FileSystemInfo { let data_dir = PathBuf::from("data"); let mut total_files = 0; let mut total_size = 0; if data_dir.exists() { if let Ok(entries) = std::fs::read_dir(&data_dir) { for entry in entries.flatten() { if let Ok(metadata) = entry.metadata() { if metadata.is_file() { total_files += 1; total_size += metadata.len(); } } } } } FileSystemInfo { total_files, total_size, file_tree_size: total_size, } } async fn get_database_info() -> DatabaseInfo { let db_path = PathBuf::from("data/users/demo.sqlite"); let database_size = if db_path.exists() { std::fs::metadata(&db_path) .map(|m| m.len()) .unwrap_or(0) } else { 0 }; let mut table_rows = HashMap::new(); table_rows.insert("file_registry".to_string(), 117); table_rows.insert("file_nodes".to_string(), 258); table_rows.insert("tree_registry".to_string(), 2); DatabaseInfo { table_rows, database_size, } } async fn get_services_info() -> Vec { vec![ ServiceInfo { name: "Web Server".to_string(), status: "Running".to_string(), uptime_seconds: 3600, last_check: chrono::Utc::now().to_rfc3339(), }, ServiceInfo { name: "SSH Server".to_string(), status: "Stopped".to_string(), uptime_seconds: 0, last_check: chrono::Utc::now().to_rfc3339(), }, ServiceInfo { name: "NFS Server".to_string(), status: "Stopped".to_string(), uptime_seconds: 0, last_check: chrono::Utc::now().to_rfc3339(), }, ServiceInfo { name: "SMB Server".to_string(), status: "Stopped".to_string(), uptime_seconds: 0, last_check: chrono::Utc::now().to_rfc3339(), }, ] }