# -*- coding: utf-8 -*- from __future__ import print_function import willie import shelve import time from ffpb import ffpb_ping, playitsafe, pretty_date monitored_nodes = None def setup(bot): """Called by willie upon loading this plugin.""" global monitored_nodes # load list of monitored nodes and their last status from disk monitored_nodes = shelve.open('nodes.monitored', writeback=True) def shutdown(bot): """Called by willie upon unloading this plugin.""" global monitored_nodes # store monitored nodes if not monitored_nodes is None: monitored_nodes.sync() monitored_nodes.close() monitored_nodes = None @willie.module.interval(3*60) def ffpb_monitor_ping(bot): """Ping each node currently under surveillance.""" # determine where-to to send alerts notify_target = bot.config.core.owner if not bot.config.ffpb.msg_target is None: notify_target = bot.config.ffpb.msg_target # check each node under surveillance for node in monitored_nodes: mon = monitored_nodes[node] last_status = mon['status'] last_check = mon['last_check'] last_success = mon['last_success'] current_status = ffpb_ping(bot=bot, target_name=node, reply_directly=False) if current_status is None: current_status = False mon['status'] = current_status mon['last_check'] = time.time() if current_status is True: mon['last_success'] = time.time() print("Monitoring ({0}) {1} (last: {2} at {3})".format( node, current_status, last_status, time.strftime('%Y-%m-%d %H:%M', time.localtime(last_check))), ) if last_status != current_status and (last_status or current_status): if last_check is None: # erster Check, keine Ausgabe continue if current_status is True: msg = 'Monitoring: Knoten \'{0}\' pingt wieder (zuletzt {1})' else: msg = 'Monitoring: Knoten \'{0}\' DOWN' bot.msg(notify_target, msg.format( node, pretty_date(last_success) if not last_success is None else '[nie]', )) @willie.module.commands('monitor') def ffpb_monitor(bot, trigger): """ Monitoring capability of the bot. Try subcommands add, del, info and list. """ # command is restricted to bot admins if not playitsafe(bot, trigger, botadmin=True): return # ensure the user gave arguments if trigger.group(2) is None or len(trigger.group(2)) == 0: bot.say('Das Monitoring sagt du hast doofe Ohren.') return # read additional arguments cmd = trigger.group(3) node = trigger.group(4) if not node is None: node = str(node) # subcommand 'add': add a node to monitoring if cmd == "add": if node in monitored_nodes: bot.say('Knoten \'{0}\' wird bereits gemonitored.'.format(node)) return monitored_nodes[node] = { 'added': trigger.sender, 'status': None, 'last_check': None, 'last_success': None, } bot.say('Knoten \'{0}\' wird jetzt ganz genau beobachtet.'.format(node)) return # subcommand 'del': remote a node from monitoring if cmd == "del": if not node in monitored_nodes: bot.say('Knoten \'{0}\' war gar nicht im Monitoring?!?'.format(node)) return del monitored_nodes[node] bot.say('Okidoki, \'{0}\' lasse ich jetzt links liegen.'.format(node)) return # subcommand 'info': monitoring status of a node if cmd == "info": if node in monitored_nodes: info = monitored_nodes[node] bot.say('Knoten \'{0}\' wurde zuletzt {1} gepingt (Ergebnis: {2})'.format(node, pretty_date(info['last_check']) if not info['last_check'] is None else "^W noch nie", info['status'])) else: bot.say('Knoten \'{0}\' ist nicht im Monitoring.'.format(node)) return # subcommand 'list': enumerate all monitored nodes if cmd == "list": nodes = "" for node in monitored_nodes: nodes = nodes + " " + node bot.say('Monitoring aktiv für:' + nodes) return # subcommand 'help': give some hints what the user can do if cmd == "help": bot.say('Entweder "!monitor list" oder "!monitor {add|del|info} "') return # no valid subcommand given: complain bot.say('Mit "' + str(cmd) + '" kann ich nix anfangen, probier doch mal "!monitor help".')