use super::ContainerMemoryInfo; use bollard::query_parameters::{ListContainersOptions, StatsOptions}; use bollard::Docker; use futures_util::stream::TryStreamExt; use std::error::Error; /// Get memory statistics for all containers pub async fn get_all_containers_memory_stats( docker: &Docker, ) -> Result, Box> { let containers = docker .list_containers(Some(ListContainersOptions { all: true, ..Default::default() })) .await?; let mut mem_infos = Vec::new(); for container in containers { let id = container.id.unwrap_or_default(); // Skip if no ID if id.is_empty() { continue; } if let Some(mem_info) = get_single_container_memory_stats(docker, &id).await? { mem_infos.push(mem_info); } } Ok(mem_infos) } /// Get memory statistics for a specific container pub async fn get_single_container_memory_stats( docker: &Docker, container_id: &str, ) -> Result, Box> { let mut stats_stream = docker.stats( container_id, Some(StatsOptions { stream: false, one_shot: true, }), ); if let Some(stats) = stats_stream.try_next().await? { if let Some(memory_stats) = &stats.memory_stats { let memory_usage = memory_stats.usage.unwrap_or(0); let memory_limit = memory_stats.limit.unwrap_or(1); // Avoid division by zero let memory_usage_percent = if memory_limit > 0 { (memory_usage as f64 / memory_limit as f64) * 100.0 } else { 0.0 }; return Ok(Some(ContainerMemoryInfo { container_id: Some(container_id.to_string()), memory_usage: Some(memory_usage), memory_limit: Some(memory_limit), memory_usage_percent: Some(memory_usage_percent), })); } } Ok(None) } /// Get total memory usage across all containers pub async fn get_total_memory_usage(docker: &Docker) -> Result> { let mem_infos = get_all_containers_memory_stats(docker).await?; let total_memory: u64 = mem_infos.iter().map(|mem| mem.memory_usage.unwrap()).sum(); Ok(total_memory) }