mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
188 lines
4.8 KiB
Text
188 lines
4.8 KiB
Text
|
#!/usr/bin/python
|
||
|
#
|
||
|
# Copyright (C) 2009 Andreas Thienemann <andreas@bawue.net>
|
||
|
#
|
||
|
# This program is free software; you can redistribute it and/or modify
|
||
|
# it under the terms of the GNU Library General Public License as published by
|
||
|
# the Free Software Foundation; version 2 only
|
||
|
#
|
||
|
# This program is distributed in the hope that it will be useful,
|
||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
# GNU Library General Public License for more details.
|
||
|
#
|
||
|
# You should have received a copy of the GNU Library General Public License
|
||
|
# along with this program; if not, write to the Free Software
|
||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
|
#
|
||
|
|
||
|
#
|
||
|
# Nagios script to query a munin host for plugin values
|
||
|
#
|
||
|
# Can be used as an active check instead of check_dummy
|
||
|
#
|
||
|
|
||
|
import optparse
|
||
|
import socket
|
||
|
import pprint
|
||
|
import sys
|
||
|
import re
|
||
|
|
||
|
parser = optparse.OptionParser("usage: %prog -H <Host> -M <Module> [-P <Port>] -D [<warn>] [<crit>]")
|
||
|
parser.add_option("-H", "--host", dest="host", type="string",
|
||
|
help="specify host to poll")
|
||
|
parser.add_option("-M", "--module", dest="module", type="string",
|
||
|
help="munin module to poll")
|
||
|
parser.add_option("-P", "--port", dest="port", default=4949,
|
||
|
type="int", help="port number to poll")
|
||
|
parser.add_option("-D", "--debug", action="store_true", dest="debug", default=False,
|
||
|
help="Debug output")
|
||
|
|
||
|
(options, args) = parser.parse_args()
|
||
|
|
||
|
HOST = options.host
|
||
|
PORT = options.port
|
||
|
MODULE = options.module
|
||
|
DEBUG = options.debug
|
||
|
|
||
|
if HOST == None or MODULE == None:
|
||
|
parser.error("options -H and -M are required.")
|
||
|
|
||
|
def compare(val, thresh):
|
||
|
# Compare value to warning and critical threshoulds
|
||
|
# Handle different threshold formats: max, :max, min:, min:max
|
||
|
|
||
|
val = float(val)
|
||
|
|
||
|
# max
|
||
|
match = re.match("^[:]?([-+]?[0-9]+)$", str(thresh))
|
||
|
if match:
|
||
|
max = float(match.group(1))
|
||
|
if val > max:
|
||
|
return 3
|
||
|
|
||
|
|
||
|
# min
|
||
|
match = re.match("^([-+]?[0-9]+):$", str(thresh))
|
||
|
if match:
|
||
|
min = float(match.group(1))
|
||
|
if val < min:
|
||
|
return 2
|
||
|
|
||
|
# min:max
|
||
|
match = re.match("^([-+]?[0-9]+):([-+]?[0-9]+)$", str(thresh))
|
||
|
if match:
|
||
|
min, max = float(match.group(1)), float(match.group(2))
|
||
|
if val < min or val > max:
|
||
|
return 1
|
||
|
|
||
|
# okay
|
||
|
return 0
|
||
|
|
||
|
def output(l, cat, desc, ret):
|
||
|
if len(l[cat]) > 0:
|
||
|
print MODULE, desc + ";"
|
||
|
for line in l["critical"]:
|
||
|
print "CRITICAL: " + line + ";"
|
||
|
for line in l["warning"]:
|
||
|
print "WARNING: " + line + ";"
|
||
|
for line in l["ok"]:
|
||
|
print "OK: " + line + ";"
|
||
|
sys.exit(ret)
|
||
|
|
||
|
try:
|
||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||
|
s.connect((HOST, PORT))
|
||
|
conn = s.makefile('wb', 0)
|
||
|
except:
|
||
|
print "Couldn't connect to requested host"
|
||
|
sys.exit(3)
|
||
|
|
||
|
|
||
|
if conn.readline().startswith("# munin node at"):
|
||
|
conn.writelines("config" + MODULE + "\n")
|
||
|
order = []
|
||
|
data = {}
|
||
|
while True:
|
||
|
line = conn.readline()
|
||
|
if DEBUG:
|
||
|
pprint.pprint(line)
|
||
|
# Last message, bail
|
||
|
if line == ".\n":
|
||
|
break
|
||
|
|
||
|
label = ""
|
||
|
|
||
|
key, val = line.split(" ", 1)
|
||
|
if key.find(".") is not -1:
|
||
|
label = key.split(".")[0]
|
||
|
if label not in data:
|
||
|
data[label] = { "warning" : "", "critical" : "", "value" : "" }
|
||
|
order.append(label)
|
||
|
# No thresholds passed on the command line
|
||
|
if len(args) == 2:
|
||
|
data[label]["warning"] = args[0]
|
||
|
data[label]["critical"] = args[1]
|
||
|
|
||
|
# No thresholds passed on the command line, take the munin supplied ones
|
||
|
if len(args) < 2:
|
||
|
if key.endswith("warning"):
|
||
|
data[label]["warning"] = val[:-1]
|
||
|
if key.endswith("critical"):
|
||
|
data[label]["critical"] = val[:-1]
|
||
|
|
||
|
if data[label]["warning"] == "" or data[label]["critical"] == "":
|
||
|
print "UNKNOWN - Couldn't retrieve thresholds, pass some on the command line"
|
||
|
sys.exit(3)
|
||
|
|
||
|
|
||
|
conn.writelines("fetch " + MODULE + "\n")
|
||
|
while True:
|
||
|
line = conn.readline()
|
||
|
# Last line, bail
|
||
|
if line == ".\n":
|
||
|
if DEBUG:
|
||
|
pprint.pprint(data)
|
||
|
break
|
||
|
|
||
|
key, val = line.split(" ", 1)
|
||
|
label = key.split(".")[0]
|
||
|
if key.endswith("value"):
|
||
|
data[label]["value"] = val[:-1]
|
||
|
|
||
|
conn.writelines("quit\n")
|
||
|
|
||
|
else:
|
||
|
print "UNKNOWN - No munin node detected"
|
||
|
sys.exit(3)
|
||
|
|
||
|
conn.close()
|
||
|
s.close()
|
||
|
|
||
|
l = { "ok" : [], "warning" : [], "critical" : [] }
|
||
|
for entry in order:
|
||
|
# compare actual data: 3 max exceeded, 2 minimum underrun, 1 outside limit, 0 okay
|
||
|
for tresh in ["critical", "warning"]:
|
||
|
val = data[entry]["value"]
|
||
|
tval = data[entry][tresh]
|
||
|
tmp = ""
|
||
|
if compare(val, tval) == 3:
|
||
|
tmp = entry + ": " + val + " has exceeded the maximum threshold of " + tval
|
||
|
break
|
||
|
elif compare(val, tval) == 2:
|
||
|
tmp = entry + ": " + val + " has underrun the minimum threshold of " + tval
|
||
|
break
|
||
|
elif compare(val, tval) == 1:
|
||
|
tmp = entry + ": " + val + " is outside of range " + tval
|
||
|
break
|
||
|
|
||
|
if tmp != "":
|
||
|
l[tresh].append(tmp)
|
||
|
else:
|
||
|
l["ok"].append(entry + ": " + val + " is okay")
|
||
|
|
||
|
|
||
|
output(l, "critical", "CRITICAL", 2)
|
||
|
output(l, "warning", "WARNING", 1)
|
||
|
output(l, "ok", "OK", 0)
|