aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar wookie184 <[email protected]>2024-03-26 18:13:24 +0000
committerGravatar GitHub <[email protected]>2024-03-26 18:13:24 +0000
commit726c16c3664e6520e93a524ea9d006410512fed9 (patch)
treeb0475cb680c2d8c779fe0743faf2f7710782b9f0
parentBump emoji from 2.10.1 to 2.11.0 (#2974) (diff)
parentAdd sentry performance spans to thread bumper cog (diff)
Merge pull request #2976 from python-discord/capture-cog-load-times
Capture cog load times using sentry performance tracking
-rw-r--r--bot/bot.py7
-rw-r--r--bot/exts/info/python_news.py30
-rw-r--r--bot/exts/info/subscribe.py34
-rw-r--r--bot/exts/utils/thread_bumper.py40
4 files changed, 65 insertions, 46 deletions
diff --git a/bot/bot.py b/bot/bot.py
index 84caf1873..fa3617f1b 100644
--- a/bot/bot.py
+++ b/bot/bot.py
@@ -6,7 +6,7 @@ import aiohttp
from discord.errors import Forbidden
from pydis_core import BotBase
from pydis_core.utils.error_handling import handle_forbidden_from_block
-from sentry_sdk import push_scope
+from sentry_sdk import push_scope, start_transaction
from bot import constants, exts
from bot.log import get_logger
@@ -29,6 +29,11 @@ class Bot(BotBase):
super().__init__(*args, **kwargs)
+ async def load_extension(self, name: str, *args, **kwargs) -> None:
+ """Extend D.py's load_extension function to also record sentry performance stats."""
+ with start_transaction(op="cog-load", name=name):
+ await super().load_extension(name, *args, **kwargs)
+
async def ping_services(self) -> None:
"""A helper to make sure all the services the bot relies on are available on startup."""
# Connect Site/API
diff --git a/bot/exts/info/python_news.py b/bot/exts/info/python_news.py
index e06c82bb8..c786a9d19 100644
--- a/bot/exts/info/python_news.py
+++ b/bot/exts/info/python_news.py
@@ -4,6 +4,7 @@ from datetime import UTC, datetime, timedelta
import discord
import feedparser
+import sentry_sdk
from bs4 import BeautifulSoup
from discord.ext.commands import Cog
from discord.ext.tasks import loop
@@ -43,6 +44,22 @@ class PythonNews(Cog):
self.webhook: discord.Webhook | None = None
self.seen_items: dict[str, set[str]] = {}
+ async def cog_load(self) -> None:
+ """Load all existing seen items from db and create any missing mailing lists."""
+ with sentry_sdk.start_span(description="Fetch mailing lists from site"):
+ response = await self.bot.api_client.get("bot/mailing-lists")
+
+ for mailing_list in response:
+ self.seen_items[mailing_list["name"]] = set(mailing_list["seen_items"])
+
+ with sentry_sdk.start_span(description="Update site with new mailing lists"):
+ for mailing_list in ("pep", *constants.PythonNews.mail_lists):
+ if mailing_list not in self.seen_items:
+ await self.bot.api_client.post("bot/mailing-lists", json={"name": mailing_list})
+ self.seen_items[mailing_list] = set()
+
+ self.fetch_new_media.start()
+
async def cog_unload(self) -> None:
"""Stop news posting tasks on cog unload."""
self.fetch_new_media.cancel()
@@ -225,19 +242,6 @@ class PythonNews(Cog):
email_information = await resp.json()
return thread_information, email_information
- async def cog_load(self) -> None:
- """Load all existing seen items from db and create any missing mailing lists."""
- response = await self.bot.api_client.get("bot/mailing-lists")
- for mailing_list in response:
- self.seen_items[mailing_list["name"]] = set(mailing_list["seen_items"])
-
- for mailing_list in ("pep", *constants.PythonNews.mail_lists):
- if mailing_list not in self.seen_items:
- await self.bot.api_client.post("bot/mailing-lists", json={"name": mailing_list})
- self.seen_items[mailing_list] = set()
-
- self.fetch_new_media.start()
-
async def setup(bot: Bot) -> None:
"""Add `News` cog."""
diff --git a/bot/exts/info/subscribe.py b/bot/exts/info/subscribe.py
index 048884587..5e33474bf 100644
--- a/bot/exts/info/subscribe.py
+++ b/bot/exts/info/subscribe.py
@@ -2,6 +2,7 @@ import operator
from dataclasses import dataclass
import discord
+import sentry_sdk
from discord.ext import commands
from discord.interactions import Interaction
from pydis_core.utils import members
@@ -157,24 +158,27 @@ class Subscribe(commands.Cog):
await self.bot.wait_until_guild_available()
self.guild = self.bot.get_guild(constants.Guild.id)
- for role in ASSIGNABLE_ROLES:
- discord_role = self.guild.get_role(role.role_id)
- if discord_role is None:
- log.warning("Could not resolve %d to a role in the guild, skipping.", role.role_id)
- continue
- self.assignable_roles.append(
- AssignableRole(
- role_id=role.role_id,
- name=discord_role.name,
+ with sentry_sdk.start_span(description="Prepare assignable roles"):
+ for role in ASSIGNABLE_ROLES:
+ discord_role = self.guild.get_role(role.role_id)
+ if discord_role is None:
+ log.warning("Could not resolve %d to a role in the guild, skipping.", role.role_id)
+ continue
+ self.assignable_roles.append(
+ AssignableRole(
+ role_id=role.role_id,
+ name=discord_role.name,
+ )
)
- )
+ # Sort by role name
+ self.assignable_roles.sort(key=operator.attrgetter("name"))
- # Sort by role name
- self.assignable_roles.sort(key=operator.attrgetter("name"))
+ with sentry_sdk.start_span(description="Fetch/create the self assignable roles message"):
+ placeholder_message_view_tuple = await self._fetch_or_create_self_assignable_roles_message()
+ self_assignable_roles_message, self_assignable_roles_view = placeholder_message_view_tuple
- placeholder_message_view_tuple = await self._fetch_or_create_self_assignable_roles_message()
- self_assignable_roles_message, self_assignable_roles_view = placeholder_message_view_tuple
- self._attach_persistent_roles_view(self_assignable_roles_message, self_assignable_roles_view)
+ with sentry_sdk.start_span(description="Attach self assignable role persistent view"):
+ self._attach_persistent_roles_view(self_assignable_roles_message, self_assignable_roles_view)
@commands.cooldown(1, 10, commands.BucketType.member)
@commands.command(name="subscribe", aliases=("unsubscribe",))
diff --git a/bot/exts/utils/thread_bumper.py b/bot/exts/utils/thread_bumper.py
index e93301e0c..588ea1274 100644
--- a/bot/exts/utils/thread_bumper.py
+++ b/bot/exts/utils/thread_bumper.py
@@ -1,5 +1,6 @@
import discord
+import sentry_sdk
from discord.ext import commands
from pydis_core.site_api import ResponseCodeError
from pydis_core.utils.channel import get_or_fetch_channel
@@ -67,23 +68,28 @@ class ThreadBumper(commands.Cog):
await self.bot.wait_until_guild_available()
threads_to_maybe_bump = []
- for thread_id in await self.bot.api_client.get(THREAD_BUMP_ENDPOINT):
- try:
- thread = await get_or_fetch_channel(self.bot, thread_id)
- except discord.NotFound:
- log.info("Thread %d has been deleted, removing from bumped threads.", thread_id)
- await self.bot.api_client.delete(f"{THREAD_BUMP_ENDPOINT}/{thread_id}")
- continue
-
- if not isinstance(thread, discord.Thread):
- await self.bot.api_client.delete(f"{THREAD_BUMP_ENDPOINT}/{thread_id}")
- continue
-
- if thread.archived:
- threads_to_maybe_bump.append(thread)
-
- if threads_to_maybe_bump:
- await self.unarchive_threads_not_manually_archived(threads_to_maybe_bump)
+ with sentry_sdk.start_span(description="Fetch threads to bump from site"):
+ bumped_threads_from_site = await self.bot.api_client.get(THREAD_BUMP_ENDPOINT)
+
+ with sentry_sdk.start_span(description="Sync bumped threads in site with current guild state"):
+ for thread_id in bumped_threads_from_site:
+ try:
+ thread = await get_or_fetch_channel(self.bot, thread_id)
+ except discord.NotFound:
+ log.info("Thread %d has been deleted, removing from bumped threads.", thread_id)
+ await self.bot.api_client.delete(f"{THREAD_BUMP_ENDPOINT}/{thread_id}")
+ continue
+
+ if not isinstance(thread, discord.Thread):
+ await self.bot.api_client.delete(f"{THREAD_BUMP_ENDPOINT}/{thread_id}")
+ continue
+
+ if thread.archived:
+ threads_to_maybe_bump.append(thread)
+
+ with sentry_sdk.start_span(description="Unarchive threads that should be bumped"):
+ if threads_to_maybe_bump:
+ await self.unarchive_threads_not_manually_archived(threads_to_maybe_bump)
@commands.group(name="bump")
async def thread_bump_group(self, ctx: commands.Context) -> None: