diff options
| author | 2020-04-11 22:11:43 +0100 | |
|---|---|---|
| committer | 2020-04-11 22:11:43 +0100 | |
| commit | ee5a4df9537b46cdceb35243d887e84601d07795 (patch) | |
| tree | 0a513a8030f2e6b21e1c876635bec3a76aa9b8ee | |
| parent | Merge branch 'master' into stats (diff) | |
Additional statistics
Diffstat (limited to '')
| -rw-r--r-- | bot/cogs/defcon.py | 2 | ||||
| -rw-r--r-- | bot/cogs/error_handler.py | 14 | ||||
| -rw-r--r-- | bot/cogs/help_channels.py | 24 | ||||
| -rw-r--r-- | bot/cogs/stats.py | 14 | 
4 files changed, 45 insertions, 9 deletions
diff --git a/bot/cogs/defcon.py b/bot/cogs/defcon.py index 06b2f25c6..9197dcca3 100644 --- a/bot/cogs/defcon.py +++ b/bot/cogs/defcon.py @@ -146,6 +146,8 @@ class Defcon(Cog):              await ctx.send(self.build_defcon_msg(action, error))              await self.send_defcon_log(action, ctx.author, error) +            self.bot.stats.gauge("defcon.days", days) +      @defcon_group.command(name='enable', aliases=('on', 'e'))      @with_role(Roles.admins, Roles.owners)      async def enable_command(self, ctx: Context) -> None: diff --git a/bot/cogs/error_handler.py b/bot/cogs/error_handler.py index 722376cc6..dae283c6a 100644 --- a/bot/cogs/error_handler.py +++ b/bot/cogs/error_handler.py @@ -171,19 +171,25 @@ class ErrorHandler(Cog):          if isinstance(e, errors.MissingRequiredArgument):              await ctx.send(f"Missing required argument `{e.param.name}`.")              await ctx.invoke(*help_command) +            self.bot.stats.incr("errors.missing_required_argument")          elif isinstance(e, errors.TooManyArguments):              await ctx.send(f"Too many arguments provided.")              await ctx.invoke(*help_command) +            self.bot.stats.incr("errors.too_many_arguments")          elif isinstance(e, errors.BadArgument):              await ctx.send(f"Bad argument: {e}\n")              await ctx.invoke(*help_command) +            self.bot.stats.incr("errors.bad_argument")          elif isinstance(e, errors.BadUnionArgument):              await ctx.send(f"Bad argument: {e}\n```{e.errors[-1]}```") +            self.bot.stats.incr("errors.bad_union_argument")          elif isinstance(e, errors.ArgumentParsingError):              await ctx.send(f"Argument parsing error: {e}") +            self.bot.stats.incr("errors.argument_parsing_error")          else:              await ctx.send("Something about your input seems off. Check the arguments:")              await ctx.invoke(*help_command) +            self.bot.stats.incr("errors.other_user_input_error")      @staticmethod      async def handle_check_failure(ctx: Context, e: errors.CheckFailure) -> None: @@ -205,10 +211,12 @@ class ErrorHandler(Cog):          )          if isinstance(e, bot_missing_errors): +            ctx.bot.stats.incr("errors.bot_permission_error")              await ctx.send(                  f"Sorry, it looks like I don't have the permissions or roles I need to do that."              )          elif isinstance(e, (InChannelCheckFailure, errors.NoPrivateMessage)): +            ctx.bot.stats.incr("errors.wrong_channel_or_dm_error")              await ctx.send(e)      @staticmethod @@ -217,16 +225,20 @@ class ErrorHandler(Cog):          if e.status == 404:              await ctx.send("There does not seem to be anything matching your query.")              log.debug(f"API responded with 404 for command {ctx.command}") +            ctx.bot.stats.incr("errors.api_error_404")          elif e.status == 400:              content = await e.response.json()              log.debug(f"API responded with 400 for command {ctx.command}: %r.", content)              await ctx.send("According to the API, your request is malformed.") +            ctx.bot.stats.incr("errors.api_error_400")          elif 500 <= e.status < 600:              await ctx.send("Sorry, there seems to be an internal issue with the API.")              log.warning(f"API responded with {e.status} for command {ctx.command}") +            ctx.bot.stats.incr("errors.api_internal_server_error")          else:              await ctx.send(f"Got an unexpected status code from the API (`{e.status}`).")              log.warning(f"Unexpected API response for command {ctx.command}: {e.status}") +            ctx.bot.stats.incr(f"errors.api_error_{e.status}")      @staticmethod      async def handle_unexpected_error(ctx: Context, e: errors.CommandError) -> None: @@ -236,7 +248,7 @@ class ErrorHandler(Cog):              f"```{e.__class__.__name__}: {e}```"          ) -        ctx.bot.stats.incr("errors.commands") +        ctx.bot.stats.incr("errors.unexpected")          with push_scope() as scope:              scope.user = { diff --git a/bot/cogs/help_channels.py b/bot/cogs/help_channels.py index 389a4ad2a..01a77db2b 100644 --- a/bot/cogs/help_channels.py +++ b/bot/cogs/help_channels.py @@ -127,6 +127,9 @@ class HelpChannels(Scheduler, commands.Cog):          self.on_message_lock = asyncio.Lock()          self.init_task = self.bot.loop.create_task(self.init_cog()) +        # Stats +        self.claim_times = {} +      def cog_unload(self) -> None:          """Cancel the init task and scheduled tasks when the cog unloads."""          log.trace("Cog unload: cancelling the init_cog task") @@ -195,7 +198,7 @@ class HelpChannels(Scheduler, commands.Cog):          if ctx.channel.category == self.in_use_category:              self.cancel_task(ctx.channel.id) -            await self.move_to_dormant(ctx.channel) +            await self.move_to_dormant(ctx.channel, "command")          else:              log.debug(f"{ctx.author} invoked command 'dormant' outside an in-use help channel") @@ -406,7 +409,7 @@ class HelpChannels(Scheduler, commands.Cog):                  f"and will be made dormant."              ) -            await self.move_to_dormant(channel) +            await self.move_to_dormant(channel, "auto")          else:              # Cancel the existing task, if any.              if has_task: @@ -446,8 +449,12 @@ class HelpChannels(Scheduler, commands.Cog):          await self.ensure_permissions_synchronization(self.available_category)          self.report_stats() -    async def move_to_dormant(self, channel: discord.TextChannel) -> None: -        """Make the `channel` dormant.""" +    async def move_to_dormant(self, channel: discord.TextChannel, caller: str) -> None: +        """ +        Make the `channel` dormant. + +        A caller argument is provided for metrics. +        """          log.info(f"Moving #{channel} ({channel.id}) to the Dormant category.")          await channel.edit( @@ -457,6 +464,13 @@ class HelpChannels(Scheduler, commands.Cog):              topic=DORMANT_TOPIC,          ) +        self.bot.stats.incr(f"help.dormant_calls.{caller}") + +        if self.claim_times.get(channel.id): +            claimed = self.claim_times[channel.id] +            in_use_time = datetime.now() - claimed +            self.bot.stats.timer("help.in_use_time", in_use_time) +          log.trace(f"Position of #{channel} ({channel.id}) is actually {channel.position}.")          log.trace(f"Sending dormant message for #{channel} ({channel.id}).") @@ -560,6 +574,8 @@ class HelpChannels(Scheduler, commands.Cog):              self.bot.stats.incr("help.claimed") +            self.claim_times[channel.id] = datetime.now() +              log.trace(f"Releasing on_message lock for {message.id}.")          # Move a dormant channel to the Available category to fill in the gap. diff --git a/bot/cogs/stats.py b/bot/cogs/stats.py index 8fb7d8639..772ae2c97 100644 --- a/bot/cogs/stats.py +++ b/bot/cogs/stats.py @@ -1,3 +1,5 @@ +import string +  from discord import Member, Message, Status  from discord.ext.commands import Bot, Cog, Context @@ -11,6 +13,8 @@ CHANNEL_NAME_OVERRIDES = {      Channels.staff_lounge: "staff_lounge"  } +ALLOWED_CHARS = string.ascii_letters + string.digits +  class Stats(Cog):      """A cog which provides a way to hook onto Discord events and forward to stats.""" @@ -32,6 +36,8 @@ class Stats(Cog):          if CHANNEL_NAME_OVERRIDES.get(message.channel.id):              reformatted_name = CHANNEL_NAME_OVERRIDES.get(message.channel.id) +        reformatted_name = "".join([char for char in reformatted_name if char in ALLOWED_CHARS]) +          stat_name = f"channels.{reformatted_name}"          self.bot.stats.incr(stat_name) @@ -73,13 +79,13 @@ class Stats(Cog):          offline = 0          for member in after.guild.members: -            if member.status == Status.online: +            if member.status is Status.online:                  online += 1 -            elif member.status == Status.dnd: +            elif member.status is Status.dnd:                  dnd += 1 -            elif member.status == Status.idle: +            elif member.status is Status.idle:                  idle += 1 -            else: +            elif member.status is Status.offline:                  offline += 1          self.bot.stats.gauge("guild.status.online", online)  |