#[cfg(target_os = "linux")]
use one_collect::perf_event::{
self,
PerfSession,
RingBufBuilder,
RingBufSessionBuilder
};
#[cfg(target_os = "linux")]
use one_collect::Writable;
#[cfg(target_os = "linux")]
struct Utilization {
per_cpu: Vec<u64>,
temp: String,
}
#[cfg(target_os = "linux")]
impl Utilization {
fn create() -> Self {
#[cfg(target_os = "linux")]
let cpu_count = perf_event::cpu_count() as usize;
#[cfg(target_os = "windows")]
let cpu_count = 1;
let mut per_cpu = Vec::new();
per_cpu.resize(cpu_count, 0);
Self {
per_cpu,
temp: String::new(),
}
}
#[cfg(target_os = "linux")]
fn new(session: &mut PerfSession) -> Writable<Self> {
let util = Writable::new(Self::create());
let ancillary = session.ancillary_data();
let session_util = util.clone();
session
.cpu_profile_event()
.add_callback(move |_| {
let mut cpu: u32 = 0;
ancillary.read(|values| {
cpu = values.cpu();
});
session_util.write(|usage| {
usage.per_cpu[cpu as usize] += 1;
});
Ok(())
});
util
}
fn report(&mut self) {
let mut all = 0u64;
println!(concat!(
"\x1b[H\x1b[J\x1b[4m",
"CPU│",
" ",
"Utilization",
" ",
" │ %\x1b[0m"));
for (cpu,total) in self.per_cpu.iter().enumerate() {
Self::print_graph(&mut self.temp, Some(cpu), *total);
all += total;
}
let total = all / self.per_cpu.len() as u64;
Self::print_graph(&mut self.temp, None, total);
for total in &mut self.per_cpu {
*total = 0;
}
}
fn print_graph(
temp: &mut String,
cpu: Option<usize>,
mut total: u64) {
if total > 100 {
total = 100;
}
let notches = total / 2;
temp.clear();
match total {
0..=25 => { temp.push_str("\x1b[1;30;1m"); },
26..=75 => { temp.push_str("\x1b[1;33m"); },
_ => { temp.push_str("\x1b[1;31m"); }
}
for _ in 0..notches {
temp.push('─');
}
temp.push_str("\x1b[0m");
for _ in notches..50 {
temp.push(' ');
}
match cpu {
Some(cpu) => {
println!("{:3}│ {} │{:2}%", cpu, temp, total);
},
None => {
println!("SUM│ {} │{:2}%", temp, total);
}
}
}
}
#[cfg(target_os = "linux")]
fn main() {
let one_sec = std::time::Duration::from_secs(1);
let need_permission = "Need permission (run via sudo?)";
let freq = 100;
let cpu = RingBufBuilder::for_profiling(freq);
let mut session = RingBufSessionBuilder::new()
.with_page_count(4)
.with_profiling_events(cpu)
.build()
.expect(need_permission);
let util = Utilization::new(&mut session);
loop {
util.write(|util| { util.report(); });
session.enable().expect(need_permission);
std::thread::sleep(one_sec);
session.disable().expect(need_permission);
session.parse_all().expect(need_permission);
}
}
#[cfg(target_os = "windows")]
fn main() {
println!("Coming soon");
}