Carpe Diem

備忘録

bugsnagのWeb UIでスタックトレースを表示する方法

背景

サーバサイドでエラー検知・トラッキングSaaSを利用する場合、bugsnagが候補に挙がると思います。

ただそのままerrorをNotify()してみてもスタックトレースがきちんと表示されない問題にぶつかります。

今回はGoでbugsnagを利用する場合に、bugsnagのWeb UIでスタックトレースを表示する方法を紹介します。

環境

  • Go 1.17
  • bugsnag-go v2.1.2

bugsnag側はどう判定しているか

bugsnag側がエラーにスタックトレース情報が含まれているか否かを判定しているロジックは以下です。

func hasStack(err error) bool {
    if _, ok := err.(errorWithStack); ok {
        return true
    }
    if _, ok := err.(ErrorWithStackFrames); ok {
        return true
    }
    if _, ok := err.(ErrorWithCallers); ok {
        return true
    }
    return false
}

ref: bugsnag-go/error.go at b31bbecd4eb6e307dd7738f729ab51973244d903 · bugsnag/bugsnag-go · GitHub

つまり

  1. errorWithStack
  2. ErrorWithStackFrames
  3. ErrorWithCallers

の3つのインタフェースのどれかを実装している必要があります。

対応

bugsnag-go/errorsを使う

公式ドキュメントに書いてある方法です。

bugsnag-go/errorsを使うとスタックトレースを表示してくれます。

このエラーパッケージは

のインタフェースを実装しています。

ただ当然ですがエラーが発生した地点から使う必要があり、bugsnag-go/errorsに強く依存することになるので心中するつもりで導入が必要です。

pkg/errorsを使う

github.com

こちらのPRでbugsnag側が対応してフレーム情報を表示するようにしてくれました。

pkg/errorsを使うと

のインタフェースを実装していることになるので、スタックトレースを表示してくれます。

Release v1.6.0 · bugsnag/bugsnag-go · GitHub

以降のバージョンであれば反映されてます。

自前でインタフェースを実装する

独自エラーを定義し、その中でフレームを保持して

  1. errorWithStack
  2. ErrorWithStackFrames
  3. ErrorWithCallers

の3つのインタフェースのどれかを実装すれば、bugsnagのWebビューでスタックトレースを表示してくれます。

ただし1はpkg/errorsのStackTrace型に依存していますし、2もbugsnag-goのStackFrame型に依存しています。

まとめ

bugsnagのWeb UIでスタックトレースを表示する方法を紹介しました。