mirror of
https://github.com/centreon/centreon-plugins.git
synced 2025-07-29 16:45:04 +02:00
enh(generic-snmp): Introduction of real thresholds (work in progress)
This commit is contained in:
parent
4fac604a4b
commit
32c1bbad3b
@ -1,5 +1,6 @@
|
||||
pub mod ast;
|
||||
pub mod lexer;
|
||||
pub mod threshold;
|
||||
|
||||
use self::ast::ExprResult;
|
||||
use self::lexer::{LexicalError, Tok};
|
||||
|
105
experimental/src/compute/threshold.rs
Normal file
105
experimental/src/compute/threshold.rs
Normal file
@ -0,0 +1,105 @@
|
||||
use std::f64::INFINITY;
|
||||
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
||||
pub struct Threshold {
|
||||
start: f64,
|
||||
end: f64,
|
||||
}
|
||||
|
||||
impl Threshold {
|
||||
pub fn parse(expr: &str) -> Threshold {
|
||||
// https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT
|
||||
let mut start: usize = 0;
|
||||
let mut in_number = false;
|
||||
let mut start_value = -INFINITY;
|
||||
let mut end_value = INFINITY;
|
||||
let mut in_range = false;
|
||||
for (idx, c) in expr.char_indices() {
|
||||
if in_number {
|
||||
match c {
|
||||
'0'..='9' => continue,
|
||||
'.' | '-' | '+' | 'e' | 'E' => continue,
|
||||
_ => {
|
||||
in_number = false;
|
||||
start_value = match expr[start..idx].parse() {
|
||||
Ok(x) => x,
|
||||
Err(err) => {
|
||||
error!("parse error: {}", err);
|
||||
std::process::exit(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* No else here, because we can continue the previous match */
|
||||
if !in_number {
|
||||
match c {
|
||||
' ' => continue,
|
||||
'0'..='9' => {
|
||||
in_number = true;
|
||||
start = idx;
|
||||
}
|
||||
':' => {
|
||||
in_range = true;
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
}
|
||||
if in_number {
|
||||
start_value = match expr[start..].parse() {
|
||||
Ok(x) => x,
|
||||
Err(err) => {
|
||||
error!("parse error: {}", err);
|
||||
std::process::exit(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We have noticed a ':' character, so the threshold is a range */
|
||||
if in_range {
|
||||
return Threshold {
|
||||
start: start_value,
|
||||
end: INFINITY,
|
||||
};
|
||||
} else {
|
||||
return Threshold {
|
||||
start: 0_f64,
|
||||
end: start_value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn in_alert(&self, value: f64) -> bool {
|
||||
if value < self.start || value > self.end {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
mod Test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_value() {
|
||||
let expr = "1.2";
|
||||
let threshold = Threshold::parse(expr);
|
||||
assert_eq!(threshold.start, 0_f64);
|
||||
assert_eq!(threshold.end, 1.2_f64);
|
||||
assert!(threshold.in_alert(2_f64));
|
||||
assert!(threshold.in_alert(-1_f64));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_val_colon() {
|
||||
let expr = "10:";
|
||||
let threshold = Threshold::parse(expr);
|
||||
assert_eq!(threshold.start, 10_f64);
|
||||
assert_eq!(threshold.end, INFINITY);
|
||||
assert!(!threshold.in_alert(10_f64));
|
||||
assert!(!threshold.in_alert(11_f64));
|
||||
assert!(threshold.in_alert(9_f64));
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
|
||||
use compute::{ast::ExprResult, Compute, Parser};
|
||||
use compute::{ast::ExprResult, threshold::Threshold, Compute, Parser};
|
||||
use log::{debug, trace};
|
||||
use serde::Deserialize;
|
||||
use snmp::{snmp_bulk_get, snmp_bulk_walk, snmp_bulk_walk_with_labels};
|
||||
@ -10,11 +10,13 @@ use std::{collections::HashMap, ops::IndexMut};
|
||||
use crate::snmp::SnmpResult;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Perfdata {
|
||||
struct Perfdata<'p> {
|
||||
name: String,
|
||||
value: f64,
|
||||
min: Option<f64>,
|
||||
max: Option<f64>,
|
||||
warning: Option<&'p str>,
|
||||
critical: Option<&'p str>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
@ -219,11 +221,22 @@ impl Command {
|
||||
panic!("A label must be a string");
|
||||
}
|
||||
};
|
||||
let status = compute_status(*item, &metric.warning, &metric.critical);
|
||||
let w = match metric.warning {
|
||||
Some(ref w) => Some(w.as_str()),
|
||||
None => None,
|
||||
};
|
||||
let c = match metric.critical {
|
||||
Some(ref c) => Some(c.as_str()),
|
||||
None => None,
|
||||
};
|
||||
let m = Perfdata {
|
||||
name,
|
||||
value: *item,
|
||||
min: compute_threshold(i, &min),
|
||||
max: compute_threshold(i, &max),
|
||||
warning: w,
|
||||
critical: c,
|
||||
};
|
||||
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
||||
metrics.push(m);
|
||||
@ -240,11 +253,22 @@ impl Command {
|
||||
res
|
||||
}
|
||||
};
|
||||
let status = compute_status(*s, &metric.warning, &metric.critical);
|
||||
let w = match metric.warning {
|
||||
Some(ref w) => Some(w.as_str()),
|
||||
None => None,
|
||||
};
|
||||
let c = match metric.critical {
|
||||
Some(ref c) => Some(c.as_str()),
|
||||
None => None,
|
||||
};
|
||||
let m = Perfdata {
|
||||
name,
|
||||
value: *s,
|
||||
min: compute_threshold(0, &min),
|
||||
max: compute_threshold(0, &max),
|
||||
warning: w,
|
||||
critical: c,
|
||||
};
|
||||
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
||||
metrics.push(m);
|
||||
@ -304,11 +328,22 @@ impl Command {
|
||||
res
|
||||
}
|
||||
};
|
||||
let status = compute_status(item, &metric.warning, &metric.critical);
|
||||
let w = match metric.warning {
|
||||
Some(ref w) => Some(w.as_str()),
|
||||
None => None,
|
||||
};
|
||||
let c = match metric.critical {
|
||||
Some(ref c) => Some(c.as_str()),
|
||||
None => None,
|
||||
};
|
||||
let m = Perfdata {
|
||||
name,
|
||||
value: item,
|
||||
min,
|
||||
max,
|
||||
warning: w,
|
||||
critical: c,
|
||||
};
|
||||
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
||||
metrics.push(m);
|
||||
@ -316,11 +351,22 @@ impl Command {
|
||||
}
|
||||
ExprResult::Number(s) => {
|
||||
let name = &metric.name;
|
||||
let status = compute_status(s, &metric.warning, &metric.critical);
|
||||
let w = match metric.warning {
|
||||
Some(ref w) => Some(w.as_str()),
|
||||
None => None,
|
||||
};
|
||||
let c = match metric.critical {
|
||||
Some(ref c) => Some(c.as_str()),
|
||||
None => None,
|
||||
};
|
||||
let m = Perfdata {
|
||||
name: name.to_string(),
|
||||
value: s,
|
||||
min,
|
||||
max,
|
||||
warning: w,
|
||||
critical: c,
|
||||
};
|
||||
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
||||
metrics.push(m);
|
||||
|
Loading…
x
Reference in New Issue
Block a user