From ad004f45088ee81723b2a2420b3bce01f0bd845b Mon Sep 17 00:00:00 2001 From: Sahina Bose Date: Fri, 14 Mar 2014 12:49:59 +0530 Subject: plugins: Plugin to check the cluster utilization This plugin sums up the volume utilization outputs in a cluster Added a utils livestatus for common code related to mk_livestatus Added constants for livestatussocket path Change-Id: Id665ad3aaa1140e54c831d721ee874421ae84fa3 Signed-off-by: Sahina Bose Reviewed-on: https://cuckoo.blr.redhat.com:8443/10 Reviewed-by: Bala FA --- plugins/Makefile.am | 3 ++ plugins/check_cluster_vol_usage.py | 105 +++++++++++++++++++++++++++++++++++++ plugins/constants.py.in | 1 + plugins/livestatus.py | 48 +++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100755 plugins/check_cluster_vol_usage.py create mode 100644 plugins/constants.py.in create mode 100644 plugins/livestatus.py (limited to 'plugins') diff --git a/plugins/Makefile.am b/plugins/Makefile.am index fa515d7..9c943f7 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -1,6 +1,9 @@ dist_glusternagiosplugins_PYTHON = \ + constants.py \ + check_cluster_vol_usage.py \ check_remote_host.py \ gluster_host_service_handler.py \ + livestatus.py \ notify_ovirt_engine_handler.py \ $(NULL) diff --git a/plugins/check_cluster_vol_usage.py b/plugins/check_cluster_vol_usage.py new file mode 100755 index 0000000..2225634 --- /dev/null +++ b/plugins/check_cluster_vol_usage.py @@ -0,0 +1,105 @@ +#!/usr/bin/python +# +# check_cluster_vol_usage +# Aggregated cluster capacity utilization for a +# gluster cluster +# The plugin reads status data using mk-livestatus +# Assumptions: +# - Volume utilization service names begin with "Volume-" +# - Host name associated is cluster name +# - All volume utilization output is of form +# "used=;warn;crit;min;max" +# +# Copyright (C) 2014 Red Hat Inc +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# + +import sys +import re +from argparse import ArgumentParser +from plugins import livestatus + + +def checkVolumePerfData(clusterName): + + # Write command to socket + cmd = "GET services\nColumns: description host_name " \ + "perf_data custom_variables\nFilter: " \ + "description ~~ %s\n" % 'Volume-' + table = livestatus.readLiveStatus(cmd) + totalUsed = 0.0 + totalAvail = 0.0 + for row in table: + if len(row) <= 3: + return 0.0, 0.0 + host = row[1] + perf_data = row[2] + if len(perf_data) > 2: + perf_arr = perf_data.split(' ') + used = perf_arr[2].split('=')[1] + avail = perf_arr[1].split('=')[1] + if host == clusterName: + totalUsed += float(re.match(r'\d*\.?\d+', used).group()) + totalAvail += float(re.match(r'\d*\.?\d+', avail).group()) + return totalUsed, totalAvail + +# Main method +if __name__ == "__main__": + + parser = ArgumentParser(description= + "Calculate the aggregate " + "capacity usage in cluster") + parser.add_argument('-w', '--warning', + action='store', + type=int, + dest='warn', + help='Warning in %', + default=70) + parser.add_argument('-c', '--critical', + action='store', + type=int, + dest='crit', + help='Critical threshold Warning in %', + default=95) + parser.add_argument('-hg', '--host-group', + action='store', + type=str, + dest='hostgroup', + help='Name of cluster or hostgroup', + required=True) + args = parser.parse_args() + # Check the various performance statuses for the host + used, avail = checkVolumePerfData(args.hostgroup) + statusstr = "OK" + exitstatus = 0 + if used == 0 and avail == 0: + statusstr = "UNKNOWN" + exitstatus = 3 + else: + warn = int((args.warn * avail) / 100.0) + crit = int((args.crit * avail) / 100.0) + usedpercent = int((used/avail) * 100.0) + if (usedpercent >= args.warn): + statusstr = "WARNING" + exitstatus = 1 + if (usedpercent >= args.crit): + statusstr = "CRITICAL" + exitstatus = 2 + + print ("%s - used %s%% of available %s|used=%s;%s;%s;0;%s;" + % (statusstr, usedpercent, + avail, usedpercent, args.warn, args.crit, 100)) + sys.exit(exitstatus) diff --git a/plugins/constants.py.in b/plugins/constants.py.in new file mode 100644 index 0000000..40dd304 --- /dev/null +++ b/plugins/constants.py.in @@ -0,0 +1 @@ +LIVESTATUS_SOCKETPATH = "@nagioslivestatussocketpath@" diff --git a/plugins/livestatus.py b/plugins/livestatus.py new file mode 100644 index 0000000..ce546ce --- /dev/null +++ b/plugins/livestatus.py @@ -0,0 +1,48 @@ +#!/usr/bin/python +# +# livestatus.py +# Utils to query livestatus +# +# Copyright (C) 2014 Red Hat Inc +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# + +import socket +from plugins import constants + +_socketPath = constants.LIVESTATUS_SOCKETPATH + + +def readLiveStatus(cmd): + # Change the default separators to + # Linefeed for row, | for columns, + # comma for lists such as contacts, semicolon for lists such as hosts + cmd += "\nSeparators: 10 124 44 59" + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + s.connect(_socketPath) + + # Write command to socket + s.send(cmd) + + # Close socket + s.shutdown(socket.SHUT_WR) + + # Read the answer + answer = s.recv(1000) + # Parse the answer into a table + table = [line.split('|') for line in answer.split('\n')[:-1]] + + return table -- cgit