aboutsummaryrefslogtreecommitdiffstats
path: root/bot/cogs/stats.py
blob: b75d29b7e79bfcdb4578437a779de80a5b009b5d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from discord import Member, Message, Status
from discord.ext.commands import Bot, Cog, Context


class Stats(Cog):
    """A cog which provides a way to hook onto Discord events and forward to stats."""

    def __init__(self, bot: Bot):
        self.bot = bot

    @Cog.listener()
    async def on_message(self, message: Message) -> None:
        """Report message events in the server to statsd."""
        if message.guild is None:
            return

        reformatted_name = message.channel.name.replace('-', '_')

        if reformatted_name.startswith("ot"):
            # Off-topic channels change names, we don't want this for stats.
            # This will change 'ot1-lemon-in-the-dishwasher' to just 'ot1'
            reformatted_name = reformatted_name[:3]

        stat_name = f"channels.{reformatted_name}"
        self.bot.stats.incr(stat_name)

        # Increment the total message count
        self.bot.stats.incr("messages")

    @Cog.listener()
    async def on_command_completion(self, ctx: Context) -> None:
        """Report completed commands to statsd."""
        command_name = ctx.command.qualified_name.replace(" ", "_")

        self.bot.stats.incr(f"commands.{command_name}")

    @Cog.listener()
    async def on_member_join(self, member: Member) -> None:
        """Update member count stat on member join."""
        self.bot.stats.gauge(f"guild.total_members", len(member.guild.members))

    @Cog.listener()
    async def on_member_leave(self, member: Member) -> None:
        """Update member count stat on member leave."""
        self.bot.stats.gauge(f"guild.total_members", len(member.guild.members))

    @Cog.listener()
    async def on_member_update(self, _before: Member, after: Member) -> None:
        """Update presence estimates on member update."""
        members = after.guild.members

        online = len([m for m in members if m.status == Status.online])
        idle = len([m for m in members if m.status == Status.idle])
        dnd = len([m for m in members if m.status == Status.do_not_disturb])
        offline = len([m for m in members if m.status == Status.offline])

        self.bot.stats.gauge("guild.status.online", online)
        self.bot.stats.gauge("guild.status.idle", idle)
        self.bot.stats.gauge("guild.status.do_not_disturb", dnd)
        self.bot.stats.gauge("guild.status.offline", offline)


def setup(bot: Bot) -> None:
    """Load the stats cog."""
    bot.add_cog(Stats(bot))