-
Notifications
You must be signed in to change notification settings - Fork 682
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added an check_munin script I had lying around.
If your nagios isntallation uses munin as a passive datasource a check_dummy script is normally installed for the active checks. This script is a replacement and will be able to query your munin-node to get current values. This is great to manually run a check.
- Loading branch information
Showing
1 changed file
with
187 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
#!/usr/bin/python | ||
# | ||
# Copyright (C) 2009 Andreas Thienemann <[email protected]> | ||
# | ||
# 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) |