Last active
July 29, 2022 06:52
-
-
Save angeloxx/c654ce47659cc4ed5c9038d4a9e09b07 to your computer and use it in GitHub Desktop.
Nagios/Icinga2 monitor perfdata
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import os, glob, time, sys, argparse | |
# The script navigate Nagios/Icinga2's perfdata and read it in order to create additional treshold based on last value or the trend in a specific timespan. | |
# python3 scripts/check_perfdata.py -H SERVER -S ILO_HEALTH -V Inlet_Ambient -C 21 -W 19.1 --trend-period-minutes 10 -P var/spool/icinga2/perfdata/ --trend-warning=1 --trend-critical=2 | |
INVALIDVALUE = -999 | |
latestValue = INVALIDVALUE | |
latestValueTime = INVALIDVALUE | |
trendFirstValue = INVALIDVALUE | |
valueTrend = INVALIDVALUE | |
valueNameFound = False | |
# 0->OK, 1->WARNING, 2->CRITICAL, 3->UNKNOWN | |
exitState = 0 | |
exitString = [] | |
exitStateString = "" | |
def nagiosFields(_in, _yourValue): | |
ret = {} | |
for field in _in: | |
(key,value) = field.split("::") | |
ret[key] = value | |
ret["PERFORMANCES"] = {} | |
for performance in ret['SERVICEPERFDATA'].split(" "): | |
(key,value) = performance.split('=') | |
(current,warning,critical) = value.split(";") | |
ret["PERFORMANCES"][key] = float(current.replace("%","")) | |
if _yourValue == key: | |
ret["PERFORMANCE"] = float(current.replace("%","")) | |
return ret | |
parser = argparse.ArgumentParser(description='Process performance data') | |
parser.add_argument('-P', '--path', dest="datapath", default="/var/spool/icinga2/perfdata/", required=False, help='Performance data path') | |
parser.add_argument('-H', '--host', dest="hostname", default="LOCALHOST", required=True, help='Nagios/Icinga2 Hostname') | |
parser.add_argument('-S', '--service', dest="service", default="UPTIME", required=True, help='Service name') | |
parser.add_argument('-V', '--value', dest="value", default="freespace", required=True, help='Performance field name') | |
parser.add_argument('-C', '--warning', dest="warning", default=20, type=float, required=True, help='Warning absolute value') | |
parser.add_argument('-W', '--critical', dest="critical", default=30, type=float, required=True, help='Critical absolute value') | |
parser.add_argument('--trend-period-minutes', dest="tperiod", default=INVALIDVALUE, type=int, required=False, help='Trend change period') | |
parser.add_argument('--trend-warning', dest="twarning", default=INVALIDVALUE, type=float, required=False, help='Warning trend change value') | |
parser.add_argument('--trend-critical', dest="tcritical", default=INVALIDVALUE, type=float, required=False, help='Critical trend change value') | |
args = parser.parse_args() | |
perfdataFiles = filter( os.path.isfile, glob.glob(args.datapath + 'service-perfdata.*') ) | |
perfdataFiles = sorted( perfdataFiles, key = os.path.getmtime, reverse = True) | |
for perfdataFile in perfdataFiles: | |
# Break if all data was already acquired | |
if latestValue != INVALIDVALUE: | |
if args.tperiod != INVALIDVALUE and trendFirstValue != INVALIDVALUE: | |
break | |
if args.tperiod == INVALIDVALUE: | |
break | |
with open(perfdataFile, "r") as f: | |
for line in f: | |
fieldsRaw=line.rstrip().split("\t") | |
if f"HOSTNAME::{args.hostname}" in fieldsRaw and f"SERVICEDESC::{args.service}" in fieldsRaw: | |
data = nagiosFields(fieldsRaw, args.value) | |
if "PERFORMANCE" in data: | |
if latestValue == INVALIDVALUE: | |
valueNameFound = True | |
latestValue = float(data["PERFORMANCE"]) | |
latestValueTime = int(data["TIMET"]) | |
else: | |
if args.tperiod != INVALIDVALUE and trendFirstValue == INVALIDVALUE and (latestValueTime-(args.tperiod*60)) >= int(data["TIMET"]): | |
trendFirstValue = float(data["PERFORMANCE"]) | |
valueTrend = latestValue - trendFirstValue | |
if valueNameFound == False: | |
exitState = 3 | |
exitString.append(f"unable to find {args.value} in performance data ({args.datapath}) for {args.hostname}") | |
else: | |
if args.tperiod == INVALIDVALUE: | |
exitString.append(f"performance {args.value} is latest={latestValue}") | |
else: | |
exitString.append(f"performance {args.value} is latest={latestValue} and trend({args.tperiod} min)={valueTrend}") | |
if latestValue >= args.critical: | |
exitState = 2 | |
exitString.append(f"above absolute critical {args.critical}") | |
if exitState <= 1 and latestValue >= args.warning: | |
exitState = 1 | |
exitString.append(f"above absolute warning {args.warning}") | |
if args.tperiod != INVALIDVALUE: | |
if valueTrend >= args.tcritical: | |
exitState = 2 | |
exitString.append(f"above trend critical {args.tcritical}") | |
if exitState <= 1 and valueTrend >= args.twarning: | |
exitState = 2 | |
exitString.append(f"above trend warning {args.twarning}") | |
if exitState <= 0: | |
pass | |
if exitState == 0: exitCodeString = "OK" | |
if exitState == 1: exitCodeString = "WARNING" | |
if exitState == 2: exitCodeString = "CRITICAL" | |
if exitState == 3: exitCodeString = "UNKNOWN" | |
print(exitCodeString + ": " + ', '.join(exitString)) | |
sys.exit(exitState) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment