summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorndarshan <dnarayan@redhat.com>2014-03-17 12:21:42 +0530
committerBala.FA <barumuga@redhat.com>2014-04-29 10:14:32 +0530
commit686b574d3c1e55a778088b58a1a2fc75ce72d280 (patch)
tree89e6335b46c42dcea1c66e80cd7500059856ffd5 /plugins
parentfcf78fd752dd24a8bb8b0bf8f62e7ba7ec0aac55 (diff)
plugins:Fix to handle sadf not accepting time range, test case addition
This patch handles the issue of sadf not accepting time range when used with -x (xml output) option(seen in version 9.0.4). Added unit-test for memory, cpu, swap, network plugins and refactored them. Change-Id: Ie7c2ecfbb38060f236a6faed606bce0aedd27d7a Signed-off-by: ndarshan <dnarayan@redhat.com> Reviewed-on: https://cuckoo.blr.redhat.com:8443/14 Reviewed-by: Bala FA <barumuga@redhat.com> Tested-by: Bala FA <barumuga@redhat.com>
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am6
-rwxr-xr-xplugins/check_disk_and_inode.py12
-rwxr-xr-xplugins/cpu.py108
-rwxr-xr-xplugins/memory.py100
-rwxr-xr-xplugins/network.py86
-rwxr-xr-xplugins/sadf.py314
-rwxr-xr-xplugins/swap.py94
7 files changed, 447 insertions, 273 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 2e2c03e..37da1cd 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -5,10 +5,14 @@ crond_DATA = \
dist_glusternagiosplugins_PYTHON = \
check_disk_and_inode.py \
+ cpu.py \
+ __init__.py \
+ memory.py \
+ network.py \
sadf.py \
+ swap.py \
$(NULL)
EXTRA_DIST = \
$(crond_DATA) \
- __init__.py \
$(NULL)
diff --git a/plugins/check_disk_and_inode.py b/plugins/check_disk_and_inode.py
index 052df3a..02c5cd2 100755
--- a/plugins/check_disk_and_inode.py
+++ b/plugins/check_disk_and_inode.py
@@ -155,8 +155,16 @@ if __name__ == '__main__':
total = (float(used) + float(avail)) / 1000
itot = (float(iused) + float(iavail)) / 1000
disk.append("%s=%.1f;%.1f;%.1f;0;%.1f %s=%.1f;%.1f;%.1f;0;%.1f" % (
- mpath, float(used)/1000, warn*total/100, crit*total/100, total,
- ipath, float(iused)/1000, warn*itot/100, crit*itot/100, itot))
+ mpath,
+ float(used) / 1000,
+ warn * total / 100,
+ crit * total / 100,
+ total,
+ ipath,
+ float(iused) / 1000,
+ warn * itot / 100,
+ crit * itot / 100,
+ itot))
else:
disk.append("%s=%.2f;%s;%s;0;100 %s=%.2f;%s;%s;0;100" % (
mpath, diskUsage, warn, crit, ipath, inodeUsage, warn, crit))
diff --git a/plugins/cpu.py b/plugins/cpu.py
new file mode 100755
index 0000000..89e8b57
--- /dev/null
+++ b/plugins/cpu.py
@@ -0,0 +1,108 @@
+#!/usr/bin/python
+# 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 argparse
+from glusternagios import utils
+import sadf
+
+_sadfCpuCommand = ["sadf", "-x", "--", "-P", "ALL"]
+
+
+def parse_input():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-w", "--warning", action="store",
+ required=True, type=int,
+ help="Warning threshold in percentage")
+ parser.add_argument("-c", "--critical", action="store",
+ required=True, type=int,
+ help="Critical threshold in percentage")
+ sadf.add_common_args(parser)
+ args = parser.parse_args()
+ return args
+
+
+def showCpuStat(warnLevel, critLevel, s):
+ pl_op = {}
+ if not s:
+ pl_op["message"] = ("CPU STATUS UNKNOWN")
+ pl_op['exit_status'] = utils.PluginStatusCode.UNKNOWN
+ return pl_op
+ perfLines = []
+ idleCpu = 0
+ try:
+ for cpu in s['cpu-load']['cpu']:
+ if cpu['number'] == 'all':
+ idleCpu = cpu['idle']
+ perfLines.append(
+ ("cpu_%s_total=%s%%;%s;%s cpu_%s_system=%s%% "
+ "cpu_%s_user=%s%% cpu_%s_idle=%s%%" % (
+ cpu['number'], 100 - float(cpu['idle']),
+ warnLevel, critLevel,
+ cpu['number'], cpu['system'],
+ cpu['number'], cpu['user'],
+ cpu['number'], cpu['idle'])))
+ if len(s['cpu-load']['cpu']) - 1 == 1:
+ break
+ except (KeyError, ValueError, TypeError) as e:
+ pl_op["message"] = "key: %s not found" % str(e)
+ pl_op["exit_status"] = utils.PluginStatusCode.UNKNOWN
+ return pl_op
+
+ totalCpuUsage = 100 - float(idleCpu)
+ if totalCpuUsage > critLevel:
+ pl_op["message"] = ("CPU Status CRITICAL: Total CPU:"
+ "%s%% Idle CPU:%s%% "
+ "| num_of_cpu=%s %s" % (
+ totalCpuUsage, idleCpu,
+ len(s['cpu-load']['cpu']) - 1,
+ " ".join(perfLines)))
+ pl_op['exit_status'] = utils.PluginStatusCode.CRITICAL
+ elif totalCpuUsage > warnLevel:
+ pl_op["message"] = ("CPU Status WARNING: Total CPU"
+ ":%s%% Idle CPU:%s%% "
+ "| num_of_cpu=%s %s" % (
+ totalCpuUsage, idleCpu,
+ len(s['cpu-load']['cpu']) - 1,
+ " ".join(perfLines)))
+ pl_op['exit_status'] = utils.PluginStatusCode.WARNING
+ else:
+ pl_op["message"] = ("CPU Status OK: Total CPU:%s%% Idle CPU:%s%% "
+ "| num_of_cpu=%s %s" % (
+ totalCpuUsage, idleCpu,
+ len(s['cpu-load']['cpu']) - 1,
+ " ".join(perfLines)))
+ pl_op['exit_status'] = utils.PluginStatusCode.OK
+ return pl_op
+
+
+if __name__ == '__main__':
+ args = parse_input()
+ if args.critical <= args.warning:
+ print "UNKNOWN:Critical must be greater than Warning."
+ sys.exit(utils.PluginStatusCode.UNKNOWN)
+ try:
+ st = sadf.getLatestStat(sadf.sadfExecCmd(_sadfCpuCommand),
+ args.interval if args.interval else 1)
+ except (sadf.SadfCmdExecFailedException,
+ sadf.SadfXmlErrorException) as e:
+ print str(e)
+ exit(utils.PluginStatusCode.UNKNOWN)
+ d = showCpuStat(args.warning, args.critical, st)
+ print d["message"]
+ exit(d['exit_status'])
diff --git a/plugins/memory.py b/plugins/memory.py
new file mode 100755
index 0000000..c57a269
--- /dev/null
+++ b/plugins/memory.py
@@ -0,0 +1,100 @@
+#!/usr/bin/python
+# 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 argparse
+import sadf
+from glusternagios import utils
+
+_sadfMemCommand = ["sadf", "-x", "--", "-r"]
+
+
+def parse_input():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-w", "--warning", action="store",
+ required=True, type=int,
+ help="Warning threshold in percentage")
+ parser.add_argument("-c", "--critical", action="store",
+ required=True, type=int,
+ help="Critical threshold in percentage")
+ sadf.add_common_args(parser)
+ args = parser.parse_args()
+ return args
+
+
+def showMemStat(warning, critical, s):
+ pl_op = {}
+ if not s:
+ pl_op["message"] = ("MEMORY STATUS UNKNOWN")
+ pl_op['exit_status'] = utils.PluginStatusCode.UNKNOWN
+ return pl_op
+ try:
+ totalMem = int(s['memory']['memfree']) + int(s['memory']['memused'])
+ except (KeyError, ValueError) as e:
+ pl_op["message"] = "key: %s not found" % str(e)
+ pl_op["exit_status"] = utils.PluginStatusCode.UNKNOWN
+ return pl_op
+
+ crit_value = (totalMem * critical) / 100
+ war_value = (totalMem * warning) / 100
+ if int(s['memory']['memused']) >= crit_value:
+ pl_op["message"] = utils.PluginStatus.CRITICAL
+ pl_op['exit_status'] = utils.PluginStatusCode.CRITICAL
+ elif int(s['memory']['memused']) >= war_value:
+ pl_op["message"] = utils.PluginStatus.WARNING
+ pl_op['exit_status'] = utils.PluginStatusCode.WARNING
+ else:
+ pl_op["message"] = utils.PluginStatus.OK
+ pl_op['exit_status'] = utils.PluginStatusCode.OK
+ try:
+ pl_op["message"] += ("- %.2f%% used(%skB out of %skB)|"
+ "Total=%skB;%s;%s;0;%s"
+ " Used=%skB Buffered=%skB"
+ " Cached=%skB" % (
+ float(s['memory']['memused-percent']),
+ s['memory']['memused'],
+ totalMem,
+ totalMem,
+ war_value,
+ crit_value,
+ totalMem,
+ s['memory']['memused'],
+ s['memory']['buffers'],
+ s['memory']['cached']))
+ except (KeyError, ValueError, TypeError) as e:
+ pl_op["message"] = "key: %s not found" % str(e)
+ pl_op["exit_status"] = utils.PluginStatusCode.UNKNOWN
+ return pl_op
+ return pl_op
+
+if __name__ == '__main__':
+ args = parse_input()
+ if args.critical <= args.warning:
+ print "UNKNOWN:Critical must be greater than Warning."
+ sys.exit(utils.PluginStatusCode.UNKNOWN)
+ try:
+ st = sadf.getLatestStat(sadf.sadfExecCmd(_sadfMemCommand),
+ args.interval if args.interval else 1)
+ except (sadf.SadfCmdExecFailedException,
+ sadf.SadfXmlErrorException) as e:
+ print str(e)
+ exit(utils.PluginStatusCode.UNKNOWN)
+ d = showMemStat(args.warning, args.critical, st)
+ print d["message"]
+ sys.exit(d['exit_status'])
diff --git a/plugins/network.py b/plugins/network.py
new file mode 100755
index 0000000..d25c848
--- /dev/null
+++ b/plugins/network.py
@@ -0,0 +1,86 @@
+#!/usr/bin/python
+# 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 sadf
+import argparse
+from glusternagios import utils
+
+_sadfNetCommand = ["sadf", "-x", "--", "-n", "DEV"]
+
+
+def parse_input():
+ parser = argparse.ArgumentParser()
+ group = parser.add_mutually_exclusive_group()
+ group.add_argument("-e", "--exclude", action="append",
+ help="Parameters to be excluded")
+ group.add_argument("-i", "--include", action="append",
+ help="Parameters to be included")
+ sadf.add_common_args(parser)
+ args = parser.parse_args()
+ return args
+
+
+def showNetStat(s, iface_list=None, list_type=None):
+ pl_op = {}
+ if not s:
+ pl_op["message"] = ("IFACE UNKNOWN")
+ pl_op['exit_status'] = utils.PluginStatusCode.UNKNOWN
+ return pl_op
+ devNames = []
+ perfLines = []
+ try:
+ for dev in s['network']['net-dev']:
+ if list_type == "exclude":
+ if dev['iface'] in iface_list:
+ continue
+ elif list_type == "include":
+ if dev['iface'] not in iface_list:
+ continue
+ devNames.append(dev['iface'])
+ perfLines.append("%s.rxpck=%s %s.txpck=%s %s.rxkB=%s %s.txkB=%s"
+ % (dev['iface'], dev['rxpck'],
+ dev['iface'], dev['txpck'],
+ dev['iface'], dev['rxkB'],
+ dev['iface'], dev['txkB']))
+ except (KeyError, ValueError, TypeError) as e:
+ pl_op["message"] = "key: %s not found" % str(e)
+ pl_op["exit_status"] = utils.PluginStatusCode.UNKNOWN
+ return pl_op
+
+ pl_op["message"] = ("IFACE OK: %s |%s" % (", ".join(devNames),
+ " ".join(perfLines)))
+ pl_op['exit_status'] = utils.PluginStatusCode.OK
+ return pl_op
+
+if __name__ == '__main__':
+ args = parse_input()
+ try:
+ st = sadf.getLatestStat(sadf.sadfExecCmd(_sadfNetCommand),
+ args.interval if args.interval else 1)
+ except (sadf.SadfCmdExecFailedException,
+ sadf.SadfXmlErrorException) as e:
+ print str(e)
+ exit(utils.PluginStatusCode.UNKNOWN)
+ if args.exclude:
+ d = showNetStat(st, args.exclude, "exclude")
+ elif args.include:
+ d = showNetStat(st, args.include, "include")
+ else:
+ d = showNetStat(st)
+ print d["message"]
+ exit(d['exit_status'])
diff --git a/plugins/sadf.py b/plugins/sadf.py
index 0bafb4a..5ac1ed0 100755
--- a/plugins/sadf.py
+++ b/plugins/sadf.py
@@ -1,4 +1,3 @@
-#!/usr/bin/python
# sadf.py -- nagios plugin uses sadf output for perf data
# Copyright (C) 2014 Red Hat Inc
#
@@ -17,22 +16,18 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
-import sys
-import shlex
-import subprocess
-import datetime
-import argparse
-import xml.etree.ElementTree as ET
-from collections import defaultdict
-_twoMinutes = datetime.timedelta(minutes=2)
-_sadfCpuCommand = "sadf -x -- -P ALL"
-_sadfMemoryCommand = "sadf -x -- -r"
-_sadfNetworkCommand = "sadf -x -- -n DEV"
-_sadfSwapSpaceCommand = "sadf -x -- -S"
+from datetime import datetime, timedelta
+from glusternagios import utils
+import xml.etree.cElementTree as etree
+if hasattr(etree, 'ParseError'):
+ _etreeExceptions = (etree.ParseError, AttributeError, ValueError)
+else:
+ _etreeExceptions = (SyntaxError, AttributeError, ValueError)
-class sadfCmdExecFailedException(Exception):
- message = "sadf command failed"
+
+class SadfException(Exception):
+ message = "sadf exception"
def __init__(self, rc=0, out=(), err=()):
self.rc = rc
@@ -55,274 +50,53 @@ class sadfCmdExecFailedException(Exception):
return s
-def execCmd(command):
- proc = subprocess.Popen(command,
- close_fds=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- (out, err) = proc.communicate()
- return (proc.returncode, out, err)
-
+class SadfCmdExecFailedException(SadfException):
+ message = "sadf command failed"
-def etree_to_dict(t):
- d = {t.tag: {} if t.attrib else None}
- children = list(t)
- if children:
- dd = defaultdict(list)
- for dc in map(etree_to_dict, children):
- for k, v in dc.iteritems():
- dd[k].append(v)
- x = {}
- for k, v in dd.iteritems():
- x[k] = v[0] if len(v) == 1 else v
- d = {t.tag: x}
- if t.attrib:
- d[t.tag].update((k, v) for k, v in t.attrib.iteritems())
- if t.text:
- text = t.text.strip()
- if children or t.attrib:
- if text:
- d[t.tag]['#text'] = text
- else:
- d[t.tag] = text
- return d
+class SadfXmlErrorException(SadfException):
+ message = "XML error"
-def _sadfExecCmd(sadfCmd):
- now = datetime.datetime.now()
- start = (now - _twoMinutes).strftime("%H:%M:%S")
- end = now.strftime("%H:%M:%S")
- cmd = sadfCmd + " -s %s -e %s" % (start, end)
+def sadfExecCmd(sadfCmd):
try:
- (rc, out, err) = execCmd(shlex.split(cmd))
+ (rc, out, err) = utils.execCmd(sadfCmd, raw=True)
except (OSError, ValueError) as e:
- raise sadfCmdExecFailedException(err=[str(e)])
+ raise SadfCmdExecFailedException(err=[str(e)])
if rc != 0:
- raise sadfCmdExecFailedException(rc, [out], [err])
-
- root = ET.fromstring(out)
- d = etree_to_dict(root)
- return d['sysstat']['host']['statistics']['timestamp']
-
-
-def _getLatestStat(stats):
- if not stats:
- return {}
- if not isinstance(stats, list):
- return stats
- lstat = stats[0]
- latestTime = datetime.datetime.strptime(lstat['time'],
- "%H:%M:%S")
- for s in stats[1:]:
- thisTime = datetime.datetime.strptime(s['time'],
- "%H:%M:%S")
- if latestTime < thisTime:
- lstat = s
- latestTime = thisTime
-
- return lstat
-
-
-def getLatestSadfCpuStat():
- return _getLatestStat(_sadfExecCmd(_sadfCpuCommand))
-
-
-def getLatestSadfMemStat():
- return _getLatestStat(_sadfExecCmd(_sadfMemoryCommand))
-
-
-def getLatestSadfNetStat():
- return _getLatestStat(_sadfExecCmd(_sadfNetworkCommand))
+ raise SadfCmdExecFailedException(rc, out, err)
+ try:
+ return etree.fromstring(out)
+ except _etreeExceptions:
+ raise SadfXmlErrorException(err=out)
-def getLatestSadfSwapStat():
- return _getLatestStat(_sadfExecCmd(_sadfSwapSpaceCommand))
-
-
-def showCpuStat(warnLevel, critLevel):
- s = getLatestSadfCpuStat()
- if not s:
- sys.stdout.write("CPU UNKNOWN\n")
- sys.exit(3)
- perfLines = []
- idleCpu = 0
- for cpu in s['cpu-load']['cpu']:
- if cpu['number'] == 'all':
- idleCpu = cpu['idle']
- perfLines.append(
- ("cpu_%s_total=%s%%;%s;%s cpu_%s_system=%s%% "
- "cpu_%s_user=%s%% cpu_%s_idle=%s%%" % (
- cpu['number'], 100-float(cpu['idle']),
- warnLevel, critLevel,
- cpu['number'], cpu['system'],
- cpu['number'], cpu['user'],
- cpu['number'], cpu['idle'])))
- if len(s['cpu-load']['cpu'])-1 == 1:
- break
- totalCpuUsage = 100 - float(idleCpu)
- if totalCpuUsage > critLevel:
- sys.stdout.write(
- ("CPU Status CRITICAL: Total CPU:%s%% Idle CPU:%s%% "
- "| num_of_cpu=%s %s\n" % (totalCpuUsage, idleCpu,
- len(s['cpu-load']['cpu'])-1,
- " ".join(perfLines))))
- elif totalCpuUsage > warnLevel:
- sys.stdout.write(
- ("CPU Status WARNING: Total CPU:%s%% Idle CPU:%s%% "
- "| num_of_cpu=%s %s\n" % (totalCpuUsage, idleCpu,
- len(s['cpu-load']['cpu'])-1,
- " ".join(perfLines))))
- else:
- sys.stdout.write(
- ("CPU Status OK: Total CPU:%s%% Idle CPU:%s%% "
- "| num_of_cpu=%s %s\n" % (totalCpuUsage, idleCpu,
- len(s['cpu-load']['cpu'])-1,
- " ".join(perfLines))))
-
- sys.exit(0)
-
-
-def showSwapStat(warning, critical):
- s = getLatestSadfSwapStat()
- if not s:
- sys.stdout.write("IFACE UNKNOWN\n")
- sys.exit(3)
- totalSwap = int(s['memory']['swpfree']) + int(s['memory']['swpused'])
- crit_value = (totalSwap * critical) / 100
- war_value = (totalSwap * warning) / 100
- if int(s['memory']['swpused']) >= crit_value:
- sys.stdout.write("CRITICAL")
- eStat = 2
- elif int(s['memory']['swpused']) >= war_value:
- sys.stdout.write("WARNING")
- eStat = 1
- else:
- sys.stdout.write("OK")
- eStat = 0
- sys.stdout.write("- %.2f%% used(%skB out of %skB)|Used=%skB;%s;"
- "%s;0;%s\n" % (float(s['memory']['swpused-percent']),
- s['memory']['swpused'],
- totalSwap,
- s['memory']['swpused'],
- war_value,
- crit_value,
- totalSwap))
- sys.exit(eStat)
-
-
-def showMemStat(warning, critical):
- s = getLatestSadfMemStat()
- if not s:
- sys.stdout.write("IFACE UNKNOWN\n")
- sys.exit(3)
- totalMem = int(s['memory']['memfree']) + int(s['memory']['memused'])
- crit_value = (totalMem * critical) / 100
- war_value = (totalMem * warning) / 100
- if int(s['memory']['memused']) >= crit_value:
- sys.stdout.write("CRITICAL")
- eStat = 2
- elif int(s['memory']['memused']) >= war_value:
- sys.stdout.write("WARNING")
- eStat = 1
- else:
- sys.stdout.write("OK")
- eStat = 0
- sys.stdout.write("- %.2f%% used(%skB out of %skB)|Total=%skB;%s;%s;0;%s"
- " Used=%skB Buffered=%skB"
- " Cached=%skB\n" % (float(s['memory']['memused-percent']),
- s['memory']['memused'],
- totalMem,
- totalMem,
- war_value,
- crit_value,
- totalMem,
- s['memory']['memused'],
- s['memory']['buffers'],
- s['memory']['cached']))
- sys.exit(eStat)
-
-
-def showNetStat(iface_list=None, list_type=None):
- s = getLatestSadfNetStat()
- if not s:
- sys.stdout.write("IFACE UNKNOWN\n")
- sys.exit(3)
-
- devNames = []
- perfLines = []
- for dev in s['network']['net-dev']:
- if list_type == "exclude":
- if dev['iface'] in iface_list:
- continue
- elif list_type == "include":
- if dev['iface'] not in iface_list:
- continue
- devNames.append(dev['iface'])
- perfLines.append("%s.rxpck=%s %s.txpck=%s %s.rxkB=%s %s.txkB=%s"
- % (dev['iface'], dev['rxpck'],
- dev['iface'], dev['txpck'],
- dev['iface'], dev['rxkB'],
- dev['iface'], dev['txkB']))
- sys.stdout.write("IFACE OK: %s |%s\n" % (", ".join(devNames),
- " ".join(perfLines)))
- sys.exit(0)
+def utcnow():
+ return datetime.utcnow()
-def parse_input():
- parser = argparse.ArgumentParser(usage='%(prog)s [-h] (\
-\n-m -w <warning> -c <critical> |\n-s -w <warning> -c <critical>\
- |\n-cp -w <warning> -c <critical> |\n-n [-e <exclude>\
- | -i <include>])')
- group1 = parser.add_mutually_exclusive_group(required=True)
- group1.add_argument('-m', '--memory', action='store_true',
- help="Gives details related to memory")
- group1.add_argument('-s', '--swap', action='store_true',
- help="Gives details related to swap")
- group1.add_argument('-cp', '--cpu', action='store_true',
- help="Gives details related to cpu")
- group1.add_argument('-n', '--network', action='store_true',
- help="Gives details related to network")
- parser.add_argument("-w", "--warning", action="store", type=int,
- help="Warning threshold in percentage")
- parser.add_argument("-c", "--critical", action="store", type=int,
- help="Critical threshold in percentage")
- group2 = parser.add_mutually_exclusive_group()
- group2.add_argument("-e", "--exclude", action="append",
- help="Parameters to be excluded")
- group2.add_argument("-i", "--include", action="append",
- help="Parameters to be included")
- args = parser.parse_args()
- if args.memory or args.swap or args.cpu:
- if not args.critical or not args.warning:
- print "UNKNOWN:Missing critical/warning threshold value."
- sys.exit(3)
- if args.exclude or args.include:
- print "UNKNOWN:Exclude/Include is not valid for the given option."
- sys.exit(3)
- if args.critical <= args.warning:
- print "UNKNOWN:Critical must be greater than Warning."
- sys.exit(3)
+def getLatestStat(root, interval=1):
+ try:
+ el = root.findall('host/statistics/timestamp')[-1]
+ except (_etreeExceptions + (IndexError,)):
+ raise SadfXmlErrorException(err=[etree.tostring(root)])
+
+ d = utils.xml2dict(el)
+ statTime = datetime.strptime("%s %s" % (d['timestamp']['date'],
+ d['timestamp']['time']),
+ "%Y-%m-%d %H:%M:%S")
+ minutes = timedelta(minutes=interval)
+ now = utcnow()
+ if (now - statTime) <= minutes:
+ return d['timestamp']
else:
- if args.critical or args.warning:
- print "UNKNOWN:Warning/Critical is not valid for the given option."
- sys.exit(3)
- return args
+ return None
-if __name__ == '__main__':
- args = parse_input()
- if args.memory:
- showMemStat(args.warning, args.critical)
- if args.swap:
- showSwapStat(args.warning, args.critical)
- if args.cpu:
- showCpuStat(args.warning, args.critical)
- if args.network:
- if args.exclude:
- showNetStat(args.exclude, "exclude")
- if args.include:
- showNetStat(args.include, "include")
- showNetStat()
+def add_common_args(parser):
+ parser.add_argument("-t", "--interval", action="store",
+ type=int,
+ help="Interval of time(min) older than"
+ " which sadf output in considered stale")
diff --git a/plugins/swap.py b/plugins/swap.py
new file mode 100755
index 0000000..5e44f6e
--- /dev/null
+++ b/plugins/swap.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+# 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 sadf
+import sys
+import argparse
+from glusternagios import utils
+
+_sadfSwapCommand = ["sadf", "-x", "--", "-S"]
+
+
+def parse_input():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-w", "--warning", action="store",
+ required=True, type=int,
+ help="Warning threshold in percentage")
+ parser.add_argument("-c", "--critical", action="store",
+ required=True, type=int,
+ help="Critical threshold in percentage")
+ sadf.add_common_args(parser)
+ args = parser.parse_args()
+ return args
+
+
+def showSwapStat(warning, critical, s):
+ pl_op = {}
+ if not s:
+ pl_op["message"] = ("SWAP STATUS UNKNOWN")
+ pl_op['exit_status'] = utils.PluginStatusCode.UNKNOWN
+ return pl_op
+ try:
+ totalSwap = int(s['memory']['swpfree']) + int(s['memory']['swpused'])
+ except (KeyError, ValueError, TypeError) as e:
+ pl_op["message"] = "key: %s not found" % str(e)
+ pl_op["exit_status"] = utils.PluginStatusCode.UNKNOWN
+ return pl_op
+
+ crit_value = (totalSwap * critical) / 100
+ war_value = (totalSwap * warning) / 100
+ if int(s['memory']['swpused']) >= crit_value:
+ pl_op["message"] = utils.PluginStatus.CRITICAL
+ pl_op['exit_status'] = utils.PluginStatusCode.CRITICAL
+ elif int(s['memory']['swpused']) >= war_value:
+ pl_op["message"] = utils.PluginStatus.WARNING
+ pl_op['exit_status'] = utils.PluginStatusCode.WARNING
+ else:
+ pl_op["message"] = utils.PluginStatus.OK
+ pl_op['exit_status'] = utils.PluginStatusCode.OK
+ try:
+ pl_op["message"] += ("- %.2f%% used(%skB out of %skB)|Used=%skB;%s;"
+ "%s;0;%s" % (
+ float(s['memory']['swpused-percent']),
+ s['memory']['swpused'],
+ totalSwap,
+ s['memory']['swpused'],
+ war_value,
+ crit_value,
+ totalSwap))
+ except (KeyError, ValueError, TypeError) as e:
+ pl_op["message"] = "key: %s not found" % str(e)
+ pl_op["exit_status"] = utils.PluginStatusCode.UNKNOWN
+ return pl_op
+ return pl_op
+
+if __name__ == '__main__':
+ args = parse_input()
+ if args.critical <= args.warning:
+ print "UNKNOWN:Critical must be greater than Warning."
+ sys.exit(utils.PluginStatusCode.UNKNOWN)
+ try:
+ st = sadf.getLatestStat(sadf.sadfExecCmd(_sadfSwapCommand),
+ args.interval if args.interval else 1)
+ except (sadf.SadfCmdExecFailedException,
+ sadf.SadfXmlErrorException) as e:
+ print str(e)
+ exit(utils.PluginStatusCode.UNKNOWN)
+ d = showSwapStat(args.warning, args.critical, st)
+ print d["message"]
+ exit(d['exit_status'])