#!/usr/bin/env python import requests import traceback import time import json import urllib2 import pytz import hashlib from datetime import datetime, timedelta from itertools import islice from hosted import CONFIG, NODE CONFIG.restart_on_update() SORT_ORDER = [3, 2, 0, 1] def current_time(): timezone = pytz.timezone("Europe/Berlin") now = datetime.utcnow() now = now.replace(tzinfo=pytz.utc) now = now.astimezone(timezone) now = now.replace(tzinfo=None) return now def to_unixtimestamp(dt): return int(time.mktime(dt.timetuple())) def limit_output_lines(output, num_lines=10): actual = len(output) if actual <= num_lines: return output more = actual-(num_lines-1) if more > 1: s = 's' else: s = '' result = output[:(num_lines-1)] result.append('... and {} more line{}'.format( more, s, )) return result def regenerate(): now = current_time() services = { 'generated': to_unixtimestamp(now), 'prettytime': now.strftime('%d.%m.%Y %H:%M:%S'), 'services': [], } try: broken_hosts = set() hosts = requests.get(CONFIG["url_hosts"], auth=(CONFIG["api_user"], CONFIG["api_password"]), verify=CONFIG["ssl_verify"]).json() serv = requests.get(CONFIG["url_services"], auth=(CONFIG["api_user"], CONFIG["api_password"]), verify=CONFIG["ssl_verify"]).json() if 'results' not in hosts: raise KeyError('API call for hosts did not return any results') if 'results' not in serv: raise KeyError('API call for services did not return any results') for host in hosts['results']: if host['attrs']['problem']: broken_hosts.add(host['attrs']['display_name']) if host['attrs']['downtime_depth'] > 0: continue if host['attrs']['acknowledgement'] == 1: if not CONFIG['show_ack']: continue ack = 'ACKNOWLEDGED' else: ack = '' if not CONFIG['show_soft'] and int(host['attrs']['state_type']) == 0: continue services['services'].append({ 'host': host['attrs']['display_name'], 'service': '-- HOST --', 'state': 2, 'type': int(host['attrs']['state_type']), 'output': limit_output_lines(host['attrs']['last_check_result']['output'].splitlines(), 3), 'ack': ack, 'sort': '{}{}{}{}'.format( int(host['attrs']['state_type'])*-1, SORT_ORDER[2], host['attrs']['display_name'], '--', ), }) for svc in serv['results']: if svc['attrs']['problem']: if svc['attrs']['downtime_depth'] > 0 or svc['attrs']['host_name'] in broken_hosts: continue if svc['attrs']['acknowledgement'] == 1: if not CONFIG['show_ack']: continue ack = 'ACKNOWLEDGED' else: ack = '' if not CONFIG['show_soft'] and int(svc['attrs']['state_type']) == 0: continue services['services'].append({ 'host': svc['attrs']['host_name'], 'service': svc['attrs']['display_name'], 'state': int(svc['attrs']['state']), 'type': int(svc['attrs']['state_type']), 'output': limit_output_lines(svc['attrs']['last_check_result']['output'].splitlines()), 'ack': ack, 'sort': '{}{}{}{}'.format( int(svc['attrs']['state_type'])*-1, SORT_ORDER[int(svc['attrs']['state'])], svc['attrs']['host_name'], svc['attrs']['display_name'], ), }) except Exception as e: services['services'].append({ 'host': 'icinga2beamer', 'service': 'INTERNAL', 'state': 2, 'type': 1, 'ack': '', 'output': [repr(e)], 'sort': 999, }) if len(services['services']) == 0: services['services'].append({ 'host': '', 'service': 'icinga2', 'state': 0, 'type': 1, 'ack': '', 'output': ['Everything is fine. Go get some coffee.'], 'sort': 1000, }) services['services'].sort(key=lambda x: x['sort']) with file("services.json", "wb") as f: f.write(json.dumps(services, ensure_ascii=False).encode("utf8")) def main(): while 1: try: regenerate() except Exception: traceback.print_exc() time.sleep(20) if __name__ == "__main__": main()