gardesk/gartop / fdeca24

Browse files

Add network and disk rate summaries to header bar

Header now shows: CPU: x% MEM: x% NET: x/s DISK: x/s up Xm
- Network rate is sum of rx+tx across all interfaces
- Disk rate is sum of read+write across all devices
- Rates displayed in compact format (K/s, M/s, G/s)
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
fdeca2437f9767d37dd5054afbd00a7f8189ae5c
Parents
358d0c1
Tree
8d2d88b

2 changed files

StatusFile+-
M gartop/src/gui/app.rs 12 1
M gartop/src/gui/header.rs 48 3
gartop/src/gui/app.rsmodified
@@ -268,7 +268,18 @@ impl App {
268268
         let uptime = self.status.as_ref().map(|s| s.uptime_secs).unwrap_or(0);
269269
         let cpu = self.cpu_stats.as_ref().map(|s| s.usage_percent as f32).unwrap_or(0.0);
270270
         let mem = self.memory_stats.as_ref().map(|s| s.usage_percent as f32).unwrap_or(0.0);
271
-        self.header.update(uptime, cpu, mem);
271
+
272
+        // Sum network rates across all interfaces
273
+        let net_rate: f64 = self.network_stats.iter()
274
+            .map(|s| s.rx_rate + s.tx_rate)
275
+            .sum();
276
+
277
+        // Sum disk rates across all devices
278
+        let disk_rate: f64 = self.disk_stats.iter()
279
+            .map(|s| s.read_rate + s.write_rate)
280
+            .sum();
281
+
282
+        self.header.update(uptime, cpu, mem, net_rate, disk_rate);
272283
     }
273284
 
274285
     /// Render the entire UI.
gartop/src/gui/header.rsmodified
@@ -10,6 +10,8 @@ pub struct HeaderBar {
1010
     uptime: String,
1111
     cpu_usage: f32,
1212
     memory_usage: f32,
13
+    net_rate: f64,   // Combined rx+tx bytes/sec
14
+    disk_rate: f64,  // Combined read+write bytes/sec
1315
 }
1416
 
1517
 impl HeaderBar {
@@ -20,14 +22,18 @@ impl HeaderBar {
2022
             uptime: String::from("0s"),
2123
             cpu_usage: 0.0,
2224
             memory_usage: 0.0,
25
+            net_rate: 0.0,
26
+            disk_rate: 0.0,
2327
         }
2428
     }
2529
 
2630
     /// Update header with current stats.
27
-    pub fn update(&mut self, uptime_secs: u64, cpu: f32, memory: f32) {
31
+    pub fn update(&mut self, uptime_secs: u64, cpu: f32, memory: f32, net_rate: f64, disk_rate: f64) {
2832
         self.uptime = format_uptime(uptime_secs);
2933
         self.cpu_usage = cpu;
3034
         self.memory_usage = memory;
35
+        self.net_rate = net_rate;
36
+        self.disk_rate = disk_rate;
3137
     }
3238
 
3339
     /// Render the header bar.
@@ -68,26 +74,46 @@ impl HeaderBar {
6874
             ..stats_style.clone()
6975
         };
7076
 
77
+        // Network indicator
78
+        let net_text = format!("NET: {}", format_rate(self.net_rate));
79
+        let net_style = TextStyle {
80
+            color: theme.network_color,
81
+            ..stats_style.clone()
82
+        };
83
+
84
+        // Disk indicator
85
+        let disk_text = format!("DISK: {}", format_rate(self.disk_rate));
86
+        let disk_style = TextStyle {
87
+            color: theme.disk_color,
88
+            ..stats_style.clone()
89
+        };
90
+
7191
         // Uptime
7292
         let uptime_text = format!("up {}", self.uptime);
7393
 
7494
         // Position from right side
7595
         let right_margin = 16.0;
76
-        let spacing = 20.0;
96
+        let spacing = 16.0;
7797
         let y = self.bounds.y as f64 + (self.bounds.height as f64 * 0.4) + 6.0;
7898
 
7999
         let uptime_width = renderer.measure_text(&uptime_text, &stats_style)?.width as f64;
100
+        let disk_width = renderer.measure_text(&disk_text, &disk_style)?.width as f64;
101
+        let net_width = renderer.measure_text(&net_text, &net_style)?.width as f64;
80102
         let mem_width = renderer.measure_text(&mem_text, &mem_style)?.width as f64;
81103
         let cpu_width = renderer.measure_text(&cpu_text, &cpu_style)?.width as f64;
82104
 
83105
         let right_edge = (self.bounds.x + self.bounds.width as i32) as f64;
84106
 
85107
         let uptime_x = right_edge - right_margin - uptime_width;
86
-        let mem_x = uptime_x - spacing - mem_width;
108
+        let disk_x = uptime_x - spacing - disk_width;
109
+        let net_x = disk_x - spacing - net_width;
110
+        let mem_x = net_x - spacing - mem_width;
87111
         let cpu_x = mem_x - spacing - cpu_width;
88112
 
89113
         renderer.text(&cpu_text, cpu_x, y, &cpu_style)?;
90114
         renderer.text(&mem_text, mem_x, y, &mem_style)?;
115
+        renderer.text(&net_text, net_x, y, &net_style)?;
116
+        renderer.text(&disk_text, disk_x, y, &disk_style)?;
91117
         renderer.text(&uptime_text, uptime_x, y, &stats_style)?;
92118
 
93119
         Ok(())
@@ -111,3 +137,22 @@ fn format_uptime(secs: u64) -> String {
111137
         format!("{}d {}h", secs / 86400, (secs % 86400) / 3600)
112138
     }
113139
 }
140
+
141
+/// Format rate (bytes/second) to compact human-readable string.
142
+fn format_rate(bytes_per_sec: f64) -> String {
143
+    const KIB: f64 = 1024.0;
144
+    const MIB: f64 = KIB * 1024.0;
145
+    const GIB: f64 = MIB * 1024.0;
146
+
147
+    if bytes_per_sec >= GIB {
148
+        format!("{:.1}G/s", bytes_per_sec / GIB)
149
+    } else if bytes_per_sec >= MIB {
150
+        format!("{:.1}M/s", bytes_per_sec / MIB)
151
+    } else if bytes_per_sec >= KIB {
152
+        format!("{:.0}K/s", bytes_per_sec / KIB)
153
+    } else if bytes_per_sec > 0.0 {
154
+        format!("{:.0}B/s", bytes_per_sec)
155
+    } else {
156
+        "0".to_string()
157
+    }
158
+}