frontendのエラーをSlack通知したい
概要
frontendで起きたエラーを、Sentryを使ってSlack通知していきます。
Sentry公式が用意しているSlack IntegrationはSentryの有料プランじゃないと使えないので、
SentryのWebhook、AWS Lamba、API Gateway、SlackのIncomming Webhookを組み合わせ、無料プランで実現していきます。
経緯
frontendのエラーログ監視に「Sentry」を使用することにしました。
以下のコードをエントリーポイントに仕込めば、
import * as Sentry from '@sentry/browser'
import { Integrations } from '@sentry/tracing'
Sentry.init({
dsn: 'https://xxxx',
integrations: [new Integrations.BrowserTracing()],
tracesSampleRate: 1.0,
})
以下のように、エラーが起きたときSentryのWebUI上で確認することができます。
deviceの情報・osの情報なども自動で取得してくれるので、特にfrontendでのエラー監視に便利だと感じています。
これだけでも最高なのですが、Sentryは様々なサービスとのintegrationが可能です。
今回、Slackと連携することにより、Sentryで捕まえたエラーログをSlackに通知したいと思ったのですが、、、
SentryのTeamプランが必要でした。そしてTeamプランは有料。
諦めかけましたが、Webhookは無料プラン(Developer Plan)でも使用できるようです。
今回、Webhookを使用して、無料プランでもSlack通知できるようにしてみました。
目的
Slackに、こんな感じの通知が来るようにします。
構成
AWS Lambdaを用います。
Sentry上でログを検出したら、Sentry WebHooksからAPI Gatewayで作成したエンドポイントを叩き、Lambdaを呼び出します。
LambdaからSlackのIncomming Webhookを叩いてSlackに通知します。
手順
-
SlackのIncomming Webhookの設定
設定方法はこちら -
AWS Lambdaで関数の作成
今回はnode.jsで作成しました。
event.bodyでSentryからやってくるjsonにアクセスできます。
Sentry公式にもjson構造はのっていますが、若干実際の構造とずれているので試行錯誤して確かめました。
const { IncomingWebhook } = require('@slack/webhook') // Webhook url const url = 'https://hooks.slack.com/xxxxx' const webhook = new IncomingWebhook(url) exports.handler = async (event) => { const sentryBodyStr = event.body const sentryBody = JSON.parse(sentryBodyStr) const sentryEvent = sentryBody.event // ブラウザ情報 const browserInfo = (() => { const browser = sentryEvent.contexts.browser if (browser === undefined) return 'unknown' return `${browser.name} ${browser.type} ${browser.version}` })() // OS情報 const osInfo = (() => { const os = sentryEvent.contexts.os if (os === undefined) return 'unknown' return `${os.name} ${os.type} ${os.version}` })() // デバイス情報 const deviceInfo = (() => { const device = sentryEvent.contexts.device if (device === undefined) return 'unknown' return `${device.family}` })() // エラー名 const title = sentryEvent.title // Sentryのissue URL const url = sentryBody.url // 環境 const env = sentryEvent.environment const issue = { message: title, detail: url, browser: browserInfo, os: osInfo, device: deviceInfo } const issueProperties = Object.entries(issue).map(entry => { return `${entry[0]}: ${entry[1]}` }) const payload = { "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": `:ghost: *${env}* でエラーがおきたよ` } }, { "type": "section", "text": { "type": "mrkdwn", "text": issueProperties.join('\n') } }, ] } await webhook.send(payload) }
-
AWS API GatewayをトリガにしてAWS Lambdaが動作するよう設定する
設定方法はこちら -
SentryのWebHooksにAPI Gatewayのendpointを指定する
Setting > Integrations > WebhooksそしてAdd To Projectを選択し、
API Gatewayのendpointを設定します。
-
SentryのAlert設定で、どういう条件のときにwebhookをkickするか設定を行う
これで設定は終了です。
無事、Sentryで検出したエラーがSlackに来るようになりました。
まとめ
SentryがWebhookという汎用性の高い手段を提供してくれているので、助かりました。
これでfrontendのエラー検知が捗りそうです。
Discussion