diff --git a/bot.py b/bot.py index 271c16b..c32d404 100755 --- a/bot.py +++ b/bot.py @@ -1,7 +1,7 @@ import datetime import logging import sys -from collections import deque +from collections import deque, Counter import aiohttp import asyncpg @@ -47,6 +47,9 @@ class TuxBot(commands.AutoShardedBot): name=Texts().get('Starting...')) ) + self.socket_stats = Counter() + self.command_stats = Counter() + self.uptime: datetime = datetime.datetime.utcnow() self.config = config self.db = db diff --git a/cogs/logs.py b/cogs/logs.py index fb8c24d..07b48dd 100644 --- a/cogs/logs.py +++ b/cogs/logs.py @@ -1,12 +1,20 @@ +""" + +Based on https://github.com/Rapptz/RoboDanny/blob/3d94e89ef27f702a5f57f432a9131bdfb60bb3ec/cogs/stats.py +Rewrite by Romain J. + +""" + import asyncio import datetime import json import logging import textwrap import traceback -from collections import defaultdict, Counter +from collections import defaultdict import discord +import humanize import psutil from discord.ext import commands, tasks @@ -67,6 +75,7 @@ class Logs(commands.Cog): return command = ctx.command.qualified_name + self.bot.command_stats[command] += 1 message = ctx.message if ctx.guild is None: destination = 'Private Message' @@ -215,8 +224,38 @@ class Logs(commands.Cog): msg = f'{emoji} `[{dt:%Y-%m-%d %H:%M:%S}] {record.message}`' await self.webhook.send(msg) + @commands.command(name='commandstats', hidden=True) + @commands.is_owner() + async def _commandstats(self, ctx, limit=20): + counter = self.bot.command_stats + width = len(max(counter, key=len)) -async def on_error(self, event, *args, **kwargs): + if limit > 0: + common = counter.most_common(limit) + else: + common = counter.most_common()[limit:] + + output = '\n'.join(f'{k:<{width}}: {c}' for k, c in common) + + await ctx.send(f'```\n{output}\n```') + + @commands.command(name='socketstats', hidden=True) + @commands.is_owner() + async def _socketstats(self, ctx): + delta = datetime.datetime.utcnow() - self.bot.uptime + minutes = delta.total_seconds() / 60 + total = sum(self.bot.socket_stats.values()) + cpm = total / minutes + await ctx.send(f'{total} socket events observed ({cpm:.2f}/minute):\n{self.bot.socket_stats}') + + @commands.command(name='uptime') + async def _uptime(self, ctx): + """Tells you how long the bot has been up for.""" + uptime = humanize.naturaltime(datetime.datetime.utcnow() - self.bot.uptime) + await ctx.send(f'Uptime: **{uptime}**') + + +async def on_error(self, event, *args): e = discord.Embed(title='Event Error', colour=0xa32952) e.add_field(name='Event', value=event) e.description = f'```py\n{traceback.format_exc()}\n```' @@ -237,11 +276,9 @@ async def on_error(self, event, *args, **kwargs): def setup(bot: TuxBot): - if not hasattr(bot, 'socket_stats'): - bot.socket_stats = Counter() - cog = Logs(bot) bot.add_cog(cog) + handler = GatewayHandler(cog) logging.getLogger().addHandler(handler) commands.AutoShardedBot.on_error = on_error diff --git a/cogs/utils/cli_colors.py b/cogs/utils/cli_colors.py deleted file mode 100755 index 2dd3466..0000000 --- a/cogs/utils/cli_colors.py +++ /dev/null @@ -1,46 +0,0 @@ -class text_colors: - BLACK = '\033[30m' - RED = '\033[31m' - GREEN = '\033[32m' - YELLOW = '\033[33m' - BLUE = '\033[34m' - MAGENTA = '\033[35m' - CYAN = '\033[36m' - LIGHT_GRAY = '\033[37m' - DARK_GRAY = '\033[90m' - LIGHT_RED = '\033[91m' - LIGHT_GREEN = '\033[92m' - LIGHT_YELLOW = '\033[93m' - LIGHT_BLUE = '\033[94m' - LIGHT_MAGENTA = '\033[95m' - LIGHT_CYAN = '\033[96m' - WHITE = '\033[97m' - - -class bg_colors: - BLACK = '\033[40m' - RED = '\033[41m' - GREEN = '\033[42m' - YELLOW = '\033[43m' - BLUE = '\033[44m' - MAGENTA = '\033[45m' - CYAN = '\033[46m' - LIGHT_GRAY = '\033[47m' - DARK_GRAY = '\033[100m' - LIGHT_RED = '\033[101m' - LIGHT_GREEN = '\033[102m' - LIGHT_YELLOW = '\033[103m' - LIGHT_BLUE = '\033[104m' - LIGHT_MAGENTA = '\033[105m' - LIGHT_CYAN = '\033[106m' - WHITE = '\033[107m' - - -class text_style: - BOLD = '\033[1m' - DIM = '\033[2m' - UNDERLINE = '\033[4m' - BLINK = '\033[5m' - - -ENDC = '\033[0m'