#!/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 or ( host['attrs']['acknowledgement'] > 0 and not CONFIG['show_ack'] ) ): continue if not CONFIG['show_soft'] and int(host['attrs']['state_type']) == 0: continue services['services'].append({ 'host': host['attrs']['display_name'], 'service': '', 'state': 2, 'type': int(host['attrs']['state_type']), 'output': limit_output_lines(host['attrs']['last_check_result']['output'].splitlines(), 3), 'ack': bool(host['attrs']['acknowledgement'] > 0), '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']['host_name'] in broken_hosts or svc['attrs']['downtime_depth'] > 0 or ( svc['attrs']['acknowledgement'] > 0 and not CONFIG['show_ack'] ) ): continue 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': bool(svc['attrs']['acknowledgement'] > 0), '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(CONFIG["refresh_interval"]) if __name__ == "__main__": main()