Compare commits
3 Commits
8bad155f15
...
750a2813d3
Author | SHA1 | Date | |
---|---|---|---|
750a2813d3
|
|||
c84e9698d7
|
|||
e6719dc6f5
|
183
src/bar_modules/bar_module_cpu.rs
Normal file
183
src/bar_modules/bar_module_cpu.rs
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
use std::fs::File;
|
||||||
|
// use std::path::Path;
|
||||||
|
// use std::io::prelude::*;
|
||||||
|
// use regex::Regex;
|
||||||
|
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 generate_data(&mut self) {
|
||||||
|
self.cpu_times_sample_1 = self.read_cpu_times().expect("REASON");
|
||||||
|
thread::sleep(Duration::from_millis(1000));
|
||||||
|
self.cpu_times_sample_2 = self.read_cpu_times().expect("REASON");
|
||||||
|
|
||||||
|
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?");
|
||||||
|
}
|
||||||
|
// let re = Regex::new(r"cpu\s+.*").unwrap();
|
||||||
|
// let caps = re.captures(self.procstat_str.as_str()).unwrap();
|
||||||
|
|
||||||
|
// let cpu_line = caps.get(0).unwrap().as_str();
|
||||||
|
// if self.opts.debug {
|
||||||
|
// println!("-----> CPU line - {:#?}", cpu_line);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let binding = Regex::new(r"\s+").unwrap();
|
||||||
|
// let mut parts :Vec<&str> = binding.split(cpu_line).collect();
|
||||||
|
|
||||||
|
// parts.remove(0); // Remove the 'cpu' part
|
||||||
|
|
||||||
|
// let cpu_idle :f32 = parts[3].parse::<f32>().unwrap();
|
||||||
|
// let mut cpu_total :f32 = 0.0;
|
||||||
|
// for usg in parts {
|
||||||
|
// cpu_total += usg.parse::<f32>().unwrap();
|
||||||
|
// }
|
||||||
|
// return format!("{}%", (((cpu_total - cpu_idle)/cpu_total) * 100.0).ceil() as i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn get_icon(&self) -> String {
|
||||||
|
return "💻".to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl bar_modules::BarModuleDebug for UnibarModuleCpu {
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
fn post_debug(&self) {
|
||||||
|
}
|
||||||
|
}
|
@@ -29,7 +29,7 @@ impl bar_modules::BarModuleActions for UnibarModuleMemory {
|
|||||||
fn generate_data(&mut self) {
|
fn generate_data(&mut self) {
|
||||||
let path = Path::new("/proc/meminfo");
|
let path = Path::new("/proc/meminfo");
|
||||||
|
|
||||||
// Contents of '/process/meminfo' has memory information
|
// Contents of '/proc/meminfo' has memory information
|
||||||
let mut meminfo_file = match File::open(&path) {
|
let mut meminfo_file = match File::open(&path) {
|
||||||
Err(why) => panic!("couldn't open {}: {}", path.display(), why),
|
Err(why) => panic!("couldn't open {}: {}", path.display(), why),
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
@@ -37,7 +37,7 @@ impl bar_modules::BarModuleActions for UnibarModuleMemory {
|
|||||||
|
|
||||||
match meminfo_file.read_to_string(&mut self.meminfo_str) {
|
match meminfo_file.read_to_string(&mut self.meminfo_str) {
|
||||||
Err(why) => panic!("couldn't read {}: {}", path.display(), why),
|
Err(why) => panic!("couldn't read {}: {}", path.display(), why),
|
||||||
Ok(_) => if self.opts.debug_json {
|
Ok(_) => if self.opts.debug {
|
||||||
println!("-----> meminfo - {:#?}", self.meminfo_str);
|
println!("-----> meminfo - {:#?}", self.meminfo_str);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -48,12 +48,12 @@ impl bar_modules::BarModuleActions for UnibarModuleMemory {
|
|||||||
// --------------------
|
// --------------------
|
||||||
// MemTotal: 7822812 kB\nMemFree: 399244 kB\nMemAvailable: 3986504 kB
|
// MemTotal: 7822812 kB\nMemFree: 399244 kB\nMemAvailable: 3986504 kB
|
||||||
fn get_content(&self) -> String {
|
fn get_content(&self) -> String {
|
||||||
let re = Regex::new(r"MemTotal:\s+(\d+)\s+kB\nMemFree:\s+(\d+)").unwrap();
|
let re = Regex::new(r"MemTotal:\s+(\d+)\s+kB\nMemFree:\s+(\d+)\s+kB\nMemAvailable:\s+(\d+)").unwrap();
|
||||||
let caps = re.captures(self.meminfo_str.as_str()).unwrap();
|
let caps = re.captures(self.meminfo_str.as_str()).unwrap();
|
||||||
|
|
||||||
let total_mem :f32 = caps.get(1).unwrap().as_str().parse::<f32>().unwrap();
|
let total_mem :f32 = caps.get(1).unwrap().as_str().parse::<f32>().unwrap();
|
||||||
let free_mem :f32 = caps.get(2).unwrap().as_str().parse::<f32>().unwrap();
|
let avail_mem :f32 = caps.get(3).unwrap().as_str().parse::<f32>().unwrap();
|
||||||
return format!("{}%", ((total_mem - free_mem)/total_mem * 100.0).ceil() as i32);
|
return format!("{}%", ((total_mem - avail_mem)/total_mem * 100.0).ceil() as i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
|
@@ -41,7 +41,7 @@ impl bar_modules::BarModuleActions for UnibarModuleNetwork {
|
|||||||
let network_data: Value = serde_json::from_str::<Value>(self.ip_addr_stdout.as_str()).unwrap();
|
let network_data: Value = serde_json::from_str::<Value>(self.ip_addr_stdout.as_str()).unwrap();
|
||||||
|
|
||||||
if let Some(interfaces) = network_data.as_array() {
|
if let Some(interfaces) = network_data.as_array() {
|
||||||
if self.opts.debug_json {
|
if self.opts.debug {
|
||||||
println!("-----> network_data - {:#?}", network_data);
|
println!("-----> network_data - {:#?}", network_data);
|
||||||
}
|
}
|
||||||
// Get all interfaces that are up
|
// Get all interfaces that are up
|
||||||
@@ -58,7 +58,7 @@ impl bar_modules::BarModuleActions for UnibarModuleNetwork {
|
|||||||
.filter(|ai| ai["scope"].as_str().unwrap().contains("global"))
|
.filter(|ai| ai["scope"].as_str().unwrap().contains("global"))
|
||||||
.cloned().collect();
|
.cloned().collect();
|
||||||
if inet_addr.len() > 0 {
|
if inet_addr.len() > 0 {
|
||||||
if self.opts.debug_json {
|
if self.opts.debug {
|
||||||
println!("-----> Inet Addr - {:#?}", inet_addr);
|
println!("-----> Inet Addr - {:#?}", inet_addr);
|
||||||
}
|
}
|
||||||
self.network_info = inet_addr[0].clone();
|
self.network_info = inet_addr[0].clone();
|
||||||
@@ -66,7 +66,7 @@ impl bar_modules::BarModuleActions for UnibarModuleNetwork {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.opts.debug_json {
|
if self.opts.debug {
|
||||||
println!("-----> ip_addr - {:#?}", self.network_info);
|
println!("-----> ip_addr - {:#?}", self.network_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -175,7 +175,7 @@ impl bar_modules::BarModuleActions for UnibarModuleWeather {
|
|||||||
}).unwrap();
|
}).unwrap();
|
||||||
transfer.perform().unwrap();
|
transfer.perform().unwrap();
|
||||||
}
|
}
|
||||||
if self.opts.debug_json {
|
if self.opts.debug {
|
||||||
println!("-----> curl_data - [{}]", std::str::from_utf8(&curl_ret).unwrap());
|
println!("-----> curl_data - [{}]", std::str::from_utf8(&curl_ret).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,3 +21,4 @@ pub mod bar_module_weather;
|
|||||||
pub mod bar_module_music;
|
pub mod bar_module_music;
|
||||||
pub mod bar_module_network;
|
pub mod bar_module_network;
|
||||||
pub mod bar_module_memory;
|
pub mod bar_module_memory;
|
||||||
|
pub mod bar_module_cpu;
|
||||||
|
@@ -26,6 +26,6 @@ pub struct AppOptions {
|
|||||||
pub weather_units: TemperatureUnits,
|
pub weather_units: TemperatureUnits,
|
||||||
pub weather_station: String,
|
pub weather_station: String,
|
||||||
pub music_progress: bool,
|
pub music_progress: bool,
|
||||||
pub debug_json: bool,
|
pub debug: bool,
|
||||||
pub debug_modules: bool,
|
pub debug_icons: bool,
|
||||||
}
|
}
|
||||||
|
14
src/main.rs
14
src/main.rs
@@ -28,11 +28,11 @@ struct CommandlineArgs {
|
|||||||
|
|
||||||
/// Show JSON data returned by query
|
/// Show JSON data returned by query
|
||||||
#[arg(short = 'D', long)]
|
#[arg(short = 'D', long)]
|
||||||
debug_json: bool,
|
debug: bool,
|
||||||
|
|
||||||
/// Show ICON debug information
|
/// Show ICON debug information
|
||||||
#[arg(short = 'I', long)]
|
#[arg(short = 'I', long)]
|
||||||
debug_modules: bool,
|
debug_icons: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -46,7 +46,7 @@ struct Unibar {
|
|||||||
impl Unibar {
|
impl Unibar {
|
||||||
// --------------------
|
// --------------------
|
||||||
fn run(&self) {
|
fn run(&self) {
|
||||||
if self.opts.debug_json {
|
if self.opts.debug {
|
||||||
self.debug_msg("Debugging ...");
|
self.debug_msg("Debugging ...");
|
||||||
}
|
}
|
||||||
self.check_options();
|
self.check_options();
|
||||||
@@ -55,6 +55,7 @@ impl Unibar {
|
|||||||
let bar_modules_enabled: Vec<Box<dyn bar_modules::BarModuleActions>> = vec! [
|
let bar_modules_enabled: Vec<Box<dyn bar_modules::BarModuleActions>> = vec! [
|
||||||
Box::new(bar_modules::bar_module_music::UnibarModuleMusic::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_music::UnibarModuleMusic::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_memory::UnibarModuleMemory::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_memory::UnibarModuleMemory::new(self.opts.clone())),
|
||||||
|
Box::new(bar_modules::bar_module_cpu::UnibarModuleCpu::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_network::UnibarModuleNetwork::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_network::UnibarModuleNetwork::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather::new(self.opts.clone())),
|
||||||
];
|
];
|
||||||
@@ -79,12 +80,13 @@ impl Unibar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show module debug information if enabled
|
// Show module debug information if enabled
|
||||||
if self.opts.debug_modules {
|
if self.opts.debug_icons {
|
||||||
let bar_modules_debugged: Vec<Box<dyn bar_modules::BarModuleDebug>> = vec! [
|
let bar_modules_debugged: Vec<Box<dyn bar_modules::BarModuleDebug>> = vec! [
|
||||||
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_weather::UnibarModuleWeather::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_music::UnibarModuleMusic::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_music::UnibarModuleMusic::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_memory::UnibarModuleMemory::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_memory::UnibarModuleMemory::new(self.opts.clone())),
|
||||||
Box::new(bar_modules::bar_module_network::UnibarModuleNetwork::new(self.opts.clone())),
|
Box::new(bar_modules::bar_module_network::UnibarModuleNetwork::new(self.opts.clone())),
|
||||||
|
Box::new(bar_modules::bar_module_cpu::UnibarModuleCpu::new(self.opts.clone())),
|
||||||
];
|
];
|
||||||
for md in bar_modules_debugged {
|
for md in bar_modules_debugged {
|
||||||
md.post_debug();
|
md.post_debug();
|
||||||
@@ -122,8 +124,8 @@ fn main() {
|
|||||||
else { common::TemperatureUnits::Imperial },
|
else { common::TemperatureUnits::Imperial },
|
||||||
weather_station: cmd_args.weather_station,
|
weather_station: cmd_args.weather_station,
|
||||||
music_progress: cmd_args.music_progress,
|
music_progress: cmd_args.music_progress,
|
||||||
debug_json: cmd_args.debug_json,
|
debug: cmd_args.debug,
|
||||||
debug_modules: cmd_args.debug_modules
|
debug_icons: cmd_args.debug_icons
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user