Adding support for -E, -Q, -w, -c, fixing threshold checking on -m, added UnitTest task, removed -l, -g

This commit is contained in:
drewkerrigan 2015-11-18 23:07:50 -05:00
parent 32a8884881
commit fb4e58b635
2 changed files with 283 additions and 135 deletions

View File

@ -37,7 +37,7 @@ Add the following command definition to your commands config (`commands.config`)
define command{
command_name <command_name>
command_line /usr/bin/python /usr/local/nagios/libexec/plugins/check_http_json.py -H <host>:<port> -p <path> [-e|-q|-l|-g <rules>] [-m <metrics>]
command_line /usr/bin/python /usr/local/nagios/libexec/plugins/check_http_json.py -H <host>:<port> -p <path> [-e|-q|-w|-c <rules>] [-m <metrics>]
}
```
@ -49,13 +49,15 @@ More info about options in Usage.
Executing `./check_http_json.py -h` will yield the following details:
```
usage: check_http_json.py [-h] -H HOST [-P PORT] [-B AUTH] [-p PATH] [-D DATA]
usage: check_http_json.py [-h] [-d] [-s] -H HOST [-P PORT] [-p PATH]
[-t TIMEOUT] [-B AUTH] [-D DATA] [-f SEPARATOR]
[-w [KEY_THRESHOLD_WARNING [KEY_THRESHOLD_WARNING ...]]]
[-c [KEY_THRESHOLD_CRITICAL [KEY_THRESHOLD_CRITICAL ...]]]
[-e [KEY_LIST [KEY_LIST ...]]]
[-E [KEY_LIST_CRITICAL [KEY_LIST_CRITICAL ...]]]
[-q [KEY_VALUE_LIST [KEY_VALUE_LIST ...]]]
[-l [KEY_LTE_LIST [KEY_LTE_LIST ...]]]
[-g [KEY_GTE_LIST [KEY_GTE_LIST ...]]]
[-m [METRIC_LIST [METRIC_LIST ...]]] [-s]
[-t TIMEOUT] [-f SEPARATOR] [-d]
[-Q [KEY_VALUE_LIST_CRITICAL [KEY_VALUE_LIST_CRITICAL ...]]]
[-m [METRIC_LIST [METRIC_LIST ...]]]
Nagios plugin which checks json values from a given endpoint against argument
specified rules and determines the status and performance data for that
@ -63,46 +65,57 @@ service
optional arguments:
-h, --help show this help message and exit
-d, --debug Debug mode.
-s, --ssl HTTPS mode.
-H HOST, --host HOST Host.
-P PORT, --port PORT TCP port
-p PATH, --path PATH Path.
-t TIMEOUT, --timeout TIMEOUT
Connection timeout (seconds)
-B AUTH, --basic-auth AUTH
Basic auth string "username:password"
-p PATH, --path PATH Path.
-D DATA, --data DATA The http payload to send as a POST
-f SEPARATOR, --field_separator SEPARATOR
Json Field separator, defaults to "." ; Select element
in an array with "(" ")"
-w [KEY_THRESHOLD_WARNING [KEY_THRESHOLD_WARNING ...]], --warning [KEY_THRESHOLD_WARNING [KEY_THRESHOLD_WARNING ...]]
Warning threshold for these values
(key1[>alias],WarnRange key2[>alias],WarnRange).
WarnRange is in the format [@]start:end, more
information at nagios-plugins.org/doc/guidelines.html.
-c [KEY_THRESHOLD_CRITICAL [KEY_THRESHOLD_CRITICAL ...]], --critical [KEY_THRESHOLD_CRITICAL [KEY_THRESHOLD_CRITICAL ...]]
Critical threshold for these values
(key1[>alias],CriticalRange
key2[>alias],CriticalRange. CriticalRange is in the
format [@]start:end, more information at nagios-
plugins.org/doc/guidelines.html.
-e [KEY_LIST [KEY_LIST ...]], --key_exists [KEY_LIST [KEY_LIST ...]]
Checks existence of these keys to determine status.
Return warning if key is not present.
-E [KEY_LIST_CRITICAL [KEY_LIST_CRITICAL ...]], --key_exists_critical [KEY_LIST_CRITICAL [KEY_LIST_CRITICAL ...]]
Same as -e but return critical if key is not present.
-q [KEY_VALUE_LIST [KEY_VALUE_LIST ...]], --key_equals [KEY_VALUE_LIST [KEY_VALUE_LIST ...]]
Checks equality of these keys and values
(key[>alias],value key2,value2) to determine status.
Multiple key values can be delimited with colon
(key,value1:value2)
-l [KEY_LTE_LIST [KEY_LTE_LIST ...]], --key_lte [KEY_LTE_LIST [KEY_LTE_LIST ...]]
Checks that these keys and values (key[>alias],value
key2,value2) are less than or equal to the returned
json value to determine status.
-g [KEY_GTE_LIST [KEY_GTE_LIST ...]], --key_gte [KEY_GTE_LIST [KEY_GTE_LIST ...]]
Checks that these keys and values (key[>alias],value
key2,value2) are greater than or equal to the returned
json value to determine status.
(key,value1:value2). Return warning if equality check
fails
-Q [KEY_VALUE_LIST_CRITICAL [KEY_VALUE_LIST_CRITICAL ...]], --key_equals_critical [KEY_VALUE_LIST_CRITICAL [KEY_VALUE_LIST_CRITICAL ...]]
Same as -q but return critical if equality check
fails.
-m [METRIC_LIST [METRIC_LIST ...]], --key_metric [METRIC_LIST [METRIC_LIST ...]]
Gathers the values of these keys (key[>alias],UnitOfMe
asure,Min,Max,WarnRange,CriticalRange) for Nagios
asure,WarnRange,CriticalRange,Min,Max) for Nagios
performance data. More information about Range format
and units of measure for nagios can be found at
nagios-plugins.org/doc/guidelines.html Additional
formats for this parameter are: (key),
(key,UnitOfMeasure), (key,UnitOfMeasure,Min,Max).
-s, --ssl HTTPS mode.
-t TIMEOUT, --timeout TIMEOUT
Connection timeout (seconds)
-f SEPARATOR, --field_separator SEPARATOR
Json Field separator, defaults to "." ; Select element
in an array with "(" ")"
-d, --debug Debug mode.
formats for this parameter are: (key[>alias]),
(key[>alias],UnitOfMeasure),
(key[>alias],UnitOfMeasure,WarnRange,CriticalRange).
```
Access a specific JSON field by following this syntax: `alpha.beta.gamma(3).theta.omega(0)`
Dots are field separators (changeable), parantheses are for entering arrays.
Dots are field separators (changeable), parentheses are for entering arrays.
If the root of the JSON data is itself an array like the following:
@ -153,14 +166,12 @@ Let's say we want to use `check_http_json.py` to read from Docker's `/info` HTTP
`localhost.cfg`
```
define service {
use local-service
host_name localhost
service_description Docker info status checker
check_command check_docker
}
```
#### Command Definition with Arguments
@ -168,12 +179,10 @@ define service {
`commands.cfg`
```
define command{
command_name check_docker
command_line /usr/bin/python /usr/local/nagios/libexec/plugins/check_http_json.py -H 127.0.0.1:4243 -p info -e Containers -q IPv4Forwarding,1 -l Debug,2 -g Images,1 -m Containers,,0,1000 Images NEventsListener NFd NGoroutines SwapLimit
command_line /usr/bin/python /usr/local/nagios/libexec/plugins/check_http_json.py -H 127.0.0.1:4243 -p info -e Containers -q IPv4Forwarding,1 -w Debug,2:2 -c Images,1:1 -m Containers,0:250,0:500,0,1000 Images NEventsListener NFd NGoroutines SwapLimit
}
```
#### Sample Output
@ -201,14 +210,12 @@ OK: Status OK.|'Containers'=1;0;1000 'Images'=11;0;0 'NEventsListener'=3;0;0 'NF
`localhost.cfg`
```
define service {
use local-service
host_name localhost
service_description Docker container liveness check
check_command check_my_container
}
```
#### Command Definition with Arguments
@ -216,12 +223,10 @@ define service {
`commands.cfg`
```
define command{
command_name check_my_container
command_line /usr/bin/python /usr/local/nagios/libexec/plugins/check_http_json.py -H 127.0.0.1:4243 -p /containers/2356e8ccb3de8308ccb16cf8f5d157bc85ded5c3d8327b0dfb11818222b6f615/json -q ID,2356e8ccb3de8308ccb16cf8f5d157bc85ded5c3d8327b0dfb11818222b6f615 State.Running,True
}
```
#### Sample Output

View File

@ -10,35 +10,57 @@ and determines the status and performance data for that service.
import httplib, urllib, urllib2, base64
import json
import argparse
import sys
from pprint import pprint
from urllib2 import HTTPError
from urllib2 import URLError
# TEST = False
OK_CODE = 0
WARNING_CODE = 1
CRITICAL_CODE = 2
UNKNOWN_CODE = 3
class NagiosHelper:
"""Help with Nagios specific status string formatting."""
code = 0
message_prefixes = {0: 'OK', 1: 'WARNING', 2: 'CRITICAL', 3: 'UNKNOWN'}
message_text = ''
message_prefixes = {OK_CODE: 'OK', WARNING_CODE: 'WARNING', CRITICAL_CODE: 'CRITICAL', UNKNOWN_CODE: 'UNKNOWN'}
performance_data = ''
warning_message = ''
critical_message = ''
unknown_message = ''
def getMessage(self):
"""Build a status-prefixed message with optional performance data generated externally"""
text = "%s" % self.message_prefixes[self.code]
if self.message_text:
text += ": %s" % self.message_text
text = "%s: Status %s." % (self.message_prefixes[self.getCode()], self.message_prefixes[self.getCode()])
text += self.warning_message
text += self.critical_message
text += self.unknown_message
if self.performance_data:
text += "|%s" % self.performance_data
return text
def setCodeAndMessage(self, code, text):
self.code = code
self.message_text = text
def getCode(self):
code = OK_CODE
if (self.warning_message != ''):
code = WARNING_CODE
if (self.critical_message != ''):
code = CRITICAL_CODE
if (self.unknown_message != ''):
code = UNKNOWN_CODE
return code
def ok(self, text): self.setCodeAndMessage(0, text)
def warning(self, text): self.setCodeAndMessage(1, text)
def critical(self, text): self.setCodeAndMessage(2, text)
def unknown(self, text): self.setCodeAndMessage(3, text)
def append_warning(self, warning_message):
self.warning_message += warning_message
def append_critical(self, critical_message):
self.critical_message += critical_message
def append_unknown(self, unknown_message):
self.critical_message += critical_message
def append_metrics(self, (performance_data, warning_message, critical_message)):
self.performance_data += performance_data
self.append_warning(warning_message)
self.append_critical(critical_message)
class JsonHelper:
"""Perform simple comparison operations against values in a given JSON dict"""
@ -63,7 +85,6 @@ class JsonHelper:
remainingKey = key[key.find(self.arrayCloser + self.separator) + 2:]
if key.find(self.arrayCloser + self.separator) == -1:
remainingKey = key[key.find(self.arrayCloser) + 1:]
if subElemKey in data:
if index < len(data[subElemKey]):
return self.get(remainingKey, data[subElemKey][index])
@ -77,7 +98,9 @@ class JsonHelper:
def equals(self, key, value): return self.exists(key) and str(self.get(key)) in value.split(':')
def lte(self, key, value): return self.exists(key) and float(self.get(key)) <= float(value)
def lt(self, key, value): return self.exists(key) and float(self.get(key)) < float(value)
def gte(self, key, value): return self.exists(key) and float(self.get(key)) >= float(value)
def gt(self, key, value): return self.exists(key) and float(self.get(key)) > float(value)
def exists(self, key): return (self.get(key) != (None, 'not_found'))
def get(self, key, temp_data=''):
"""Can navigate nested json keys with a dot format (Element.Key.NestedKey). Returns (None, 'not_found') if not found"""
@ -85,10 +108,8 @@ class JsonHelper:
data = temp_data
else:
data = self.data
if len(key) <= 0:
return data
if key.find(self.separator) != -1 and key.find(self.arrayOpener) != -1 :
if key.find(self.separator) < key.find(self.arrayOpener) :
return self.getSubElement(key, data)
@ -111,10 +132,8 @@ def _getKeyAlias(original_key):
alias = original_key
if '>' in original_key:
keys = original_key.split('>')
if len(keys) == 2:
key, alias = keys
return key, alias
class JsonRuleProcessor:
@ -128,105 +147,153 @@ class JsonRuleProcessor:
debugPrint(rules_args.debug, "rules:%s" % rules_args)
debugPrint(rules_args.debug, "separator:%s" % separator)
def isAlive(self):
"""Return a tuple with liveness and reason for not liveness given existence, equality, and comparison rules"""
reason = ''
def checkExists(self, exists_list):
failure = ''
for k in exists_list:
key, alias = _getKeyAlias(k)
if (self.helper.exists(key) == False):
failure += " Key %s did not exist." % alias
return failure
if self.rules.key_list != None:
for k in self.rules.key_list:
key, alias = _getKeyAlias(k)
if (self.helper.exists(key) == False):
reason += " Key %s did not exist." % alias
def checkEquality(self, equality_list):
failure = ''
for kv in equality_list:
k, v = kv.split(',')
key, alias = _getKeyAlias(k)
if (self.helper.equals(key, v) == False):
failure += " Value for key %s did not match %s." % (alias, v)
return failure
def checkThreshold(self, key, alias, r):
failure = ''
invert = False
start = 0
end = 'infinity'
if r.startswith('@'):
invert = True
r = r[1:]
vals = r.split(':')
if len(vals) == 1:
end = vals[0]
if len(vals) == 2:
start = vals[0]
if vals[1] != '':
end = vals[1]
if(start == '~'):
if (invert and self.helper.lte(key, end)):
failure += " Value for key %s was less than or equal to %s." % (alias, end)
elif (not invert and self.helper.gt(key, end)):
failure += " Value for key %s was greater than %s." % (alias, end)
elif(end == 'infinity'):
if (invert and self.helper.gte(key, start)):
failure += " Value for key %s was greater than or equal to %s." % (alias, start)
elif (not invert and self.helper.lt(key, start)):
failure += " Value for key %s was less than %s." % (alias, start)
else:
if (invert and self.helper.gte(key, start) and self.helper.lte(key, end)):
failure += " Value for key %s was inside the range %s:%s." % (alias, start, end)
elif (not invert and (self.helper.lt(key, start) or self.helper.gt(key, end))):
failure += " Value for key %s was outside the range %s:%s." % (alias, start, end)
return failure
def checkThresholds(self, threshold_list):
failure = ''
for threshold in threshold_list:
k, r = threshold.split(',')
key, alias = _getKeyAlias(k)
failure += self.checkThreshold(key, alias, r)
return failure
def checkWarning(self):
failure = ''
if self.rules.key_threshold_warning != None:
failure += self.checkThresholds(self.rules.key_threshold_warning)
if self.rules.key_value_list != None:
for kv in self.rules.key_value_list:
k, v = kv.split(',')
key, alias = _getKeyAlias(k)
if (self.helper.equals(key, v) == False):
reason += " Value for key %s did not match %s." % (alias, v)
failure += self.checkEquality(self.rules.key_value_list)
if self.rules.key_list != None:
failure += self.checkExists(self.rules.key_list)
return failure
if self.rules.key_lte_list != None:
for kv in self.rules.key_lte_list:
k, v = kv.split(',')
key, alias = _getKeyAlias(k)
if (self.helper.lte(key, v) == False):
reason += " Value for key %s was not less than or equal to %s." % (alias, v)
def checkCritical(self):
failure = ''
if self.rules.key_threshold_critical != None:
failure += self.checkThresholds(self.rules.key_threshold_critical)
if self.rules.key_value_list_critical != None:
failure += self.checkEquality(self.rules.key_value_list_critical)
if self.rules.key_list_critical != None:
failure += self.checkExists(self.rules.key_list_critical)
return failure
if self.rules.key_gte_list != None:
for kv in self.rules.key_gte_list:
k, v = kv.split(',')
key, alias = _getKeyAlias(k)
if (self.helper.gte(key, v) == False):
reason += " Value for key %s was not greater than or equal to %s." % (v, alias)
is_alive = (reason == '')
return (is_alive, reason)
def getMetrics(self):
def checkMetrics(self):
"""Return a Nagios specific performance metrics string given keys and parameter definitions"""
metrics = ''
warning = ''
critical = ''
if self.rules.metric_list != None:
for metric in self.rules.metric_list:
key = metric
minimum = maximum = warn_range = crit_range = 0
minimum = maximum = warn_range = crit_range = None
uom = ''
if ',' in metric:
vals = metric.split(',')
if len(vals) == 2:
key,uom = vals
if len(vals) == 4:
key,uom,minimum,maximum = vals
key,uom,warn_range,crit_range = vals
if len(vals) == 6:
key,uom,minimum,maximum,warn_range,crit_range = vals
key,uom,warn_range,crit_range,minimum,maximum = vals
key, alias = _getKeyAlias(key)
if self.helper.exists(key):
metrics += "'%s'=%s" % (alias, self.helper.get(key))
if uom: metrics += uom
metrics += ";%s" % minimum
metrics += ";%s" % maximum
if warn_range: metrics += ";%s" % warn_range
if crit_range: metrics += ";%s" % crit_range
if warn_range != None:
warning += self.checkThreshold(key, alias, warn_range)
metrics += ";%s" % warn_range
if crit_range != None:
critical += self.checkThreshold(key, alias, crit_range)
metrics += ";%s" % crit_range
if minimum != None:
critical += self.checkThreshold(key, alias, minimum + ':')
metrics += ";%s" % minimum
if maximum != None:
critical += self.checkThreshold(key, alias, '~:' + maximum)
metrics += ";%s" % maximum
metrics += ' '
return "%s" % metrics
return ("%s" % metrics, warning, critical)
def parseArgs():
parser = argparse.ArgumentParser(description=
'Nagios plugin which checks json values from a given endpoint against argument specified rules\
and determines the status and performance data for that service')
# parser.add_argument('-v', '--verbose', action='store_true', help='Verbose Output')
parser.add_argument('-d', '--debug', action='store_true', help='Debug mode.')
parser.add_argument('-s', '--ssl', action='store_true', help='HTTPS mode.')
parser.add_argument('-H', '--host', dest='host', required=True, help='Host.')
parser.add_argument('-P', '--port', dest='port', required=False, help='TCP port')
parser.add_argument('-B', '--basic-auth', dest='auth', required=False, help='Basic auth string "username:password"')
parser.add_argument('-P', '--port', dest='port', help='TCP port')
parser.add_argument('-p', '--path', dest='path', help='Path.')
parser.add_argument('-t', '--timeout', type=int, help='Connection timeout (seconds)')
parser.add_argument('-B', '--basic-auth', dest='auth', help='Basic auth string "username:password"')
parser.add_argument('-D', '--data', dest='data', help='The http payload to send as a POST')
parser.add_argument('-f', '--field_separator', dest='separator',
help='Json Field separator, defaults to "." ; Select element in an array with "(" ")"')
parser.add_argument('-w', '--warning', dest='key_threshold_warning', nargs='*',
help='Warning threshold for these values (key1[>alias],WarnRange key2[>alias],WarnRange). WarnRange is in the format [@]start:end, more information at nagios-plugins.org/doc/guidelines.html.')
parser.add_argument('-c', '--critical', dest='key_threshold_critical', nargs='*',
help='Critical threshold for these values (key1[>alias],CriticalRange key2[>alias],CriticalRange. CriticalRange is in the format [@]start:end, more information at nagios-plugins.org/doc/guidelines.html.')
parser.add_argument('-e', '--key_exists', dest='key_list', nargs='*',
help='Checks existence of these keys to determine status.')
help='Checks existence of these keys to determine status. Return warning if key is not present.')
parser.add_argument('-E', '--key_exists_critical', dest='key_list_critical', nargs='*',
help='Same as -e but return critical if key is not present.')
parser.add_argument('-q', '--key_equals', dest='key_value_list', nargs='*',
help='Checks equality of these keys and values (key[>alias],value key2,value2) to determine status.\
Multiple key values can be delimited with colon (key,value1:value2)')
parser.add_argument('-l', '--key_lte', dest='key_lte_list', nargs='*',
help='Checks that these keys and values (key[>alias],value key2,value2) are less than or equal to\
the returned json value to determine status.')
parser.add_argument('-g', '--key_gte', dest='key_gte_list', nargs='*',
help='Checks that these keys and values (key[>alias],value key2,value2) are greater than or equal to\
the returned json value to determine status.')
Multiple key values can be delimited with colon (key,value1:value2). Return warning if equality check fails')
parser.add_argument('-Q', '--key_equals_critical', dest='key_value_list_critical', nargs='*',
help='Same as -q but return critical if equality check fails.')
parser.add_argument('-m', '--key_metric', dest='metric_list', nargs='*',
help='Gathers the values of these keys (key[>alias],UnitOfMeasure,Min,Max,WarnRange,CriticalRange) for Nagios performance data.\
help='Gathers the values of these keys (key[>alias],UnitOfMeasure,WarnRange,CriticalRange,Min,Max) for Nagios performance data.\
More information about Range format and units of measure for nagios can be found at nagios-plugins.org/doc/guidelines.html\
Additional formats for this parameter are: (key), (key,UnitOfMeasure), (key,UnitOfMeasure,Min,Max).')
parser.add_argument('-s', '--ssl', action='store_true', help='HTTPS mode.')
parser.add_argument('-t', '--timeout', type=int, help='Connection timeout (seconds)')
parser.add_argument('-f', '--field_separator', dest='separator', help='Json Field separator, defaults to "." ; Select element in an array with "(" ")"')
parser.add_argument('-d', '--debug', action='store_true', help='Debug mode.')
Additional formats for this parameter are: (key[>alias]), (key[>alias],UnitOfMeasure), (key[>alias],UnitOfMeasure,WarnRange,CriticalRange).')
return parser.parse_args()
@ -237,20 +304,105 @@ def debugPrint(debug_flag, message, pretty_flag=False):
else:
print message
if __name__ == "__main__" and len(sys.argv) >= 2 and sys.argv[1] == 'UnitTest':
import unittest
class RulesHelper:
separator = '.'
debug = False
key_threshold_warning,key_value_list,key_list,key_threshold_critical,key_value_list_critical,key_list_critical,metric_list = None, None, None, None, None, None, None
def dash_m(self, data):
self.metric_list = data; return self
def dash_e(self, data):
self.key_list = data; return self
def dash_E(self, data):
self.key_list_critical = data; return self
def dash_q(self, data):
self.key_value_list = data; return self
def dash_Q(self, data):
self.key_value_list_critical = data; return self
def dash_w(self, data):
self.key_threshold_warning = data; return self
def dash_c(self, data):
self.key_threshold_critical = data; return self
class UnitTest(unittest.TestCase):
rules = RulesHelper()
def check_data(self, args, jsondata, code):
data = json.loads(jsondata)
nagios = NagiosHelper()
processor = JsonRuleProcessor(data, args)
nagios.append_warning(processor.checkWarning())
nagios.append_critical(processor.checkCritical())
nagios.append_metrics(processor.checkMetrics())
self.assertEqual(code, nagios.getCode())
def test_metrics(self):
self.check_data(RulesHelper().dash_m(['metric,,1:4,1:5']), '{"metric": 5}', WARNING_CODE)
self.check_data(RulesHelper().dash_m(['metric,,1:5,1:4']), '{"metric": 5}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_m(['metric,,1:5,1:5,6,10']), '{"metric": 5}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_m(['metric,,1:5,1:5,1,4']), '{"metric": 5}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_m(['metric,s,@1:4,@6:10,1,10']), '{"metric": 5}', OK_CODE)
def test_exists(self):
self.check_data(RulesHelper().dash_e(['nothere']), '{"metric": 5}', WARNING_CODE)
self.check_data(RulesHelper().dash_E(['nothere']), '{"metric": 5}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_e(['metric']), '{"metric": 5}', OK_CODE)
def test_equality(self):
self.check_data(RulesHelper().dash_q(['metric,6']), '{"metric": 5}', WARNING_CODE)
self.check_data(RulesHelper().dash_Q(['metric,6']), '{"metric": 5}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_q(['metric,5']), '{"metric": 5}', OK_CODE)
def test_warning_thresholds(self):
self.check_data(RulesHelper().dash_w(['metric,5']), '{"metric": 5}', OK_CODE)
self.check_data(RulesHelper().dash_w(['metric,5:']), '{"metric": 5}', OK_CODE)
self.check_data(RulesHelper().dash_w(['metric,~:5']), '{"metric": 5}', OK_CODE)
self.check_data(RulesHelper().dash_w(['metric,1:5']), '{"metric": 5}', OK_CODE)
self.check_data(RulesHelper().dash_w(['metric,@5']), '{"metric": 6}', OK_CODE)
self.check_data(RulesHelper().dash_w(['metric,@5:']), '{"metric": 4}', OK_CODE)
self.check_data(RulesHelper().dash_w(['metric,@~:5']), '{"metric": 6}', OK_CODE)
self.check_data(RulesHelper().dash_w(['metric,@1:5']), '{"metric": 6}', OK_CODE)
self.check_data(RulesHelper().dash_w(['metric,5']), '{"metric": 6}', WARNING_CODE)
self.check_data(RulesHelper().dash_w(['metric,5:']), '{"metric": 4}', WARNING_CODE)
self.check_data(RulesHelper().dash_w(['metric,~:5']), '{"metric": 6}', WARNING_CODE)
self.check_data(RulesHelper().dash_w(['metric,1:5']), '{"metric": 6}', WARNING_CODE)
self.check_data(RulesHelper().dash_w(['metric,@5']), '{"metric": 5}', WARNING_CODE)
self.check_data(RulesHelper().dash_w(['metric,@5:']), '{"metric": 5}', WARNING_CODE)
self.check_data(RulesHelper().dash_w(['metric,@~:5']), '{"metric": 5}', WARNING_CODE)
self.check_data(RulesHelper().dash_w(['metric,@1:5']), '{"metric": 5}', WARNING_CODE)
def test_critical_thresholds(self):
self.check_data(RulesHelper().dash_c(['metric,5']), '{"metric": 5}', OK_CODE)
self.check_data(RulesHelper().dash_c(['metric,5:']), '{"metric": 5}', OK_CODE)
self.check_data(RulesHelper().dash_c(['metric,~:5']), '{"metric": 5}', OK_CODE)
self.check_data(RulesHelper().dash_c(['metric,1:5']), '{"metric": 5}', OK_CODE)
self.check_data(RulesHelper().dash_c(['metric,@5']), '{"metric": 6}', OK_CODE)
self.check_data(RulesHelper().dash_c(['metric,@5:']), '{"metric": 4}', OK_CODE)
self.check_data(RulesHelper().dash_c(['metric,@~:5']), '{"metric": 6}', OK_CODE)
self.check_data(RulesHelper().dash_c(['metric,@1:5']), '{"metric": 6}', OK_CODE)
self.check_data(RulesHelper().dash_c(['metric,5']), '{"metric": 6}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_c(['metric,5:']), '{"metric": 4}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_c(['metric,~:5']), '{"metric": 6}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_c(['metric,1:5']), '{"metric": 6}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_c(['metric,@5']), '{"metric": 5}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_c(['metric,@5:']), '{"metric": 5}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_c(['metric,@~:5']), '{"metric": 5}', CRITICAL_CODE)
self.check_data(RulesHelper().dash_c(['metric,@1:5']), '{"metric": 5}', CRITICAL_CODE)
def test_separator(self):
rules = RulesHelper()
rules.separator = '_'
self.check_data(
rules.dash_q(['(0)_gauges_jvm.buffers.direct.capacity(1)_value,1234']),
'[{ "gauges": { "jvm.buffers.direct.capacity": [{"value": 215415},{"value": 1234}]}}]',
OK_CODE)
unittest.main()
exit(0)
"""Program entry point"""
if __name__ == "__main__":
args = parseArgs()
nagios = NagiosHelper()
if args.ssl:
url = "https://%s" % args.host
else:
url = "http://%s" % args.host
if args.port: url += ":%s" % args.port
if args.path: url += "/%s" % args.path
debugPrint(args.debug, "url:%s" % url)
# Attempt to reach the endpoint
try:
req = urllib2.Request(url)
@ -266,28 +418,19 @@ if __name__ == "__main__":
else:
response = urllib2.urlopen(req)
except HTTPError as e:
nagios.unknown("HTTPError[%s], url:%s" % (str(e.code), url))
nagios.append_unknown("HTTPError[%s], url:%s" % (str(e.code), url))
except URLError as e:
nagios.critical("URLError[%s], url:%s" % (str(e.reason), url))
nagios.append_critical("URLError[%s], url:%s" % (str(e.reason), url))
else:
jsondata = response.read()
data = json.loads(jsondata)
debugPrint(args.debug, 'json:')
debugPrint(args.debug, data, True)
# Apply rules to returned JSON data
processor = JsonRuleProcessor(data, args)
is_alive, reason = processor.isAlive()
# Gather metrics for display
nagios.performance_data = processor.getMetrics()
if is_alive:
nagios.ok("Status OK.")
else:
nagios.warning("Status check failed, reason:%s" % reason)
nagios.append_warning(processor.checkWarning())
nagios.append_critical(processor.checkCritical())
nagios.append_metrics(processor.checkMetrics())
# Print Nagios specific string and exit appropriately
print nagios.getMessage()
exit(nagios.code)
exit(nagios.getCode())