load configuration file

This commit is contained in:
Ondrej Novak 2026-06-19 23:23:20 +02:00
parent 6d3f360012
commit fe3cbc7fc3
Signed by: handy
SSH Key Fingerprint: SHA256:jlNm8ijkaMl4X7+nn3zBFTJufdQgT4unKJoZVH6kYTM
6 changed files with 167 additions and 71 deletions

108
Cargo.lock generated
View File

@ -313,6 +313,12 @@ dependencies = [
"syn",
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "exr"
version = "1.74.0"
@ -516,6 +522,12 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "hashbrown"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
name = "image"
version = "0.25.10"
@ -576,6 +588,16 @@ version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8"
[[package]]
name = "indexmap"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "interpolate_name"
version = "0.2.4"
@ -1187,6 +1209,45 @@ dependencies = [
"version-compare",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_spanned"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26"
dependencies = [
"serde_core",
]
[[package]]
name = "shlex"
version = "1.3.0"
@ -1284,6 +1345,45 @@ dependencies = [
"zune-jpeg",
]
[[package]]
name = "toml"
version = "1.1.2+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee"
dependencies = [
"indexmap",
"serde_core",
"serde_spanned",
"toml_datetime",
"toml_parser",
"toml_writer",
"winnow",
]
[[package]]
name = "toml_datetime"
version = "1.1.1+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
dependencies = [
"serde_core",
]
[[package]]
name = "toml_parser"
version = "1.1.2+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
dependencies = [
"winnow",
]
[[package]]
name = "toml_writer"
version = "1.1.1+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db"
[[package]]
name = "transpose"
version = "0.2.3"
@ -1391,6 +1491,8 @@ dependencies = [
"imageproc",
"protocol",
"regex",
"serde",
"toml",
]
[[package]]
@ -1409,6 +1511,12 @@ dependencies = [
"safe_arch",
]
[[package]]
name = "winnow"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1"
[[package]]
name = "wit-bindgen"
version = "0.51.0"

View File

@ -7,6 +7,7 @@ use imageproc::{
use crate::Container;
pub struct StackedConfig {
pub name: String,
pub width_px_per_sample: u32,
pub height_px: u32,
pub series: Vec<StackedSeriesConfig>,

View File

@ -8,3 +8,5 @@ draw = { version = "0.1.0", path = "../draw" }
imageproc = { version = "0.26.1", features = ["display-window"] }
protocol = { path = "../protocol" }
regex = "1.12.3"
serde = { version = "1.0.228", features = ["derive"] }
toml = { version = "1.1.2", features = ["serde", "parse"] }

View File

@ -1,9 +1,13 @@
use regex::Regex;
use std::fs;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct Config {
pub graphs: Vec<GraphConfig>,
pub graph: Vec<GraphConfig>,
}
#[derive(Debug, Deserialize)]
pub struct GraphConfig {
pub name: String,
pub width_px: u16,
@ -12,8 +16,14 @@ pub struct GraphConfig {
pub series: Vec<SeriesConfig>,
}
#[derive(Debug, Deserialize)]
pub struct SeriesConfig {
pub name: String,
pub color: (u8, u8, u8),
pub metrics: Vec<Regex>,
pub metrics: Vec<String>,
}
pub fn parse(path: &str) -> Config {
let file = fs::read_to_string(path).expect("Could not open configuration file");
toml::from_str(&file).expect("Could not parse configuration file")
}

View File

@ -2,77 +2,21 @@ mod config;
mod observables;
mod runner;
use config::{Config, GraphConfig, SeriesConfig};
use draw::{StackedConfig, StackedSeriesConfig};
use observables::{Observable, ObservableCollection};
use protocol::{Protocol, ProtocolError};
use regex::Regex;
use config::parse;
use protocol::Protocol;
use std::{thread, time};
use crate::runner::{Graph, Runner};
fn create_debug_config() -> Config {
let load_regexes = vec![Regex::new(".*\\/cpu-[0-9]+\\/cpu-(nice|steal|system|user)").unwrap()];
let iowait_regexes = vec![Regex::new(".*\\/cpu-[0-9]+\\/cpu-wait").unwrap()];
let irq_regexes = vec![Regex::new(".*\\/cpu-[0-9]+\\/cpu-(interrupt|softirq)").unwrap()];
let idle_regexes = vec![Regex::new(".*\\/cpu-[0-9]+\\/cpu-idle").unwrap()];
let series = vec![
SeriesConfig {
name: "load".to_string(),
color: (2, 154, 219),
metrics: load_regexes,
},
SeriesConfig {
name: "io wait".to_string(),
color: (68, 200, 229),
metrics: iowait_regexes,
},
SeriesConfig {
name: "irq".to_string(),
color: (143, 232, 252),
metrics: irq_regexes,
},
SeriesConfig {
name: "idle".to_string(),
color: (0, 0, 0),
metrics: idle_regexes,
},
];
let graphs = vec![GraphConfig {
name: "cpu load".to_string(),
width_px: 480,
height_px: 98,
samples: 60,
series: series,
}];
Config { graphs: graphs }
}
fn main() {
if let Ok(mut proto) = Protocol::new("/var/run/collectd-unixsock") {
let config = create_debug_config();
let config = parse("config.toml");
let cfg = StackedConfig {
height_px: config.graphs[0].height_px as u32,
max_samples: config.graphs[0].samples as u32,
width_px_per_sample: (config.graphs[0].width_px / config.graphs[0].samples) as u32,
series: config.graphs[0]
.series
let graphs = config
.graph
.iter()
.map(|s| StackedSeriesConfig { color: s.color })
.collect(),
};
let observables = config.graphs[0]
.series
.iter()
.map(|s| Observable::discover(&mut proto, &s.name, &s.metrics))
.collect::<Result<Vec<Observable>, ProtocolError>>()
.unwrap();
let collection = ObservableCollection::new(observables);
let graphs = vec![Graph::new(cfg, collection)];
.map(|g| Graph::new(g, &mut proto))
.collect();
let mut runner = Runner::new(graphs, proto);
loop {

View File

@ -1,9 +1,13 @@
use core::fmt;
use draw::{StackedConfig, StackedSeries, stacked};
use protocol::Protocol;
use draw::{StackedConfig, StackedSeries, StackedSeriesConfig, stacked};
use protocol::{Protocol, ProtocolError};
use regex::Regex;
use crate::observables::ObservableCollection;
use crate::{
config::GraphConfig,
observables::{Observable, ObservableCollection},
};
pub struct Graph {
pub observable: ObservableCollection,
@ -11,10 +15,37 @@ pub struct Graph {
}
impl Graph {
pub fn new(config: StackedConfig, observable: ObservableCollection) -> Graph {
pub fn new(config: &GraphConfig, proto: &mut Protocol) -> Graph {
let stacked_config = StackedConfig {
name: config.name.to_string(),
height_px: config.height_px as u32,
max_samples: config.samples as u32,
width_px_per_sample: (config.width_px / config.samples) as u32,
series: config
.series
.iter()
.map(|s| StackedSeriesConfig { color: s.color })
.collect(),
};
let observable = ObservableCollection::new(
config
.series
.iter()
.map(|s| {
Observable::discover(
proto,
&s.name,
&s.metrics.iter().map(|m| Regex::new(&m).unwrap()).collect(),
)
})
.collect::<Result<Vec<Observable>, ProtocolError>>()
.expect("Could not discover required metrics"),
);
Graph {
series: StackedSeries::new(stacked_config),
observable: observable,
series: StackedSeries::new(config),
}
}
}