mirror of
https://github.com/centreon/centreon-plugins.git
synced 2025-07-30 17:15:11 +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 ast;
|
||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
|
pub mod threshold;
|
||||||
|
|
||||||
use self::ast::ExprResult;
|
use self::ast::ExprResult;
|
||||||
use self::lexer::{LexicalError, Tok};
|
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;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
|
||||||
use compute::{ast::ExprResult, Compute, Parser};
|
use compute::{ast::ExprResult, threshold::Threshold, Compute, Parser};
|
||||||
use log::{debug, trace};
|
use log::{debug, trace};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use snmp::{snmp_bulk_get, snmp_bulk_walk, snmp_bulk_walk_with_labels};
|
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;
|
use crate::snmp::SnmpResult;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Perfdata {
|
struct Perfdata<'p> {
|
||||||
name: String,
|
name: String,
|
||||||
value: f64,
|
value: f64,
|
||||||
min: Option<f64>,
|
min: Option<f64>,
|
||||||
max: Option<f64>,
|
max: Option<f64>,
|
||||||
|
warning: Option<&'p str>,
|
||||||
|
critical: Option<&'p str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
@ -219,11 +221,22 @@ impl Command {
|
|||||||
panic!("A label must be a string");
|
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 {
|
let m = Perfdata {
|
||||||
name,
|
name,
|
||||||
value: *item,
|
value: *item,
|
||||||
min: compute_threshold(i, &min),
|
min: compute_threshold(i, &min),
|
||||||
max: compute_threshold(i, &max),
|
max: compute_threshold(i, &max),
|
||||||
|
warning: w,
|
||||||
|
critical: c,
|
||||||
};
|
};
|
||||||
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
||||||
metrics.push(m);
|
metrics.push(m);
|
||||||
@ -240,11 +253,22 @@ impl Command {
|
|||||||
res
|
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 {
|
let m = Perfdata {
|
||||||
name,
|
name,
|
||||||
value: *s,
|
value: *s,
|
||||||
min: compute_threshold(0, &min),
|
min: compute_threshold(0, &min),
|
||||||
max: compute_threshold(0, &max),
|
max: compute_threshold(0, &max),
|
||||||
|
warning: w,
|
||||||
|
critical: c,
|
||||||
};
|
};
|
||||||
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
||||||
metrics.push(m);
|
metrics.push(m);
|
||||||
@ -304,11 +328,22 @@ impl Command {
|
|||||||
res
|
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 {
|
let m = Perfdata {
|
||||||
name,
|
name,
|
||||||
value: item,
|
value: item,
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
|
warning: w,
|
||||||
|
critical: c,
|
||||||
};
|
};
|
||||||
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
||||||
metrics.push(m);
|
metrics.push(m);
|
||||||
@ -316,11 +351,22 @@ impl Command {
|
|||||||
}
|
}
|
||||||
ExprResult::Number(s) => {
|
ExprResult::Number(s) => {
|
||||||
let name = &metric.name;
|
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 {
|
let m = Perfdata {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
value: s,
|
value: s,
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
|
warning: w,
|
||||||
|
critical: c,
|
||||||
};
|
};
|
||||||
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
trace!("New metric '{}' with value {:?}", m.name, m.value);
|
||||||
metrics.push(m);
|
metrics.push(m);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user