diff --git a/allay/builtins/monitoring/__init__.py b/allay/builtins/monitoring/__init__.py new file mode 100644 index 00000000..f7b6b437 --- /dev/null +++ b/allay/builtins/monitoring/__init__.py @@ -0,0 +1,32 @@ + +#============================================================================== +# Requirements +#============================================================================== + +# Standard libs --------------------------------------------------------------- + +# Third party libs ------------------------------------------------------------ + +from LRFutils import logs + +# Project modules ------------------------------------------------------------- + +import allay +from .src.monitoring import * + +#============================================================================== +# Plugin +#============================================================================== + +# Info ------------------------------------------------------------------------ + +VERSION = "0.0.1" +ICON = "👁️‍🗨️" +NAME = "Monitoring" + +# Cog ------------------------------------------------------------------------- + +async def setup(bot: allay.Bot): + "Load cogs related to server configuration" + logs.info(f"Loading {ICON} {NAME} v{VERSION}...") + await bot.add_cog(MonitoringCog(bot), icon=ICON, display_name=NAME) diff --git a/allay/builtins/monitoring/config.yaml b/allay/builtins/monitoring/config.yaml new file mode 100644 index 00000000..12fc7c6d --- /dev/null +++ b/allay/builtins/monitoring/config.yaml @@ -0,0 +1,8 @@ +# Ce programme est régi par la licence CeCILL soumise au droit français et +# respectant les principes de diffusion des logiciels libres. Vous pouvez +# utiliser, modifier et/ou redistribuer ce programme sous les conditions +# de la licence CeCILL diffusée sur le site "http://www.cecill.info". + +enabled: false +push_url: "https://uptimekuma.url/api/push/" +push_monitor: "" \ No newline at end of file diff --git a/allay/builtins/monitoring/src/monitoring.py b/allay/builtins/monitoring/src/monitoring.py new file mode 100644 index 00000000..acc1ccd0 --- /dev/null +++ b/allay/builtins/monitoring/src/monitoring.py @@ -0,0 +1,81 @@ +""" +Ce programme est régi par la licence CeCILL soumise au droit français et +respectant les principes de diffusion des logiciels libres. Vous pouvez +utiliser, modifier et/ou redistribuer ce programme sous les conditions +de la licence CeCILL diffusée sur le site "http://www.cecill.info". +""" + +import time + +import aiohttp +from discord.ext import tasks, commands +from LRFutils import logs + +import allay + + +class MonitoringCog(commands.Cog): + def __init__(self, bot: allay.Bot): + self.bot = bot + self.error_counter = 0 + self.session = aiohttp.ClientSession() + + async def cog_load(self) -> None: + if allay.BotConfig.get("builtins.monitoring.enabled") is True: + for i in range(5): + if await self.ping_monitoring(): + logs.info("Monitoring test ping successful") + logs.info("Monitoring enabled") + self.loop.start() # pylint: disable=no-member + return + logs.error("Monitoring ping failed %s times", i + 1) + time.sleep(5) + self.bot.dispatch( + "error", RuntimeError("Monitoring disabled due to ping failure") + ) + + async def ping_monitoring(self): + # retrieve Discord Ping + ping = round(self.bot.latency * 1000, 0) + + # build URL + url = ( + allay.BotConfig.get("builtins.monitoring.push_url") + + allay.BotConfig.get("builtins.monitoring.push_monitor") + + "?status=up&msg=OK&ping=" + + str(ping) + ) + + # send request + async with self.session.get(url) as resp: + if resp.status != 200: + logs.error("Monitoring ping failed with status %s", resp.status) + return False + json = await resp.json() + try: + if not json["ok"]: + logs.error( + "Monitoring ping failed with error : %s", json["msg"] + ) + return False + return True + except KeyError: + logs.error("Monitoring ping failed") + return False + + @tasks.loop(seconds=20) + async def loop(self): + if await self.ping_monitoring(): + self.error_counter = 0 + return + self.error_counter += 1 + if self.error_counter >= 6: + self.bot.dispatch( + "error", + RuntimeError("Monitoring disabled due to multiple ping failure"), + ) + self.loop.stop() # pylint: disable=no-member + + @loop.before_loop + async def before_ping_monitoring(self): + await self.bot.wait_until_ready() diff --git a/allay/core/src/bot_config.py b/allay/core/src/bot_config.py index 7a99689c..a7998ff3 100644 --- a/allay/core/src/bot_config.py +++ b/allay/core/src/bot_config.py @@ -42,6 +42,7 @@ def load(setup_if_missing: bool = False): "Check basic requirements and start the setup script if something is missing" plugin_path = "allay/plugins" + builtins_path = "allay/builtins" config_file_exist = os.path.isfile("config.yaml") # Load config template @@ -50,10 +51,16 @@ def load(setup_if_missing: bool = False): # Load plugin config template for plugin in os.listdir(plugin_path): - if os.path.isfile(file := plugin_path + plugin + "/config.yaml"): + if os.path.isfile(file := plugin_path + "/" + plugin + "/config.yaml"): with open(file, encoding='utf-8') as file: BotConfig.__global_config.update({"plugins":{plugin: yaml.safe_load(file)}}) + # Load builtins config template + for builtin in os.listdir(builtins_path): + if os.path.isfile(file := builtins_path + "/" + builtin + "/config.yaml"): + with open(file, encoding='utf-8') as file: + BotConfig.__global_config.update({"builtins":{builtin: yaml.safe_load(file)}}) + # If a config already exist -> overwrite the templates if config_file_exist: with open("config.yaml", "r", encoding='utf-8') as file: