From cfa70c946bec1a8f7455cf7b3e0823ac8978154a Mon Sep 17 00:00:00 2001 From: Ondrej Novak Date: Sun, 14 Jun 2026 22:08:05 +0200 Subject: [PATCH] implement generic observable --- Cargo.lock | 3 -- protocol/Cargo.toml | 3 -- protocol/src/protocol.rs | 11 +---- waybar-collectd/src/main.rs | 10 ++++- waybar-collectd/src/observables.rs | 66 ++++++++++++------------------ 5 files changed, 37 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28b312c..86d41c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -938,9 +938,6 @@ dependencies = [ [[package]] name = "protocol" version = "0.1.0" -dependencies = [ - "regex", -] [[package]] name = "pxfm" diff --git a/protocol/Cargo.toml b/protocol/Cargo.toml index 2c707ab..eb1150f 100644 --- a/protocol/Cargo.toml +++ b/protocol/Cargo.toml @@ -2,6 +2,3 @@ name = "protocol" version = "0.1.0" edition = "2024" - -[dependencies] -regex = "1" diff --git a/protocol/src/protocol.rs b/protocol/src/protocol.rs index 22eea4c..82f87e3 100644 --- a/protocol/src/protocol.rs +++ b/protocol/src/protocol.rs @@ -1,8 +1,6 @@ use std::io::{Read, Write}; use std::os::unix::net::UnixStream; -use regex::Regex; - use crate::err::ProtocolError; use crate::message::{ create_list_message, create_request_message, parse_list_response, parse_response_header, @@ -48,15 +46,10 @@ impl Protocol { } } - pub fn list(&mut self, path_regex: &Regex) -> Result, ProtocolError> { + pub fn list(&mut self) -> Result, ProtocolError> { let req = create_list_message(); let lines = self.rpc(&req)?; - let values = parse_list_response(lines); - - Ok(values - .into_iter() - .filter(|v| path_regex.is_match(v)) - .collect()) + Ok(parse_list_response(lines)) } fn rpc(&mut self, req: &str) -> Result, ProtocolError> { diff --git a/waybar-collectd/src/main.rs b/waybar-collectd/src/main.rs index 4a27b3d..76f5079 100644 --- a/waybar-collectd/src/main.rs +++ b/waybar-collectd/src/main.rs @@ -1,7 +1,7 @@ mod observables; use draw::{StackedConfig, StackedSeries, StackedSeriesConfig, stacked}; -use observables::CpuObservable; +use observables::{Observable, ObservableConfig}; use protocol::Protocol; use std::{thread, time}; @@ -19,7 +19,13 @@ fn main() { if let Ok(mut proto) = Protocol::new("/var/run/collectd-unixsock") { // loop { - let cpu = CpuObservable::discover(&mut proto).unwrap(); + + let cpu_load_cfg = ObservableConfig { + name: "cpu".to_string(), + norm: 1., + include: vec![Regex::new()], + }; + let cpu = Observable::discover(&mut proto).unwrap(); let mut series = StackedSeries::new(cfg); for _ in 1..10 { let sample = cpu.sample(&mut proto).unwrap(); diff --git a/waybar-collectd/src/observables.rs b/waybar-collectd/src/observables.rs index 4ae9941..d78e496 100644 --- a/waybar-collectd/src/observables.rs +++ b/waybar-collectd/src/observables.rs @@ -1,55 +1,43 @@ use protocol::{Protocol, ProtocolError}; use regex::Regex; -const CPU_NORM: f32 = 100.; - -pub struct CpuObservable { +pub struct ObservableConfig { pub name: String, - num_cpus: u8, - wait_cpus: Vec, - interrupt_cpus: Vec, - load_cpus: Vec, - idle_cpus: Vec, + pub norm: f32, + pub include: Vec, } -impl CpuObservable { - pub fn discover(proto: &mut Protocol) -> Result { - let wait_cpus = proto.list(&Regex::new(".*\\/cpu-[0-9]+\\/cpu-wait").unwrap())?; - let interrupt_cpus = - proto.list(&Regex::new(".*\\/cpu-[0-9]+\\/cpu-(softirq|interrupt)").unwrap())?; - let load_cpus = proto.list(&Regex::new(".*\\/cpu-[0-9]+\\/cpu-.+").unwrap())?; - let idle_cpus = proto.list(&Regex::new(".*\\/cpu-[0-9]+\\/cpu-idle").unwrap())?; +pub struct Observable { + pub name: String, + norm: f32, + metrics: Vec, +} - let num_cpus = wait_cpus.iter().len(); +impl Observable { + pub fn discover( + proto: &mut Protocol, + cfg: ObservableConfig, + ) -> Result { + let all_values = proto.list()?; + let filtered_values = all_values + .into_iter() + .filter(|v| cfg.include.iter().any(|i| i.is_match(v))) + .collect(); - Ok(CpuObservable { - name: "cpu".into(), - num_cpus: num_cpus as u8, - wait_cpus: wait_cpus, - interrupt_cpus: interrupt_cpus, - load_cpus: load_cpus, - idle_cpus: idle_cpus, + Ok(Observable { + name: cfg.name, + norm: cfg.norm, + metrics: filtered_values, }) } - pub fn sample(&self, proto: &mut Protocol) -> Result, ProtocolError> { - let load = self.sample_fields(&self.load_cpus, proto)?; - let iowait = self.sample_fields(&self.wait_cpus, proto)?; - let interrupts = self.sample_fields(&self.interrupt_cpus, proto)?; - let idle = self.sample_fields(&self.idle_cpus, proto)?; - - Ok(vec![load - iowait - interrupts - idle, iowait, interrupts]) - } - - fn sample_fields( - &self, - fields: &Vec, - proto: &mut Protocol, - ) -> Result { - let results = fields + pub fn sample(&self, proto: &mut Protocol) -> Result { + let results = self + .metrics .iter() .map(|f| proto.get(f.into(), "value".to_string())) .collect::, ProtocolError>>()?; - Ok(results.into_iter().sum::() / self.num_cpus as f32 / CPU_NORM) + + Ok(results.into_iter().sum::() / self.norm) } }