168 lines
4.9 KiB
Rust
168 lines
4.9 KiB
Rust
use std::fs::File;
|
||
use std::io::{self, BufRead, BufReader};
|
||
use std::thread;
|
||
use std::time::Duration;
|
||
|
||
use crate::common;
|
||
use crate::bar_modules;
|
||
|
||
#[derive(Debug, Default, Clone)]
|
||
struct CpuTimes {
|
||
user: u64,
|
||
nice: u64,
|
||
system: u64,
|
||
idle: u64,
|
||
iowait: u64,
|
||
irq: u64,
|
||
softirq: u64,
|
||
steal: u64,
|
||
guest: u64,
|
||
guest_nice: u64,
|
||
}
|
||
|
||
impl CpuTimes {
|
||
pub fn new() -> Self {
|
||
CpuTimes {
|
||
user: 0,
|
||
nice: 0,
|
||
system: 0,
|
||
idle: 0,
|
||
iowait: 0,
|
||
irq: 0,
|
||
softirq: 0,
|
||
steal: 0,
|
||
guest: 0,
|
||
guest_nice: 0
|
||
}
|
||
}
|
||
|
||
fn total(&self) -> u64 {
|
||
self.user
|
||
+ self.nice
|
||
+ self.system
|
||
+ self.idle
|
||
+ self.iowait
|
||
+ self.irq
|
||
+ self.softirq
|
||
+ self.steal
|
||
+ self.guest
|
||
+ self.guest_nice
|
||
}
|
||
|
||
fn idle(&self) -> u64 {
|
||
self.idle + self.iowait
|
||
}
|
||
}
|
||
|
||
#[derive(Clone)]
|
||
pub struct UnibarModuleCpu {
|
||
opts: common::AppOptions,
|
||
cpu_times_sample_1: CpuTimes,
|
||
cpu_times_sample_2: CpuTimes,
|
||
}
|
||
|
||
impl UnibarModuleCpu {
|
||
|
||
// --------------------
|
||
pub fn new(o :common::AppOptions) -> Self {
|
||
UnibarModuleCpu {
|
||
opts: o,
|
||
cpu_times_sample_1: CpuTimes::new(),
|
||
cpu_times_sample_2: CpuTimes::new(),
|
||
}
|
||
}
|
||
|
||
// --------------------
|
||
// cpu 242109 7 60985 6538626 8344 39138 9647 0 0 0
|
||
// * user – time spent in user mode
|
||
// * nice – time spent processing nice processes in user mode
|
||
// * system – time spent executing kernel code
|
||
// * idle – time spent idle
|
||
// * iowait – time spent waiting for I/O
|
||
// * irq – time spent servicing interrupts
|
||
// * softirq – time spent servicing software interrupts
|
||
// * steal – time stolen from a virtual machine
|
||
// * guest – time spent running a virtual CPU for a guest operating system
|
||
// * guest_nice – time spent running a virtual CPU for a “niced” guest operating system
|
||
fn read_cpu_times(&self) -> io::Result<CpuTimes> {
|
||
let file = File::open("/proc/stat")?;
|
||
let reader = BufReader::new(file);
|
||
|
||
for line in reader.lines() {
|
||
let line = line?;
|
||
if line.starts_with("cpu ") {
|
||
let fields: Vec<u64> = line.split_whitespace().skip(1).map(|s| s.parse().unwrap_or(0)).collect();
|
||
|
||
if fields.len() >= 8 {
|
||
return Ok(CpuTimes {
|
||
user: fields[0],
|
||
nice: fields[1],
|
||
system: fields[2],
|
||
idle: fields[3],
|
||
iowait: fields[4],
|
||
irq: fields[5],
|
||
softirq: fields[6],
|
||
steal: fields[7],
|
||
guest: if fields.len() > 8 { fields[8] } else { 0 },
|
||
guest_nice: if fields.len() > 9 { fields[9] } else { 0 },
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
Err(io::Error::new(io::ErrorKind::InvalidData, "Could not find cpu line in /proc/stat"))
|
||
}
|
||
}
|
||
|
||
impl bar_modules::BarModuleActions for UnibarModuleCpu {
|
||
|
||
// --------------------
|
||
fn clear(&mut self) {
|
||
self.cpu_times_sample_1 = CpuTimes::new();
|
||
self.cpu_times_sample_2 = CpuTimes::new();
|
||
}
|
||
|
||
// --------------------
|
||
fn generate_data(&mut self) {
|
||
self.cpu_times_sample_1 = self.read_cpu_times().expect("Trouble getting CPU times sample 1");
|
||
thread::sleep(Duration::from_millis(500));
|
||
self.cpu_times_sample_2 = self.read_cpu_times().expect("Trouble getting CPU times sample 2");
|
||
|
||
if self.opts.debug {
|
||
println!("-----> CPU times sample 1 - {:#?}", self.cpu_times_sample_1);
|
||
println!("-----> CPU times sample 2 - {:#?}", self.cpu_times_sample_2);
|
||
}
|
||
}
|
||
|
||
// --------------------
|
||
fn get_content(&self) -> String {
|
||
let sample_1_total = self.cpu_times_sample_1.total();
|
||
let sample_2_total = self.cpu_times_sample_2.total();
|
||
|
||
let sample_1_idle = self.cpu_times_sample_1.idle();
|
||
let sample_2_idle = self.cpu_times_sample_2.idle();
|
||
|
||
let total_diff = sample_2_total - sample_1_total;
|
||
let idle_diff = sample_2_idle - sample_1_idle;
|
||
|
||
if total_diff > 0 {
|
||
let cpu_usage = (1.0 - (idle_diff as f64 / total_diff as f64)) * 100.0;
|
||
return format!("{}%", cpu_usage.ceil() as i32);
|
||
} else {
|
||
return format!("CPU?");
|
||
}
|
||
}
|
||
|
||
// --------------------
|
||
fn get_icon(&self) -> String {
|
||
return "💻".to_string();
|
||
}
|
||
}
|
||
|
||
impl bar_modules::BarModuleDebug for UnibarModuleCpu {
|
||
|
||
// --------------------
|
||
fn post_debug(&self) {
|
||
}
|
||
}
|