diff --git a/agent/src/cpu.rs b/agent/src/cpu.rs index 6d8a7c9..71293f9 100644 --- a/agent/src/cpu.rs +++ b/agent/src/cpu.rs @@ -1,7 +1,8 @@ use std::collections::HashMap; +use anyhow::anyhow; use common::metrics::CPUBreakdown; -#[derive(Debug, Clone, Copy)] +#[derive(Default, Debug, Clone, Copy)] struct CPUValues { pub user: u64, pub nice: u64, @@ -43,26 +44,33 @@ impl CPUStatReader { } fn parse_cpu_line(&mut self, line: &str) -> anyhow::Result { - let parts: Vec<&str> = line.split_whitespace().collect(); + let mut parts = line.split_whitespace(); - let cpu_name = parts[0].to_string(); + let cpu_name = parts.next() + .ok_or_else(|| anyhow!("missing cpu name"))? + .to_string(); - let parse = |num: usize| -> u64 { - parts[num].parse().ok().unwrap() - }; + let mut values = CPUValues::default(); + let mut fields = [ + &mut values.user, + &mut values.nice, + &mut values.system, + &mut values.idle, + &mut values.iowait, + &mut values.irq, + &mut values.softirq, + &mut values.steal, + &mut values.guest, + &mut values.guest_nice, + ]; - let values = CPUValues { - user: parse(1), - nice: parse(2), - system: parse(3), - idle: parse(4), - iowait: parse(5), - irq: parse(6), - softirq: parse(7), - steal: parse(8), - guest: parse(9), - guest_nice: parse(10), - }; + for (field, part) in fields.iter_mut().zip(&mut parts) { + **field = part.parse()?; + } + + if fields.iter().any(|f| **f == 0 && parts.next().is_some()) { + return Err(anyhow!("invalid cpu line")); + } let previous = self.previous_stats.get(&cpu_name).copied(); let percentages = self.calculate_percentages(&values, previous);