エンジニア

なんくるないさ

「このブログはアフィリエイト広告を利用しています」

Sentry無料プランでDjangoのエラーをSlackに通知する

背景: Sentryを使ってDjangoのエラーを無料でSlack通知したい

関わっている案件において、Heroku上で動いているDjangoサーバにSentryを導入して、Slackにエラー通知をしていました

今まで何事もなく動いていたSentryのSlack通知が、このようになりました。

トライアル期間までの時間

Uh oh. Sentry is going to stop Slacking you soon. Your plan doesn't support the Slack integration, all Slack alerts will stop after 6月29日 09:59.

意訳「君のプランじゃSlack統合サポートしないよ。 6月29日 09:59以降はSlack通知しないからね。」

そして6月29日 09:59以降...

Sentyのサポート期間切れ

Your Slack integration has been disabled. Your Sentry organization 〇〇 is on the Developer Plan. Upgrade to our Team or Business Plan to re-enable this integration.

意訳「Developer PlanだからSlack統合使えないよ。TeamかBusinessプランにしてくれよ」

私「仕方ねえな。お値段見てみるか」

SentryのTeam・Businessプラン料金

私「...高いな」

私「無料プランで通知させる方法調べるかー」

クラスメソッド「Sentry無料プランでSlackにエラー通知する方法!!!」

私「どれどれ...」

クラスメソッド「AWS APIGateway+LambdaでSentryからの通知を受け、そこからSlackに通知する方法を紹介します。」

私「んーAWSとか使わずにDjangoだけで済ませたいけど、googleで見つけられない....」

私「しゃーない。私がやるか」

この記事は、Sentry無料プランでDjangoのエラーをSlackに通知するための記事です。

作成したSlack通知

構成図

必要な設定

以下3つの設定が必要です。

  • Slackの設定
  • Djangoの設定
  • Sentryの設定

順番に書いていきます。

Slackの設定: Incoming Webhookの追加

通知したいチャンネルを選択します。

Incoming Webhookの追加方法

APP>"アプリを追加する"を選択し、Incoming Webhookを追加します。

画像のようにIncoming Webhookの設定をします。

Incoming Webhookの設定

このWebhook URLは後のDjangoの設定に必要になります。

Djangoの設定

以下の作業を実施します。2を詳しく書きます。

  1. DjangoにSentryを追加する
  2. Djangoにエラー情報を受け取るエンドポイントを生やし、SlackにPOSTする

1はSentryの公式を見てください。

2は、以下の画像部分です。

Djangoにエラー情報を受け取るエンドポイントを生やし、SlackにPOSTする

urls.pyに以下の新しいAPIエンドポイント作成コードを記述します。

    url(r"^error", views.ErrorView.as_view()),

ErrorViewは以下のようにしました。

class ErrorView(APIView):
        """
        sentryからエラー情報をpostしてもらい、slackにpostする
        """
    def post(self, request):
        sentry_body = request.data
        message = sentry_body["message"]
        url = sentry_body["url"]
        slack_post({"text": f"{message} \n\n {url} "})
        requests.post(WEBHOOK_URL, headers={"content-type": "application/json"}, data=json.dumps(data))
        return Response(sentry_body, status=status.HTTP_200_OK)
    )

WEBHOOK_URLには、Slackの設定のWebhook URLを指定します(環境変数等で)

参考までに、sentryからのAPIリクエストの中身を残します。

{
    "id": "***",
    "project": "***",
    "project_name": "***",
    "project_slug": "***",
    "logger": "None",
    "level": "error",
    "culprit": "django.db.models.query in __getitem__",
    "message": "",
    "url": "https: ***",
    "triggering_rules": [
        "Webhooks経由でのエラー通知",
    ],
    "event": {
        "event_id": "***",
        "level": "error",
        "version": "7",
        "type": "error",
        "fingerprint": [
            "{{ default }}"
        ],
        "culprit": "django.db.models.query in __getitem__",
        "logger": "",
        "modules": {
            "aiohttp": "3.8.1",
            "aiosignal": "1.2.0",
...
}

Sentryの設定

Sentry無料プランでSlackにエラー通知する方法の”Sentryの設定手順”を参照してください。

特にCallbackのURLの指定と、アラートの設定が重要です。

このCallback URLsには、DjangoAPIエンドポイント({DjagnoサーバのBASE_URL}/error)を記述します。

Alert設定は、Send a notification via Webhooksを設定してください。これを忘れると、SentryからDjangoにPOSTされません。

ちなみに、サーバにAPIがない場合は以下のエラーになります。

サーバにAPIが準備されていない場合のエラー

まとめ

上記の対応をすることで、Sentry無料プランでDjangoのエラーをSlackに通知できるようになりました。

ただし上記の実装だと、Sentryからの検証はできていません。

それを検証するコードの実装は、またの機会にさせてください。