LoginSignup
1
1

More than 1 year has passed since last update.

【discord.py】Sentryを使ってエラー監視する

Last updated at Posted at 2021-07-01

はじめに

discord botやその他アプリケーションを運用する際、エラーを一元管理するためにSentryを導入しました。

その際にdiscord botで行った手順を紹介します。

Sentryとは

Sentry とは、エラーを検知、監視できるサービスです。
複数アプリケーションのエラーを一元管理できます。

エラー監視方法

プロジェクトの作成

Create a new Project

Choose a platform: 「PYTHON」を選択します。

Set your default alert settings:デフォルトの「I'll create my own alerts later」を選択します。

プロジェクトに名前を付けてください:プロジェクト名を設定します。

Sentry用環境変数の設定

プロジェクトの作成完了後、使い方が表示されます。

Configure Python

この使い方に従えばSentryでエラー監視できます。
ただし、 sentry_sdk.init の最初の引数、DSNはハードコーディングを避け、環境変数として設定しましょう。

DSNとはData Source Nameの略で、エラーなどイベントの送信先です。Sentryのプロジェクトごとに作成されます。
DSNが外部に流出すると、あなたのプロジェクトに第三者がイベントを送信する可能性があります。
そのため環境変数としてDSNを設定しましょう。

今回は .env を使って環境変数を設定します。

  1. .env を扱うためのパッケージをインストール

    PipenvやPoetryなどパッケージ管理ツールを使う場合は適宜読み替えてください。

    pip install python-dotenv
    
  2. .env ファイルを作成

    .env
    SENTRY_DSN="https://xxxxxxxxxxxx"
    SENTRY_ENVIRONMENT="development"
    

    SENTRY_DSN の値にDSNを設定します。未設定の場合、Sentryへイベント送信を行いません。

    SENTRY_ENVIRONMENT ではproduction、developmentなどの環境を表す文字列を設定できます。

    Sentryでは他にも環境変数を設定できます。詳細は、公式ドキュメント を参照ください。

例外のキャプチャ

Sentryはデフォルトでは、キャッチされない例外、ログレベルERROR以上のログをイベントとして送信します。
discord.pyはBotが停止しないよう、デフォルトでエラーをハンドリングしていて、そのままではイベントが送信されません。

コマンドは on_command_error 、タスクは tasks.Loop.error 内で capture_exception を使ってエラーをキャプチャする必要があります。

import os

import sentry_sdk
from discord.ext import commands, tasks
from dotenv import load_dotenv
from sentry_sdk import capture_exception


class MyBot(commands.Bot):
    async def on_ready(self):
        print(f"Ready: {self.user}")
        self.add_cog(MyCog(self))

    async def on_command_error(self, context: commands.Context, exception: Exception):
        capture_exception(exception)
        return await super().on_command_error(context, exception)


class MyCog(commands.Cog):
    def __init__(self, bot: commands.Bot):
        self.bot = bot
        self.do_task.start()

    @commands.command()
    async def ping(self, ctx: commands.Context):
        await ctx.send("pong")

    @tasks.loop(minutes=1)
    async def do_task(self):
        1 / 0

    @do_task.error
    async def task_error(self, exception: Exception):
        capture_exception(exception)


def main():
    load_dotenv()
    sentry_sdk.init(traces_sample_rate=1.0)

    token = os.environ["DISCORD_BOT_TOKEN"]
    bot = MyBot(command_prefix="/")
    bot.run(token)


if __name__ == "__main__":
    main()

注:コード例では環境変数 DISCORD_BOT_TOKEN にdiscord botのtokenを設定しています。

存在しないコマンドを入力したり、時間経過でタスクが実行されると、画像のようにIssueへエラーが追加されていきます。

Issues

Discord/Slackとの連携

このままではエラーが発生しても通知が来ず不便です。
DiscordやSlackと連携して、エラーの通知が来るようにしましょう。

現在、Slack integrationは有料プランのみになっていますが、Slack(Legacy)のURLに直接アクセスすれば無料プランでも設定可能なようです。

以下の記事を参考にして、設定することができました。

Webhook URLを変更すれば、Slackも通知可能です。

参考URL

Python | Sentry Documentation

エラー監視には Sentry が超便利! - Qiita

Sentryのエラー通知をDiscordに送信する - #えむけーろぐ

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1