1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
#!/usr/bin/env python
import sys
import urllib
from future.utils import lrange
"""check_buildbot.py -H hostname -p httpport [options]
nagios check for buildbot.
requires that both metrics and web status enabled.
Both hostname and httpport must be set, or alternatively use url which
should be the full url to the metrics json resource"""
try:
import simplejson as json
except ImportError:
import json
OK, WARNING, CRITICAL, UNKNOWN = lrange(4)
STATUS_TEXT = ["OK", "Warning", "Critical", "Unknown"]
STATUS_CODES = dict(OK=OK, WARNING=WARNING, CRIT=CRITICAL)
def exit(level, msg):
print(f"{STATUS_TEXT[level]}: {msg}")
sys.exit(level)
def main():
from optparse import OptionParser
parser = OptionParser(__doc__)
parser.set_defaults(hostname=None, httpport=None, url=None, verbosity=0)
parser.add_option("-H", "--host", dest="hostname", help="Hostname")
parser.add_option("-p", "--port", dest="httpport", type="int", help="WebStatus port")
parser.add_option("-u", "--url", dest="url", help="Metrics url")
parser.add_option(
"-v", "--verbose", dest="verbosity", action="count", help="Increase verbosity"
)
options, args = parser.parse_args()
if options.hostname and options.httpport:
url = f"http://{options.hostname}:{options.httpport}/json/metrics"
elif options.url:
url = options.url
else:
exit(UNKNOWN, "You must specify both hostname and httpport, or just url")
try:
data = urllib.urlopen(url).read()
except Exception:
exit(CRITICAL, f"Error connecting to {url}")
try:
data = json.loads(data)
except ValueError:
exit(CRITICAL, f"Could not parse output of {url} as json")
if not data:
exit(WARNING, f"{url} returned null; are metrics disabled?")
alarms = data['alarms']
status = OK
messages = []
for alarm_name, alarm_state in alarms.items():
if options.verbosity >= 2:
messages.append(f"{alarm_name}: {alarm_state}")
try:
alarm_code = STATUS_CODES[alarm_state[0]]
except (KeyError, IndexError):
status = UNKNOWN
messages.append(f"{alarm_name} has unknown alarm state {alarm_state}")
continue
status = max(status, alarm_code)
if alarm_code > OK and options.verbosity < 2:
messages.append(f"{alarm_name}: {alarm_state}")
if not messages and status == OK:
messages.append("no problems")
exit(status, ";".join(messages))
if __name__ == '__main__':
main()
|