procstat/
lib.rs

1#![crate_type = "lib"]
2#![crate_name = "procstat"]
3
4use std::collections::HashMap;
5use std::{fs::File, io::{BufRead, BufReader}, path::Path};
6
7mod boot_time;
8mod cpu;
9mod contexts;
10mod interrupts;
11mod processes;
12mod soft_irq;
13
14pub use boot_time::*;
15pub use cpu::*;
16pub use contexts::*;
17pub use interrupts::*;
18pub use processes::*;
19pub use soft_irq::*;
20
21#[derive(Debug)]
22pub struct ProcStat {
23    pub cpu: CPU,
24    pub cpus: HashMap<usize,CPU>,
25    pub interrupts: Interrupts,
26    pub contexts: Contexts,
27    pub boot_time: BootTime,
28    pub processes: Processes,
29    pub soft_irq: SoftIrq,
30}
31
32const KEY_CPU: &str = "cpu";
33const KEY_INTERRUPTS: &str = "intr";
34const KEY_CONTEXTS: &str = "ctxt";
35const KEY_BOOT_TIME: &str = "btime";
36const KEY_SOFT_IRQ: &str = "softirq";
37const KEY_PROCESSES: &str = "processes";
38const KEY_PROCESSES_RUNNING: &str = "procs_running";
39const KEY_PROCESSES_BLOCKED: &str = "procs_blocked";
40
41impl ProcStat {
42    fn empty() -> Self {
43        Self {
44            cpu: CPU::empty(),
45            cpus: HashMap::new(),
46            interrupts: Interrupts::empty(),
47            contexts: Contexts::empty(),
48            boot_time: BootTime::empty(),
49            processes: Processes::empty(),
50            soft_irq: SoftIrq::empty(),
51        }
52    }
53
54    pub fn read() -> ProcStat {
55
56        let file = File::open(Path::new("/proc/stat")).unwrap();
57        
58        ProcStat::read_file(file)
59    }
60
61    pub fn read_file(file: File) -> ProcStat {
62        let mut proc_stat = Self::empty();
63
64        let reader = BufReader::new(file);
65        for line in reader.lines() {
66            let line = line.unwrap();
67            let mut tokenised = line.split_whitespace();
68            let key = tokenised.next().unwrap_or("");
69            let values: Vec<u64> = tokenised.by_ref().map(|t| u64::from_str_radix(t, 10).unwrap_or_default()).collect();
70
71            if key.eq(KEY_CPU) {
72                proc_stat.cpu = CPU::from_vec(values);
73            } else if key.starts_with(KEY_CPU) {
74                let cpu = CPU::from_vec(values);
75                let cpu_index = usize::from_str_radix(key.split_at(3).1, 10).unwrap();
76                proc_stat.cpus.insert(cpu_index, cpu);
77            } else if key.eq(KEY_INTERRUPTS) {
78                proc_stat.interrupts = Interrupts::from_vec(values);
79            } else if key.eq(KEY_CONTEXTS) {
80                proc_stat.contexts = Contexts::from_vec(values);
81            } else if key.eq(KEY_BOOT_TIME) {
82                proc_stat.boot_time = BootTime::from_vec(values);
83            } else if key.eq(KEY_SOFT_IRQ) {
84                proc_stat.soft_irq = SoftIrq::from_vec(values);
85            } else if key.eq(KEY_PROCESSES) {
86                proc_stat.processes.forks_since_boot = *values.first().unwrap();
87            } else if key.eq(KEY_PROCESSES_RUNNING) {
88                proc_stat.processes.running_processes = *values.first().unwrap();
89            } else if key.eq(KEY_PROCESSES_BLOCKED) {
90                proc_stat.processes.blocked_processes = *values.first().unwrap();
91            }
92        }
93
94        proc_stat
95    }
96}