#!/usr/bin/python ############################################################################## # # Copyright (c) 2007 Syslab.com # # This software is subject to the provisions of the Zope Public License, # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE # ############################################################################## # Tested with ZEO version 2.7.* """%(program)s: check the output of a ZEO monitor usage: %(program)s [options] Options: -h/--help -- print this help text -u/--url -- the URL you want to check -p/--port -- the port where the ZEO monitor is running -s/--storage -- the name of the storage to check -w/--warn -- threshold for the warning state -c/--crit -- threshold for the critical state -a/--action -- the action command. valid values are: conflicts: monitors the number of conflicts, warns if ABOVE threshold commits: monitors the number of commits, warns if ABOVE threshold aborts: monitors the number of aborts, warns if ABOVE threshold stores2loads: monitors tha ratio of store to loads, warns id ABOVE threshold clients: monitors the number of clients, warns if BELOW threshold """ import getopt import os import shutil import sys import urllib STATE_OK = 0 STATE_WARN = 1 STATE_CRIT = 2 STATE_UNKNOWN = 3 ACTIONS = [ 'clients' , 'commits' , 'aborts' , 'conflicts' , 'stores2loads' ] __dbg__ = 0 def dbg(t,d): if __dbg__ == 0: return print "DBG (%s): %s" % (t,d) def usage(stream, msg=None): if msg: print >>stream, msg print >>stream program = os.path.basename(sys.argv[0]) print >>stream, __doc__ % {"program": program} sys.exit(STATE_UNKNOWN) def state_text(state): if state==0: return "OK" if state==1: return "WARNING" if state==2: return "CRITICAL" if state==3: return "UNKNOWN" def main(): try: opts, args = getopt.getopt(sys.argv[1:], "h:u:w:c:p:s:a:", ["help", "url=", "port=", "storage=", "warn=", "crit=", "action=" ] ) except getopt.GetoptError, msg: usage(sys.stderr, "\nIllegal argument") url = "" port = "" storage = "" action = "conflicts" warn = 0 crit = 0 for opt, arg in opts: if opt in ("-h", "--help"): usage(sys.stderr) if opt in ("-u", "--url"): url = arg if opt in ("-p", "--port"): port = arg if opt in ("-s", "--storage"): storage = arg if opt in ("-a", "--action"): action = arg if opt in ("-w", "--warn"): warn = arg.strip() if opt in ("-c", "--crit"): crit = arg.strip() if url=='': usage(sys.stderr, "\nError: No URL supplied") if port=='': usage(sys.stderr, "\nError: No port supplied") if storage=='': usage(sys.stderr, "\nError: No storage specified") if action not in ACTIONS: usage(sys.stderr, "\nError: Action '%s' is not valid" %action) if action in ["clients", "commits", "aborts", "conflicts"]: try: warn = int(warn) except: usage(sys.stderr, "\nError: value for warn ('%s') is not a valid integer" %warn) try: crit = int(crit) except: usage(sys.stderr, "\nError: value for crit ('%s') is not a valid integer" %crit) # action == stores2loads else: try: warn = float(warn) except: usage(sys.stderr, "\nError: value for warn ('%s') is not a valid float" %warn) try: crit = float(crit) except: usage(sys.stderr, "\nError: value for crit ('%s') is not a valid float" %crit) result = getResult(url, port, storage, action, warn, crit) print result[1] sys.exit(result[0]) def getResult(url, port, storage, action, warn, crit): cmd = "telnet %s %s" %(url, port) std_out, std_in, std_err = os.popen3(cmd) data = std_in.read() chunks = data.split('\n\n') state = STATE_UNKNOWN retdata = "" storage_entry = "" for mychunk in chunks: if mychunk.startswith("Storage: %s" % storage): storage_entry = mychunk if not storage_entry: state = STATE_CRIT retdata = "No information about storage '%s' found" %storage lines = storage_entry.split('\n') storagedata = {} for l in lines: k,v = l.split(':', 1) storagedata[k.strip()] = v.strip() if action == "conflicts": val = int(storagedata['Conflicts']) if val <= warn: state = STATE_OK elif val > crit: state = STATE_CRIT elif val > warn: state = STATE_WARN else: state = STATE_UNKNOWN retdata = state_text(state) + " - %d Conflicts for storage %s" %(val, storage) elif action == "clients": val = int(storagedata['Clients']) if val >= warn: state = STATE_OK elif val < crit: state = STATE_CRIT elif val < warn: state = STATE_WARN else: state = STATE_UNKNOWN retdata = state_text(state) + " - %d Clients for storage %s" %(val, storage) elif action == "commits": val = int(storagedata['Commits']) if val <= warn: state = STATE_OK elif val > crit: state = STATE_CRIT elif val > warn: state = STATE_WARN else: state = STATE_UNKNOWN retdata = state_text(state) + " - %d Commits for storage %s" %(val, storage) elif action == "aborts": val = int(storagedata['Aborts']) if val <= warn: state = STATE_OK elif val > crit: state = STATE_CRIT elif val > warn: state = STATE_WARN else: state = STATE_UNKNOWN retdata = state_text(state) + " - %d Aborts for storage %s" %(val, storage) elif action == "stores2loads": val = (float(storagedata['Stores']) + 1) / (float(storagedata['Loads']) + 1) * 100 if val <= warn: state = STATE_OK elif val > crit: state = STATE_CRIT elif val > warn: state = STATE_WARN else: state = STATE_UNKNOWN perfdata = "ratio_percent=%f%%" %val retdata = state_text(state) + " - Ratio of stores to loads for storage %s is %f%% | %s" %(storage, val, perfdata) return (state, retdata) if __name__ == "__main__": main()