tux.handlers.sentry
¶
Classes:
Name | Description |
---|---|
SentryHandler | Handles Sentry transaction tracking for commands and interactions. |
Functions:
Name | Description |
---|---|
setup | Add the SentryHandler cog to the bot. |
Classes¶
SentryHandler(bot: Tux)
¶
Bases: Cog
Handles Sentry transaction tracking for commands and interactions.
This cog listens for Discord events to create and complete Sentry transactions, providing performance monitoring and error context for both prefix commands and slash commands.
Initialize the Sentry handler cog.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
bot | Tux | The bot instance to attach the listeners to | required |
Methods:
Name | Description |
---|---|
on_command | Start a Sentry transaction for a prefix command. |
on_command_completion | Finish the Sentry transaction for a completed prefix command. |
on_interaction | Start a Sentry transaction for application command interactions. |
on_app_command_completion | Finish the Sentry transaction for a completed application command. |
Source code in tux/handlers/sentry.py
Functions¶
_is_sentry_available() -> bool
¶
Check if Sentry is initialized and available for use.
Returns:
Type | Description |
---|---|
bool | True if Sentry is initialized, False otherwise |
_create_transaction(operation: str, name: str, description: str, tags: dict[str, Any]) -> Any | None
¶
Create a Sentry transaction with the given parameters.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
operation | str | The operation type (e.g., "discord.command") | required |
name | str | The name of the transaction | required |
description | str | A description of the transaction | required |
tags | dict[str, Any] | Tags to attach to the transaction | required |
Returns:
Type | Description |
---|---|
Optional[Any] | The created transaction or None if Sentry is not initialized |
Source code in tux/handlers/sentry.py
def _create_transaction(
self,
operation: str,
name: str,
description: str,
tags: dict[str, Any],
) -> Any | None:
"""Create a Sentry transaction with the given parameters.
Parameters
----------
operation : str
The operation type (e.g., "discord.command")
name : str
The name of the transaction
description : str
A description of the transaction
tags : dict[str, Any]
Tags to attach to the transaction
Returns
-------
Optional[Any]
The created transaction or None if Sentry is not initialized
"""
if not self._is_sentry_available():
return None
try:
transaction = sentry_sdk.start_transaction(op=operation, name=name, description=description)
# Add all tags to the transaction
for key, value in tags.items():
transaction.set_tag(key, value)
except Exception as e:
logger.error(f"Error creating Sentry transaction: {e}")
sentry_sdk.capture_exception(e)
return None
else:
return transaction
_finish_transaction(object_id: int, status: str = STATUS['OK']) -> None
¶
Finish a stored transaction with the given status.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
object_id | int | The ID of the interaction or message | required |
status | str | The status to set on the transaction | STATUS['OK'] |
Source code in tux/handlers/sentry.py
def _finish_transaction(self, object_id: int, status: str = STATUS["OK"]) -> None:
"""Finish a stored transaction with the given status.
Parameters
----------
object_id : int
The ID of the interaction or message
status : str
The status to set on the transaction
"""
if not self._is_sentry_available():
return
if transaction := self.bot.active_sentry_transactions.pop(object_id, None):
transaction.set_status(status)
transaction.finish()
logger.trace(f"Finished Sentry transaction ({status}) for {transaction.name}")
on_command(ctx: commands.Context[Tux]) -> None
async
¶
Start a Sentry transaction for a prefix command.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
ctx | Context[Tux] | The command context | required |
Source code in tux/handlers/sentry.py
@commands.Cog.listener()
async def on_command(self, ctx: commands.Context[Tux]) -> None:
"""
Start a Sentry transaction for a prefix command.
Parameters
----------
ctx : commands.Context[Tux]
The command context
"""
if not self._is_sentry_available():
return
if command_name := (ctx.command.qualified_name if ctx.command else "Unknown Command"):
tags = {
"discord.command.name": command_name,
"discord.guild.id": str(ctx.guild.id) if ctx.guild else "DM",
"discord.channel.id": ctx.channel.id,
"discord.user.id": ctx.author.id,
"discord.message.id": ctx.message.id,
"discord.command.type": "prefix",
}
if transaction := self._create_transaction(
operation="discord.command",
name=command_name,
description=ctx.message.content,
tags=tags,
):
self.bot.active_sentry_transactions[ctx.message.id] = transaction
logger.trace(f"Started transaction for prefix command: {command_name}")
on_command_completion(ctx: commands.Context[Tux]) -> None
async
¶
Finish the Sentry transaction for a completed prefix command.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
ctx | Context[Tux] | The command context | required |
Source code in tux/handlers/sentry.py
@commands.Cog.listener()
async def on_command_completion(self, ctx: commands.Context[Tux]) -> None:
"""
Finish the Sentry transaction for a completed prefix command.
Parameters
----------
ctx : commands.Context[Tux]
The command context
"""
self._finish_transaction(ctx.message.id, self.STATUS["OK"])
on_interaction(interaction: discord.Interaction) -> None
async
¶
Start a Sentry transaction for application command interactions.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
interaction | Interaction | The interaction object | required |
Source code in tux/handlers/sentry.py
@commands.Cog.listener()
async def on_interaction(self, interaction: discord.Interaction) -> None:
"""
Start a Sentry transaction for application command interactions.
Parameters
----------
interaction : discord.Interaction
The interaction object
"""
if not self._is_sentry_available() or interaction.type != discord.InteractionType.application_command:
return
if command_name := (interaction.command.qualified_name if interaction.command else "Unknown App Command"):
tags = {
"discord.command.name": command_name,
"discord.guild.id": str(interaction.guild_id) if interaction.guild_id else "DM",
"discord.channel.id": interaction.channel_id,
"discord.user.id": interaction.user.id,
"discord.interaction.id": interaction.id,
"discord.interaction.type": interaction.type.name,
"discord.command.type": "slash",
}
if transaction := self._create_transaction(
operation="discord.app_command",
name=command_name,
description=f"/{command_name}",
tags=tags,
):
self.bot.active_sentry_transactions[interaction.id] = transaction
logger.trace(f"Started transaction for app command: {command_name}")
on_app_command_completion(interaction: discord.Interaction, command: CommandObject) -> None
async
¶
Finish the Sentry transaction for a completed application command.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
interaction | Interaction | The interaction object | required |
command | CommandObject | The command that was completed | required |
Source code in tux/handlers/sentry.py
@commands.Cog.listener()
async def on_app_command_completion(self, interaction: discord.Interaction, command: CommandObject) -> None:
"""
Finish the Sentry transaction for a completed application command.
Parameters
----------
interaction : discord.Interaction
The interaction object
command : CommandObject
The command that was completed
"""
self._finish_transaction(interaction.id, self.STATUS["OK"])