1import gc 2import os 3import signal 4from datetime import datetime 5 6from errbot import BotPlugin, arg_botcmd, botcmd 7from errbot.utils import format_timedelta, global_restart 8 9 10class Health(BotPlugin): 11 @botcmd(template="status") 12 def status(self, msg, args): 13 """If I am alive I should be able to respond to this one""" 14 plugins_statuses = self.status_plugins(msg, args) 15 loads = self.status_load(msg, args) 16 gc = self.status_gc(msg, args) 17 18 return { 19 "plugins_statuses": plugins_statuses["plugins_statuses"], 20 "loads": loads["loads"], 21 "gc": gc["gc"], 22 } 23 24 @botcmd(template="status_load") 25 def status_load(self, _, args): 26 """shows the load status""" 27 try: 28 from posix import getloadavg 29 30 loads = getloadavg() 31 except Exception: 32 loads = None 33 34 return {"loads": loads} 35 36 @botcmd(template="status_gc") 37 def status_gc(self, _, args): 38 """shows the garbage collection details""" 39 return {"gc": gc.get_count()} 40 41 @botcmd(template="status_plugins") 42 def status_plugins(self, _, args): 43 """shows the plugin status""" 44 pm = self._bot.plugin_manager 45 all_blacklisted = pm.get_blacklisted_plugin() 46 all_loaded = pm.get_all_active_plugin_names() 47 all_attempted = sorted(pm.plugin_infos.keys()) 48 plugins_statuses = [] 49 for name in all_attempted: 50 if name in all_blacklisted: 51 if name in all_loaded: 52 plugins_statuses.append(("BA", name)) 53 else: 54 plugins_statuses.append(("BD", name)) 55 elif name in all_loaded: 56 plugins_statuses.append(("A", name)) 57 elif ( 58 pm.get_plugin_obj_by_name(name) is not None 59 and pm.get_plugin_obj_by_name(name).get_configuration_template() 60 is not None 61 and pm.get_plugin_configuration(name) is None 62 ): 63 plugins_statuses.append(("C", name)) 64 else: 65 plugins_statuses.append(("D", name)) 66 67 return {"plugins_statuses": plugins_statuses} 68 69 @botcmd 70 def uptime(self, _, args): 71 """Return the uptime of the bot""" 72 u = format_timedelta(datetime.now() - self._bot.startup_time) 73 since = self._bot.startup_time.strftime("%A, %b %d at %H:%M") 74 return f"I've been up for {u} (since {since})." 75 76 # noinspection PyUnusedLocal 77 @botcmd(admin_only=True) 78 def restart(self, msg, args): 79 """Restart the bot.""" 80 self.send(msg.frm, "Deactivating all the plugins...") 81 self._bot.plugin_manager.deactivate_all_plugins() 82 self.send(msg.frm, "Restarting") 83 self._bot.shutdown() 84 global_restart() 85 return "I'm restarting..." 86 87 # noinspection PyUnusedLocal 88 @arg_botcmd( 89 "--confirm", 90 dest="confirmed", 91 action="store_true", 92 help="confirm you want to shut down", 93 admin_only=True, 94 ) 95 @arg_botcmd( 96 "--kill", 97 dest="kill", 98 action="store_true", 99 help="kill the bot instantly, don't shut down gracefully", 100 admin_only=True, 101 ) 102 def shutdown(self, msg, confirmed, kill): 103 """ 104 Shutdown the bot. 105 106 Useful when the things are going crazy and you don't have access to the machine. 107 """ 108 if not confirmed: 109 yield "Please provide `--confirm` to confirm you really want me to shut down." 110 return 111 112 if kill: 113 yield "Killing myself right now!" 114 os.kill(os.getpid(), signal.SIGKILL) 115 else: 116 yield "Roger that. I am shutting down." 117 os.kill(os.getpid(), signal.SIGINT) 118