Browse files

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...
1 parent 227e510 commit 3c6692940b99b344f1b2636e5bd24111d8bbca2e @ixs ixs committed Mar 7, 2012
Showing with 187 additions and 0 deletions.
  1. +187 −0 tools/nagios/check_munin
View
187 tools/nagios/check_munin
@@ -0,0 +1,187 @@
+#!/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)

0 comments on commit 3c66929

Please sign in to comment.