From c90a276dca594935e335d4cb63f80ab40a4144dc Mon Sep 17 00:00:00 2001 From: donpat1to Date: Tue, 28 Oct 2025 11:20:12 +0100 Subject: [PATCH] added error handling --- WatcherAgent/src/docker/mod.rs | 101 +++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 11 deletions(-) diff --git a/WatcherAgent/src/docker/mod.rs b/WatcherAgent/src/docker/mod.rs index 6a6ce2d..e645d62 100644 --- a/WatcherAgent/src/docker/mod.rs +++ b/WatcherAgent/src/docker/mod.rs @@ -129,27 +129,72 @@ impl DockerManager { /// Collects Docker metrics for all containers pub async fn collect_metrics(&self) -> Result> { let containers = self.get_containers().await?; - let (cpu_stats, net_stats, mem_stats) = stats::get_container_stats(&self.docker).await?; + if let Some(first_container) = containers.first() { + println!("Debug: Testing stats for container {}", first_container.id); + let _ = self.debug_container_stats(&first_container.id).await; + } + + + // Get stats with proper error handling + let stats_result = stats::get_container_stats(&self.docker).await; + let (cpu_stats, net_stats, mem_stats) = match stats_result { + Ok(stats) => stats, + Err(e) => { + eprintln!("Warning: Failed to get container stats: {}", e); + // Return empty stats instead of failing completely + (Vec::new(), Vec::new(), Vec::new()) + } + }; + + println!("Debug: Found {} containers, {} CPU stats, {} network stats, {} memory stats", + containers.len(), cpu_stats.len(), net_stats.len(), mem_stats.len()); let container_infos_total: Vec<_> = containers .into_iter() .map(|container| { + // Use short ID for matching (first 12 chars) + let container_short_id = if container.id.len() > 12 { + &container.id[..12] + } else { + &container.id + }; + let cpu = cpu_stats .iter() - .find(|c| c.container_id == Some(container.id.clone())) + .find(|c| { + c.container_id.as_ref() + .map(|id| id.starts_with(container_short_id)) + .unwrap_or(false) + }) .cloned(); + let network = net_stats .iter() - .find(|n| n.container_id == Some(container.id.clone())) + .find(|n| { + n.container_id.as_ref() + .map(|id| id.starts_with(container_short_id)) + .unwrap_or(false) + }) .cloned(); + let ram = mem_stats .iter() - .find(|m| m.container_id == Some(container.id.clone())) + .find(|m| { + m.container_id.as_ref() + .map(|id| id.starts_with(container_short_id)) + .unwrap_or(false) + }) .cloned(); + // Debug output for this container + if cpu.is_none() || network.is_none() || ram.is_none() { + println!("Debug: Container {} - CPU: {:?}, Network: {:?}, RAM: {:?}", + container_short_id, cpu.is_some(), network.is_some(), ram.is_some()); + } + DockerContainerInfo { container: Some(container), - status: None, // Status can be fetched if needed + status: None, cpu, network, ram, @@ -160,7 +205,6 @@ impl DockerManager { let container_infos: Vec = container_infos_total .into_iter() .filter_map(|info| { - // Safely handle container extraction let container = match info.container { Some(c) => c, None => { @@ -190,13 +234,13 @@ impl DockerManager { // Safely handle network data with defaults let network_dto = if let Some(net) = info.network { DockerContainerNetworkDto { - net_in: net.rx_bytes.map(|bytes| bytes as f64).or(Some(0.0)), - net_out: net.tx_bytes.map(|bytes| bytes as f64).or(Some(0.0)), + net_in: net.rx_bytes.map(|bytes| bytes as f64), + net_out: net.tx_bytes.map(|bytes| bytes as f64), } } else { DockerContainerNetworkDto { - net_in: Some(0.0), - net_out: Some(0.0), + net_in: None, + net_out: None, } }; @@ -229,6 +273,41 @@ impl DockerManager { Ok(dto) } + + /// Debug function to check stats collection for a specific container + pub async fn debug_container_stats( + &self, + container_id: &str + ) -> Result<(), Box> { + println!("=== DEBUG STATS FOR CONTAINER {} ===", container_id); + + let (cpu_info, net_info, mem_info) = stats::get_single_container_stats(&self.docker, container_id).await?; + + println!("CPU Info: {:?}", cpu_info); + println!("Network Info: {:?}", net_info); + println!("Memory Info: {:?}", mem_info); + + // Also try the individual stats functions + println!("--- Individual CPU Stats ---"); + match stats::cpu::get_single_container_cpu_stats(&self.docker, container_id).await { + Ok(cpu) => println!("CPU: {:?}", cpu), + Err(e) => println!("CPU Error: {}", e), + } + + println!("--- Individual Network Stats ---"); + match stats::network::get_single_container_network_stats(&self.docker, container_id).await { + Ok(net) => println!("Network: {:?}", net), + Err(e) => println!("Network Error: {}", e), + } + + println!("--- Individual Memory Stats ---"); + match stats::ram::get_single_container_memory_stats(&self.docker, container_id).await { + Ok(mem) => println!("Memory: {:?}", mem), + Err(e) => println!("Memory Error: {}", e), + } + + Ok(()) + } } // Keep these as utility functions if needed, but they should use DockerManager internally @@ -247,4 +326,4 @@ impl DockerContainer { pub fn name(&self) -> &str { &self.name.as_deref().unwrap_or("unknown") } -} +} \ No newline at end of file