feat(meta): Add a system status reporter.
This commit is contained in:
@@ -10,6 +10,7 @@ from discord import app_commands as appcmds
|
||||
from meta import LionCog, LionBot, LionContext
|
||||
from meta.logger import log_wrap
|
||||
from meta.sharding import THIS_SHARD
|
||||
from meta.monitor import ComponentMonitor, ComponentStatus, StatusLevel
|
||||
from utils.lib import utc_now
|
||||
|
||||
from wards import low_management_ward
|
||||
@@ -42,12 +43,25 @@ class TimerCog(LionCog):
|
||||
self.bot = bot
|
||||
self.data = bot.db.load_registry(TimerData())
|
||||
self.settings = TimerSettings()
|
||||
self.monitor = ComponentMonitor('TimerCog', self._monitor)
|
||||
|
||||
self.timer_options = TimerOptions()
|
||||
|
||||
self.ready = False
|
||||
self.timers = defaultdict(dict)
|
||||
|
||||
async def _monitor(self):
|
||||
if not self.ready:
|
||||
level = StatusLevel.STARTING
|
||||
info = "(STARTING) Not ready. {timers} timers loaded."
|
||||
else:
|
||||
level = StatusLevel.OKAY
|
||||
info = "(OK) {timers} timers loaded."
|
||||
data = dict(timers=len(self.timers))
|
||||
return ComponentStatus(level, info, info, data)
|
||||
|
||||
async def cog_load(self):
|
||||
self.bot.system_monitor.add_component(self.monitor)
|
||||
await self.data.init()
|
||||
|
||||
self.bot.core.guild_config.register_model_setting(self.settings.PomodoroChannel)
|
||||
|
||||
@@ -13,6 +13,7 @@ from meta import LionCog, LionBot, LionContext
|
||||
from meta.logger import log_wrap
|
||||
from meta.errors import UserInputError, ResponseTimedOut
|
||||
from meta.sharding import THIS_SHARD
|
||||
from meta.monitor import ComponentMonitor, ComponentStatus, StatusLevel
|
||||
from utils.lib import utc_now, error_embed
|
||||
from utils.ui import Confirm
|
||||
from utils.data import MULTIVALUE_IN, MEMBERS
|
||||
@@ -38,6 +39,10 @@ class ScheduleCog(LionCog):
|
||||
self.bot = bot
|
||||
self.data: ScheduleData = bot.db.load_registry(ScheduleData())
|
||||
self.settings = ScheduleSettings()
|
||||
self.monitor = ComponentMonitor(
|
||||
'ScheduleCog',
|
||||
self._monitor
|
||||
)
|
||||
|
||||
# Whether we are ready to take events
|
||||
self.initialised = asyncio.Event()
|
||||
@@ -57,12 +62,56 @@ class ScheduleCog(LionCog):
|
||||
|
||||
self.session_channels = self.settings.SessionChannels._cache
|
||||
|
||||
async def _monitor(self):
|
||||
nowid = self.nowid
|
||||
now = None
|
||||
now_lock = self.slotlock(nowid)
|
||||
if not self.initialised.is_set():
|
||||
level = StatusLevel.STARTING
|
||||
info = (
|
||||
"(STARTING) "
|
||||
"Not ready. "
|
||||
"Spawn task is {spawn}. "
|
||||
"Spawn lock is {spawn_lock}. "
|
||||
"Active slots {active}."
|
||||
)
|
||||
elif nowid not in self.active_slots:
|
||||
level = StatusLevel.UNSURE
|
||||
info = (
|
||||
"(UNSURE) "
|
||||
"Setup, but current slotid {nowid} not active. "
|
||||
"Spawn task is {spawn}. "
|
||||
"Spawn lock is {spawn_lock}. "
|
||||
"Now lock is {now_lock}. "
|
||||
"Active slots {active}."
|
||||
)
|
||||
else:
|
||||
now = self.active_slots[nowid]
|
||||
level = StatusLevel.OKAY
|
||||
info = (
|
||||
"(OK) "
|
||||
"Running current slot {now}. "
|
||||
"Spawn lock is {spawn_lock}. "
|
||||
"Now lock is {now_lock}. "
|
||||
"Active slots {active}."
|
||||
)
|
||||
data = {
|
||||
'spawn': self.spawn_task,
|
||||
'spawn_lock': self.spawn_lock,
|
||||
'active': self.active_slots,
|
||||
'nowid': nowid,
|
||||
'now_lock': now_lock,
|
||||
'now': now,
|
||||
}
|
||||
return ComponentStatus(level, info, info, data)
|
||||
|
||||
@property
|
||||
def nowid(self):
|
||||
now = utc_now()
|
||||
return time_to_slotid(now)
|
||||
|
||||
async def cog_load(self):
|
||||
self.bot.system_monitor.add_component(self.monitor)
|
||||
await self.data.init()
|
||||
|
||||
# Update the session channel cache
|
||||
|
||||
@@ -186,6 +186,17 @@ def mk_print(fp: io.StringIO) -> Callable[..., None]:
|
||||
return _print
|
||||
|
||||
|
||||
def mk_status_printer(bot, printer):
|
||||
async def _status(details=False):
|
||||
if details:
|
||||
status = await bot.system_monitor.get_overview()
|
||||
else:
|
||||
status = await bot.system_monitor.get_summary()
|
||||
printer(status)
|
||||
return status
|
||||
return _status
|
||||
|
||||
|
||||
@log_wrap(action="Code Exec")
|
||||
async def _async(to_eval: str, style='exec'):
|
||||
newline = '\n' * ('\n' in to_eval)
|
||||
@@ -202,6 +213,7 @@ async def _async(to_eval: str, style='exec'):
|
||||
scope['ctx'] = ctx = context.get()
|
||||
scope['bot'] = ctx_bot.get()
|
||||
scope['print'] = _print # type: ignore
|
||||
scope['print_status'] = mk_status_printer(scope['bot'], _print)
|
||||
|
||||
try:
|
||||
if ctx and ctx.message:
|
||||
@@ -297,7 +309,7 @@ class Exec(LionCog):
|
||||
file = discord.File(fp, filename=f"output-{target}.md")
|
||||
await ctx.reply(file=file)
|
||||
elif result:
|
||||
await ctx.reply(f"```md{result}```")
|
||||
await ctx.reply(f"```md\n{result}```")
|
||||
else:
|
||||
await ctx.reply("Command completed, and had no output.")
|
||||
else:
|
||||
@@ -351,7 +363,7 @@ class Exec(LionCog):
|
||||
except asyncio.TimeoutError:
|
||||
return
|
||||
if ctx.interaction:
|
||||
await ctx.interaction.response.defer(thinking=True, ephemeral=True)
|
||||
await ctx.interaction.response.defer(thinking=True)
|
||||
if target is not None:
|
||||
if target not in shard_talk.peers:
|
||||
embed = discord.Embed(description=f"Unknown peer {target}", colour=discord.Colour.red())
|
||||
@@ -376,7 +388,7 @@ class Exec(LionCog):
|
||||
await ctx.reply(file=file)
|
||||
else:
|
||||
# Send as message
|
||||
await ctx.reply(f"```md\n{output}```", ephemeral=True)
|
||||
await ctx.reply(f"```md\n{output}```")
|
||||
|
||||
asyncall_cmd.autocomplete('target')(_peer_acmpl)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user