From 630d2ff674139b6d77a36b1b01adcf9dd9897586 Mon Sep 17 00:00:00 2001 From: Christoffer Martinsson Date: Tue, 14 Oct 2025 10:14:24 +0200 Subject: [PATCH] Add disk quota display to services widget Implement disk quota/total display in services widget showing usage/quota format. When services don't have specific disk quotas configured, use system total disk capacity as the quota value. Changes: - Add disk_quota_gb field to ServiceData struct in agent - Add disk_quota_gb field to ServiceInfo struct in dashboard - Update format_disk_value to show usage/quota format - Use system disk total capacity as default quota for services - Rename DiskUsage.total_gb to total_capacity_gb for clarity Services will now display disk usage as "5.2/500.0 GB" format where 500.0 GB is either the service's specific quota or system total capacity. --- agent/src/collectors/service.rs | 21 ++++++++++++++++----- dashboard/src/data/metrics.rs | 2 ++ dashboard/src/ui/services.rs | 13 +++++++++---- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/agent/src/collectors/service.rs b/agent/src/collectors/service.rs index 74f0b85..2eb8fc6 100644 --- a/agent/src/collectors/service.rs +++ b/agent/src/collectors/service.rs @@ -113,6 +113,7 @@ impl ServiceCollector { cpu_percent, sandbox_limit: None, // TODO: Implement sandbox limit detection disk_used_gb, + disk_quota_gb: 0.0, // Will be set to system total in collect() description, sub_service: None, }) @@ -331,7 +332,7 @@ impl ServiceCollector { }; Ok(DiskUsage { - total_gb: parse_size(parts[0])?, + total_capacity_gb: parse_size(parts[0])?, used_gb: parse_size(parts[1])?, }) } @@ -1122,6 +1123,7 @@ impl Collector for ServiceCollector { cpu_percent: 0.0, sandbox_limit: None, disk_used_gb: 0.0, + disk_quota_gb: 0.0, description: None, sub_service: Some("nginx".to_string()), }); @@ -1147,6 +1149,7 @@ impl Collector for ServiceCollector { cpu_percent: 0.0, sandbox_limit: None, disk_used_gb: 0.0, + disk_quota_gb: 0.0, description: None, sub_service: Some("docker".to_string()), }); @@ -1168,6 +1171,7 @@ impl Collector for ServiceCollector { cpu_percent: 0.0, sandbox_limit: None, disk_used_gb: 0.0, + disk_quota_gb: 0.0, description: None, sub_service: None, }); @@ -1176,12 +1180,18 @@ impl Collector for ServiceCollector { } } - - let _disk_usage = self.get_disk_usage().await.unwrap_or(DiskUsage { - total_gb: 0.0, + let disk_usage = self.get_disk_usage().await.unwrap_or(DiskUsage { + total_capacity_gb: 0.0, used_gb: 0.0, }); + // Set disk quota to system total capacity for services that don't have specific quotas + let system_disk_capacity_gb = disk_usage.total_capacity_gb; + for service in &mut services { + if service.disk_quota_gb == 0.0 { + service.disk_quota_gb = system_disk_capacity_gb; + } + } // Calculate overall services status let services_status = self.determine_services_status(healthy, degraded, failed); @@ -1226,6 +1236,7 @@ struct ServiceData { cpu_percent: f32, sandbox_limit: Option, disk_used_gb: f32, + disk_quota_gb: f32, #[serde(skip_serializing_if = "Option::is_none")] description: Option>, #[serde(default)] @@ -1243,6 +1254,6 @@ enum ServiceStatus { #[allow(dead_code)] struct DiskUsage { - total_gb: f32, + total_capacity_gb: f32, used_gb: f32, } diff --git a/dashboard/src/data/metrics.rs b/dashboard/src/data/metrics.rs index c0c37b4..cb0acff 100644 --- a/dashboard/src/data/metrics.rs +++ b/dashboard/src/data/metrics.rs @@ -117,6 +117,8 @@ pub struct ServiceInfo { #[serde(default)] pub disk_used_gb: f32, #[serde(default)] + pub disk_quota_gb: f32, + #[serde(default)] pub description: Option>, #[serde(default)] pub sub_service: Option, diff --git a/dashboard/src/ui/services.rs b/dashboard/src/ui/services.rs index f7142be..8c80d74 100644 --- a/dashboard/src/ui/services.rs +++ b/dashboard/src/ui/services.rs @@ -126,7 +126,7 @@ fn render_metrics( svc.name.clone(), format_memory_value(svc.memory_used_mb, svc.memory_quota_mb), format_cpu_value(svc.cpu_percent), - format_disk_value(svc.disk_used_gb), + format_disk_value(svc.disk_used_gb, svc.disk_quota_gb), ], ); } @@ -158,14 +158,19 @@ fn format_cpu_value(cpu_percent: f32) -> String { } } -fn format_disk_value(used: f32) -> String { - if used >= 1.0 { +fn format_disk_value(used: f32, quota: f32) -> String { + if quota > 0.05 { + // Show usage/quota format when quota is set + format!("{:.1}/{:.1} GB", used, quota) + } else if used >= 1.0 { format!("{:.1} GB", used) } else if used >= 0.001 { // 1 MB or more format!("{:.0} MB", used * 1000.0) - } else { + } else if used > 0.0 { "<1 MB".to_string() + } else { + "—".to_string() // Em dash for no disk usage } }