wheatandcatの開発ブログ

React Nativeで開発しているペペロミア & memoirの技術系記事を投稿してます

sentry-goを実装してみる

GAEのエラーは、デフォルトでGCPのロギングに出力されますが、ずっと追い辛いと思っていたのでsentry-go導入してエラー監視できるようにしてみました。

github.com

Pull Request

github.com

実装

Sentryはアプリのエラー監視でも使用していますがGo言語もサポートしていたので、こちらを採用しました。

Go | Sentry Documentation

実装的には上記のドキュメント通りでOKです。 ペペロミアではフレームワークにGinを採用しているので、以下のドキュメントの通り実装しました。

Gin | Sentry Documentation

まず、main関数に以下を追加

app.go

func main() {
    err := sentry.Init(sentry.ClientOptions{
        Dsn: os.Getenv("SENTRY_DNS"),
        Debug:            flase,
        AttachStacktrace: true,
    })

ペペロミアではエラー出力箇所を一箇所にまとめていたので、そこにSentryのメッセージ送信処理を追加

handler/handler.go

// Render 書き込み
func (e *ErrorResponse) Render(gc *gin.Context) {
    if hub := sentrygin.GetHubFromContext(gc); hub != nil {
        hub.WithScope(func(scope *sentry.Scope) {
            r := getRole(gc)
            if r == RoleApp || r == RoleGraphql || r == RoleAdmin {
                // アプリの場合はユーザーIDを追加
                uid, _ := GetSelfUID(gc)
                scope.SetUser(sentry.User{ID: uid})
            }
            hub.Scope().SetTag("role", r)
            hub.CaptureException(e.Error)
        })
    }

    gc.JSON(e.StatusCode, e)
}

ユーザーIDがSentryで表示されると便利そうなので、以下の部分でユーザーIDを設定しています (※cronで実行するAPIにはユーザーIDが無いのでif文で分岐させています)

         if r == RoleApp || r == RoleGraphql || r == RoleAdmin {
                // アプリの場合はユーザーIDを追加
                uid, _ := GetSelfUID(gc)
                scope.SetUser(sentry.User{ID: uid})
            }
            hub.Scope().SetTag("role", r)
            hub.CaptureException(e.Error)

これでエラーが発生すると以下みたいにSentryにエラーメッセージが飛ぶようになります。

スクリーンショット 2020-08-12 22 59 40

以下の画像で、ちゃんとユーザーIDが設定されているのも確認できました。

f:id:wheatandcat:20200817004054p:plain

あとは、SentryのIntegrationsの設定でSlackと連携させればエラー発生時に気づけるようになると思います。

Sentryはフロントエンドのエラー監視システムのイメージがありましたが、Go言語でも問題なく運用できそうです。