From f9ace6f4c4bd83615877fa7c42aba84dcc018315 Mon Sep 17 00:00:00 2001 From: David Boucher Date: Thu, 24 Apr 2025 09:09:31 +0200 Subject: [PATCH] enh(generic-snmp): min/max computed and added to perfdata --- experimental/src/compute/ast.rs | 2 +- experimental/src/compute/mod.rs | 6 +- experimental/src/generic/mod.rs | 138 +++++++++++++++++++++++++++++--- 3 files changed, 131 insertions(+), 15 deletions(-) diff --git a/experimental/src/compute/ast.rs b/experimental/src/compute/ast.rs index c9aef5c23..0af150d83 100644 --- a/experimental/src/compute/ast.rs +++ b/experimental/src/compute/ast.rs @@ -1,6 +1,6 @@ +use log::debug; use snmp::{SnmpItem, SnmpResult}; use std::str; -use log::debug; #[derive(Debug)] pub enum Expr<'input> { diff --git a/experimental/src/compute/mod.rs b/experimental/src/compute/mod.rs index 4dd70be92..d81919914 100644 --- a/experimental/src/compute/mod.rs +++ b/experimental/src/compute/mod.rs @@ -15,8 +15,10 @@ pub struct Metric { pub prefix: Option, pub value: String, uom: Option, - min: Option, - max: Option, + pub min_expr: Option, + pub min: Option, + pub max_expr: Option, + pub max: Option, } #[derive(Deserialize, Debug)] diff --git a/experimental/src/generic/mod.rs b/experimental/src/generic/mod.rs index 7227915ca..3d8fdd4e6 100644 --- a/experimental/src/generic/mod.rs +++ b/experimental/src/generic/mod.rs @@ -1,11 +1,19 @@ extern crate serde; extern crate serde_json; -use compute::{Compute, Parser}; +use compute::{ast::ExprResult, Compute, Parser}; use serde::Deserialize; use snmp::{snmp_bulk_get, snmp_bulk_walk, snmp_bulk_walk_with_labels}; use std::collections::HashMap; +#[derive(Debug)] +struct Perfdata { + name: String, + value: f64, + min: Option, + max: Option, +} + #[derive(Copy, Clone, PartialEq)] pub enum Status { Ok = 0, @@ -136,20 +144,126 @@ impl Command { } println!("{:#?}", collect); - for (i, metric) in self.compute.metrics.iter().enumerate() { - let name = match &metric.prefix { - Some(prefix) => { - format!("{:?}#{}", prefix, metric.name) - } - - None => format!("{}#{}", i, metric.name), - }; - println!("name: {}", name); + let mut idx: u32 = 0; + let mut metrics = vec![]; + for metric in self.compute.metrics.iter() { let value = &metric.value; - println!("value: {}", value); + let min = metric.min; + let max = metric.max; let parser = Parser::new(&collect); let value = parser.eval(value).unwrap(); - println!("value result: {:?}", value); + match value { + ExprResult::Vector(v) => { + for item in v { + let name = match &metric.prefix { + Some(prefix) => { + format!("{:?}#{}", prefix, metric.name) + } + None => { + let res = format!("{}#{}", idx, metric.name); + idx += 1; + res + } + }; + let m = Perfdata { + name, + value: item, + min, + max, + }; + metrics.push(m); + } + } + ExprResult::Scalar(s) => { + let name = match &metric.prefix { + Some(prefix) => { + format!("{:?}#{}", prefix, metric.name) + } + None => { + let res = format!("{}#{}", idx, metric.name); + idx += 1; + res + } + }; + let m = Perfdata { + name, + value: s, + min, + max, + }; + metrics.push(m); + } + } + println!("perfdata: {:?}", metrics); + } + if let Some(aggregations) = self.compute.aggregations.as_ref() { + for metric in aggregations { + let value = &metric.value; + let parser = Parser::new(&collect); + let max = if let Some(max_expr) = metric.max_expr.as_ref() { + let res = parser.eval(&max_expr).unwrap(); + Some(match res { + ExprResult::Scalar(v) => v, + ExprResult::Vector(v) => { + assert!(v.len() == 1); + v[0] + } + }) + } else if let Some(max_value) = metric.max { + Some(max_value) + } else { + None + }; + let min = if let Some(min_expr) = metric.min_expr.as_ref() { + let res = parser.eval(&min_expr).unwrap(); + Some(match res { + ExprResult::Scalar(v) => v, + ExprResult::Vector(v) => { + assert!(v.len() == 1); + v[0] + } + }) + } else if let Some(min_value) = metric.min { + Some(min_value) + } else { + None + }; + let value = parser.eval(value).unwrap(); + match value { + ExprResult::Vector(v) => { + for item in v { + let name = match &metric.prefix { + Some(prefix) => { + format!("{:?}#{}", prefix, metric.name) + } + None => { + let res = format!("{}#{}", idx, metric.name); + idx += 1; + res + } + }; + let m = Perfdata { + name, + value: item, + min, + max, + }; + metrics.push(m); + } + } + ExprResult::Scalar(s) => { + let name = &metric.name; + let m = Perfdata { + name: name.to_string(), + value: s, + min, + max, + }; + metrics.push(m); + } + } + println!("perfdata: {:?}", metrics); + } } CmdResult {