ffpb_monitoring.py 4.6 KB

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