diff --git a/src/sensors/mod.rs b/src/sensors/mod.rs index c15e4525..5b573de7 100644 --- a/src/sensors/mod.rs +++ b/src/sensors/mod.rs @@ -247,10 +247,8 @@ impl Topology { /// Generates CPUCore instances for the host and adds them /// to appropriate CPUSocket instance from self.sockets pub fn add_cpu_cores(&mut self) { - let mut cores = Topology::generate_cpu_cores().unwrap(); - while !cores.is_empty() { - let c = cores.pop().unwrap(); - let socket_id = &c + Topology::generate_cpu_cores().unwrap().into_iter().for_each(|core| { + let socket_id = &core .attributes .get("physical id") .unwrap() @@ -262,9 +260,9 @@ impl Topology { .find(|x| &x.id == socket_id) .expect("Trick: if you are running on a vm, do not forget to use --vm parameter invoking scaphandre at the command line"); if socket_id == &socket.id { - socket.add_cpu_core(c); + socket.add_cpu_core(core); } - } + }); } /// Triggers ProcessTracker refresh on process stats @@ -298,10 +296,8 @@ impl Topology { for p in current_procs { let pid = p.pid; - let res = self.proc_tracker.add_process_record(p); - match res { - Ok(_) => {} - Err(msg) => panic!("Failed to track process with pid {} !\nGot: {}", pid, msg), + if let Err(msg) = self.proc_tracker.add_process_record(p) { + panic!("Failed to track process with pid {} !\nGot: {}", pid, msg); } } } @@ -435,47 +431,27 @@ impl Topology { /// Reads content from /proc/stat and extracts the stats of the whole CPU topology. pub fn read_stats(&self) -> Option { - let kernelstats_or_not = KernelStats::new(); - if let Ok(res_cputime) = kernelstats_or_not { - return Some(CPUStat { - cputime: res_cputime.total, - }); - } - None + KernelStats::new() + .ok() + .map(|res| CPUStat { cputime: res.total }) } /// Returns the number of processes currently available pub fn read_nb_process_total_count(&self) -> Option { - if let Ok(result) = KernelStats::new() { - return Some(result.processes); - } - None + KernelStats::new().ok().map(|res| res.processes) } /// Returns the number of processes currently in a running state pub fn read_nb_process_running_current(&self) -> Option { - if let Ok(result) = KernelStats::new() { - if let Some(procs_running) = result.procs_running { - return Some(procs_running); - } - } - None + KernelStats::new().ok().and_then(|res| res.procs_running) } /// Returns the number of processes currently blocked waiting pub fn read_nb_process_blocked_current(&self) -> Option { - if let Ok(result) = KernelStats::new() { - if let Some(procs_blocked) = result.procs_blocked { - return Some(procs_blocked); - } - } - None + KernelStats::new().ok().and_then(|res| res.procs_blocked) } /// Returns the current number of context switches pub fn read_nb_context_switches_total_count(&self) -> Option { - if let Ok(result) = KernelStats::new() { - return Some(result.ctxt); - } - None + KernelStats::new().ok().map(|res| res.ctxt) } /// Returns the power consumed between last and previous measurement for a given process ID, in microwatts @@ -749,35 +725,29 @@ impl CPUSocket { /// Combines stats from all CPU cores owned byu the socket and returns /// a CpuTime struct containing stats for the whole socket. pub fn read_stats(&self) -> Option { - let mut stats = CPUStat { - cputime: CpuTime { - user: 0.0, - nice: 0.0, - system: 0.0, - idle: 0.0, - iowait: Some(0.0), - irq: Some(0.0), - softirq: Some(0.0), - guest: Some(0.0), - guest_nice: Some(0.0), - steal: Some(0.0), - }, - }; - for c in &self.cpu_cores { - let c_stats = c.read_stats().unwrap(); - stats.cputime.user += c_stats.user; - stats.cputime.nice += c_stats.nice; - stats.cputime.system += c_stats.system; - stats.cputime.idle += c_stats.idle; - stats.cputime.iowait = - Some(stats.cputime.iowait.unwrap_or_default() + c_stats.iowait.unwrap_or_default()); - stats.cputime.irq = - Some(stats.cputime.irq.unwrap_or_default() + c_stats.irq.unwrap_or_default()); - stats.cputime.softirq = Some( - stats.cputime.softirq.unwrap_or_default() + c_stats.softirq.unwrap_or_default(), - ); - } - Some(stats) + Some( + self.cpu_cores + .iter() + .fold(CPUStat::default(), |mut stats, c| { + let c_stats = c.read_stats().unwrap(); + stats.cputime.user += c_stats.user; + stats.cputime.nice += c_stats.nice; + stats.cputime.system += c_stats.system; + stats.cputime.idle += c_stats.idle; + stats.cputime.iowait = Some( + stats.cputime.iowait.unwrap_or_default() + + c_stats.iowait.unwrap_or_default(), + ); + stats.cputime.irq = Some( + stats.cputime.irq.unwrap_or_default() + c_stats.irq.unwrap_or_default(), + ); + stats.cputime.softirq = Some( + stats.cputime.softirq.unwrap_or_default() + + c_stats.softirq.unwrap_or_default(), + ); + stats + }), + ) } /// Computes the difference between previous usage statistics record for the socket @@ -1055,6 +1025,25 @@ pub struct CPUStat { pub cputime: CpuTime, } +impl Default for CPUStat { + fn default() -> Self { + Self { + cputime: CpuTime { + user: 0.0, + nice: 0.0, + system: 0.0, + idle: 0.0, + iowait: Some(0.0), + irq: Some(0.0), + softirq: Some(0.0), + guest: Some(0.0), + guest_nice: Some(0.0), + steal: Some(0.0), + }, + } + } +} + impl CPUStat { /// Returns the total of active CPU time spent, for this stat measurement /// (not iowait, idle, irq or softirq) diff --git a/src/sensors/utils.rs b/src/sensors/utils.rs index ac41dd5d..fab8fa9c 100644 --- a/src/sensors/utils.rs +++ b/src/sensors/utils.rs @@ -141,19 +141,20 @@ impl ProcessTracker { /// Returns all vectors of process records linked to a running, sleeping, waiting or zombie process. /// (Not terminated) pub fn get_alive_processes(&self) -> Vec<&Vec> { - let mut res = vec![]; - for p in self.procs.iter() { - if !p.is_empty() { - let status = p[0].process.status(); - if let Ok(status_val) = status { - if !&status_val.state.contains('T') { - // !&status_val.state.contains("Z") && - res.push(p); - } - } - } - } - res + self.procs + .iter() + .filter_map(|p| { + p.first() + .and_then(|p| p.process.status().ok()) + .and_then(|status| { + if !status.state.contains('T') { + Some(p) + } else { + None + } + }) + }) + .collect::>() } /// Extracts the container_id from a cgroup path containing it. @@ -343,18 +344,10 @@ impl ProcessTracker { .iter() .filter(|x| !x.is_empty() && x.get(0).unwrap().process.pid == pid); let process = result.next().unwrap(); - if let Some(vec) = process.get(0) { - if let Ok(mut cmdline_vec) = vec.process.cmdline() { - let mut cmdline = String::from(""); - while !cmdline_vec.is_empty() { - if !cmdline_vec.is_empty() { - cmdline.push_str(&cmdline_vec.remove(0)); - } - } - return Some(cmdline); - } - } - None + process + .get(0) + .and_then(|vec| vec.process.cmdline().ok()) + .map(|vec| vec.join("")) } /// Returns the CPU time consumed between two measure iteration