diff --git a/experimental/Cargo.toml b/experimental/Cargo.toml index 6dd617cd1..5693233ea 100644 --- a/experimental/Cargo.toml +++ b/experimental/Cargo.toml @@ -17,3 +17,10 @@ regex = "1.11.1" serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" snafu = "0.8.5" + +[dev-dependencies] +criterion = { version = "0.5", features = ["html_reports"] } + +[[bench]] +name = "bench" +harness = false diff --git a/experimental/src/compute/ast.rs b/experimental/src/compute/ast.rs index c26c89317..f36ee2336 100644 --- a/experimental/src/compute/ast.rs +++ b/experimental/src/compute/ast.rs @@ -338,8 +338,19 @@ impl<'input> Expr<'input> { Func::Average => match v { ExprResult::Number(n) => ExprResult::Number(n), ExprResult::Vector(v) => { - let sum = v.iter().sum::(); - ExprResult::Number(sum / v.len() as f64) + let mut sum = 0.0; + let mut count = 0; + for value in v { + if !value.is_nan() { + sum += value; + count += 1; + } + } + if count > 0 { + return ExprResult::Number(sum / count as f64); + } else { + return ExprResult::Number(f64::NAN); + } } _ => panic!("Invalid operation"), }, diff --git a/experimental/src/generic/mod.rs b/experimental/src/generic/mod.rs index 5723409a1..ea89b3968 100644 --- a/experimental/src/generic/mod.rs +++ b/experimental/src/generic/mod.rs @@ -99,16 +99,16 @@ pub struct CmdResult { pub output: String, } -fn compute_status(value: f64, warn: &Option, crit: &Option) -> Result { +fn compute_status(value: &f64, warn: &Option, crit: &Option) -> Result { if let Some(c) = crit { let crit = Threshold::parse(c)?; - if crit.in_alert(value) { + if crit.in_alert(*value) { return Ok(Status::Critical); } } if let Some(w) = warn { let warn = Threshold::parse(w)?; - if warn.in_alert(value) { + if warn.in_alert(*value) { return Ok(Status::Warning); } } @@ -247,7 +247,7 @@ impl Command { } }; let current_status = - compute_status(*item, &metric.warning, &metric.critical)?; + compute_status(item, &metric.warning, &metric.critical)?; status = worst(status, current_status); let w = match metric.warning { Some(ref w) => Some(w.as_str()), @@ -280,7 +280,7 @@ impl Command { res } }; - let current_status = compute_status(*s, &metric.warning, &metric.critical)?; + let current_status = compute_status(s, &metric.warning, &metric.critical)?; status = worst(status, current_status); let w = match metric.warning { Some(ref w) => Some(w.as_str()), @@ -309,6 +309,7 @@ impl Command { } collect.push(my_res); if let Some(aggregations) = self.compute.aggregations.as_ref() { + let mut my_res = SnmpResult::new(HashMap::new()); for metric in aggregations { let value = &metric.value; let parser = Parser::new(&collect); @@ -343,7 +344,7 @@ impl Command { None }; let value = parser.eval(value).unwrap(); - match value { + match &value { ExprResult::Vector(v) => { for item in v { let name = match &metric.prefix { @@ -369,7 +370,7 @@ impl Command { }; let m = Perfdata { name, - value: item, + value: *item, min, max, warning: w, @@ -393,7 +394,7 @@ impl Command { }; let m = Perfdata { name: name.to_string(), - value: s, + value: *s, min, max, warning: w, @@ -404,12 +405,16 @@ impl Command { } _ => panic!("Aggregation must be applied to a vector"), } + let key = format!("aggregations.{}", metric.name); + debug!("New ID '{}' with content: {:?}", key, value); + my_res.items.insert(key, value); } + collect.push(my_res); } - trace!("collect: {:#?}", collect); + debug!("collect: {:#?}", collect); trace!("metrics: {:#?}", metrics); - let output_formatter = OutputFormatter::new(status, &metrics, &self.output); + let output_formatter = OutputFormatter::new(status, &collect, &metrics, &self.output); let output = output_formatter.to_string(); Ok(CmdResult { status, output }) } diff --git a/experimental/src/main.rs b/experimental/src/main.rs index 9433d80d9..4bd1ad290 100644 --- a/experimental/src/main.rs +++ b/experimental/src/main.rs @@ -15,6 +15,7 @@ mod generic; mod output; mod snmp; +use env_logger::Env; use generic::error::*; use generic::Command; use lalrpop_util::lalrpop_mod; @@ -41,7 +42,12 @@ fn json_to_command(file_name: &str) -> Result { } fn main() -> Result<(), Error> { - env_logger::init(); + env_logger::Builder::from_env( + Env::default().default_filter_or("info") + .filter("PLUGIN_LOG") + ).init(); + + //env_logger::init(); use lexopt::prelude::*; let mut parser = lexopt::Parser::from_env();