ffpb_monitoring.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. # -*- coding: utf-8 -*-
  2. from __future__ import print_function
  3. import willie
  4. import shelve
  5. import time
  6. from ffpb import ffpb_ping, pretty_date
  7. monitored_nodes = None
  8. def setup(bot):
  9. global monitored_nodes
  10. # load list of monitored nodes and their last status from disk
  11. monitored_nodes = shelve.open('nodes.monitored', writeback=True)
  12. def shutdown(bot):
  13. global monitored_nodes
  14. # store monitored nodes
  15. if not monitored_nodes is None:
  16. monitored_nodes.sync()
  17. monitored_nodes.close()
  18. monitored_nodes = None
  19. @willie.module.interval(3*60)
  20. def ffpb_monitor_ping(bot):
  21. """Ping each node currently under surveillance."""
  22. # determine where-to to send alerts
  23. notify_target = bot.config.core.owner
  24. if (not bot.config.ffpb.msg_target is None):
  25. notify_target = bot.config.ffpb.msg_target
  26. # check each node under surveillance
  27. for node in monitored_nodes:
  28. mon = monitored_nodes[node]
  29. last_status = mon['status']
  30. last_check = mon['last_check']
  31. last_success = mon['last_success']
  32. current_status = ffpb_ping(bot=bot, target_name=node, reply_directly=False)
  33. if current_status is None: current_status = False
  34. mon['status'] = current_status
  35. mon['last_check'] = time.time()
  36. if current_status == True: mon['last_success'] = time.time()
  37. 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))))
  38. if last_status != current_status and (last_status or current_status):
  39. if last_check is None:
  40. # erster Check, keine Ausgabe
  41. continue
  42. if current_status == True:
  43. bot.msg(notify_target, 'Monitoring: Knoten \'{0}\' pingt wieder (zuletzt {1})'.format(node, pretty_date(last_success) if not last_success is None else '[nie]'))
  44. else:
  45. bot.msg(notify_target, 'Monitoring: Knoten \'{0}\' DOWN'.format(node))
  46. @willie.module.commands('monitor')
  47. def ffpb_monitor(bot, trigger):
  48. """Monitoring capability of the bot, try subcommands add, del, info and list."""
  49. # command is restricted to bot admins
  50. if not trigger.admin:
  51. bot.say('Ich ping hier nicht für jeden durch die Weltgeschichte.')
  52. return
  53. # ensure the user gave arguments (group 2 is the concatenation of all following groups)
  54. if trigger.group(2) is None or len(trigger.group(2)) == 0:
  55. bot.say('Das Monitoring sagt du hast doofe Ohren.')
  56. return
  57. # read additional arguments
  58. cmd = trigger.group(3)
  59. node = trigger.group(4)
  60. if not node is None: node = str(node)
  61. # subcommand 'add': add a node to monitoring
  62. if cmd == "add":
  63. if node in monitored_nodes:
  64. bot.say('Knoten \'{0}\' wird bereits gemonitored.'.format(node))
  65. return
  66. monitored_nodes[node] = {
  67. 'added': trigger.sender,
  68. 'status': None,
  69. 'last_check': None,
  70. 'last_success': None,
  71. }
  72. bot.say('Knoten \'{0}\' wird jetzt ganz genau beobachtet.'.format(node))
  73. return
  74. # subcommand 'del': remote a node from monitoring
  75. if cmd == "del":
  76. if not node in monitored_nodes:
  77. bot.say('Knoten \'{0}\' war gar nicht im Monitoring?!?'.format(node))
  78. return
  79. del monitored_nodes[node]
  80. bot.say('Okidoki, \'{0}\' lasse ich jetzt links liegen.'.format(node))
  81. return
  82. # subcommand 'info': monitoring status of a node
  83. if cmd == "info":
  84. if node in monitored_nodes:
  85. info = monitored_nodes[node]
  86. 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']))
  87. else:
  88. bot.say('Knoten \'{0}\' ist nicht im Monitoring.'.format(node))
  89. return
  90. # subcommand 'list': enumerate all monitored nodes
  91. if cmd == "list":
  92. nodes = ""
  93. for node in monitored_nodes:
  94. nodes = nodes + " " + node
  95. bot.say('Monitoring aktiv für:' + nodes)
  96. return
  97. # subcommand 'help': give some hints what the user can do
  98. if cmd == "help":
  99. bot.say('Entweder "!monitor list" oder "!monitor {add|del|info} <node>"')
  100. return
  101. # no valid subcommand given: complain
  102. bot.say('Mit "' + str(cmd) + '" kann ich nix anfangen, probier doch mal "!monitor help".')