今回はSentryというエラー集約管理システムをGo言語で扱う場合の知見を共有したいと思います。Sentryはエラーの集約管理を行うためのシステムで、作成したアプリケーション内で発生したエラーを一括で収集して見やすく管理することができます。sentry.io類似のエラーをグルーピングして発生頻度を確認したり、エラーの発生状況をSlackのようなチャットツールに通知してくれたりします。予期しないエラーが発生したとき、生のログを見なくてもSlackやWebのUIで確認出来るのはとても便利です。バックエンドからフロントエンドまで幅広い言語に対応しているためシステムのエラーを一括で集約が可能です。JX通信社ではエラー管理ツールとしてSentryを広く利用しており100を超えるシステムが登録されています。Sentryはセルフホスト版のSentryも存在していて、当初はサーバーを構築して利用していたのですが運用の煩雑さからマネージドなサービス版を利用するようになりました。sentry-go、触ったことない方もいると思いますので、まずは使い方を軽く紹介します。}}このような形でSDKをセットアップすると、エラーやPanicが発生した場合にSentryへとデータが送られます。呼んでpanicから脱しSentryへの送信を行います。呼ばないと捕捉できないケースがあります。APIサーバーの場合はSentry側でWebFrameworkのインテグレーションを用意してくれています。ユーザーのリクエスト情報(パスやメソッド、リモートアドレスなど)をエラーと合わせて記録してくれるので原因の調査がしやすくなるので利用可能であれば使ってみましょう。おすすめのClientOptionsSentryの初期化時に渡せるClientOptionsについて参考程度におすすめの設定を紹介します。詳細については公式ドキュメントを参照してください。DSNを入れるオプションです。プロジェクトごとに専用のDSNが発行されるので、これをソースコードにセットすることで正しくセットアップができます。いう環境変数をSDKが参照してくれるのでセットせず利用することが多いです。DSNが未設定の場合でもエラーにはなりません。未設定時の場合、sentry.CaptureException()などを呼んでも何も起こりません。有効にするとEventを破棄したログが出ます。ローカルの開発環境ではSentryを使わず開発し、検証用のサーバーにあげるときにSentryのログを有効にする使い方が簡単にできます。Environment:環境を入れるオプションです。入れておくと本番で起きたエラーなのかがすぐ分かります。チャンネルを変えるといった使い方も可能です。AttachStacktrace:CaptureMessageを呼んだ時にスタックトレースを付与するかのオプションですソースコードの位置がわかるので基本付けておいて損はないかと。サーバーにエラーを飛ばした数で料金プランが変化するので、対処する必要は特にないけれど大量に出てしまうエラーなどはここでセットしておくと安心です。他にもパフォーマンス計測用のオプションなどがありますが今回は割愛します。Goでの困りごとエラーの収集は上記で出来るのですが、Go言語の場合すこし困ったことが起こります。機能が提供されるようになり、捕捉したエラーをfmt.Errorfでラップして上位に返すパターンをよく書くようになりました。...ラップをすることでエラーの抽象度があがり、呼び出す側が意図を把握しやすくなります。ところがこうしてラップされたエラーをSentryに渡すとこのような形で処理されてしまいます。呼び出した箇所になってしまっています。エラーの原因を調査をするとき、CaptureExceptionを呼び出した箇所というのはあまり重要ではなく、実際にWrap前のエラーが発生した箇所や、fmt.Errorfでラップを行った箇所を知らせてくれるほうが有用です。Python版のSentryの場合、SDKをセットアップすればよしなにスタックトレースを出してくれたのですが、Goの場合、言語の標準エラーにスタックトレースの機能が存在しないため、少し不便な出力になります。ラップしたエラーがすべて同列のエラーとして集約されてしまう問題もあります。Sentryの場合、エラーのグループごとに通知を設定することが多いので、異なるエラーが同一にまとめられてしまうと重要なエラーを見逃してしまうリスクがあります。このあたりもPython版だとSDK入れるだけだったのですが静的言語なのでいろいろ制約がありそうです。2つが実現できればSentryでの取り扱いがよくなりそうです。外部エラーパッケージを利用すると、Sentryがそこからスタックトレースを取り出して表示してくれることが分かりました。pkg/errorsxerrorsgo-errors/errorspingcap/errorsドキュメントとして明文化されていないものの、現在この4つのパッケージに対応してそうです。有名なエラーパッケージでしたが、現在レポジトリがArchiveされてしまっているため新規では利用しづらいです。Go公式がメンテナンスしているエラーパッケージです。本体に取り込まれたものの、スタックトレースの機能については取り込まれなかったためパッケージが残っています。スタックトレースのみを表示する用途であればこのパッケージで十分そうです。sentryでエラーを投げるところだけではなくてちゃんとエラーが発生したところをトレースできてますね。一括で変換してしまえばいいかというとそうでもなくて、今度は過剰にスタックトレースが付与されてしまいます。それらを全部列挙しようとします。本当に見たい部分以外のスタックトレースが入ってしまうので調査のための情報が逆にノイズになってしまいます。以下の方針でラップすると無駄のないエラーハンドリングが出来るかと思います。した部分もトレースが残っていくので上記の方針で進めると無駄なくエラーにスタックトレースを付与できると思います。ラップしたものがSentry上でまとめられてしまう問題についても見ていきます。https://github.com/getsentry/sentry/issues/17837GitHubのIssueにヒントがないかみてみたのですが明確な解決法が見当たらず、SDKでタイトルを上書きするのがいいのではないかというコメントで終わっています。いうフックが用意されており、こちらを利用することでタイトルの書き換えが可能になるみたいです。keyのように書き換えてあげれば、最後にWrapしたメッセージがグループ名として利用できそうです。*sentry.Eventのようになっており、渡されたeventを書き換えてreturnしてあげれば上書きが可能です。利用されるみたいたいです。場合だけ上書きしてみることにします。無事エラーを書き換えることが出来ました。剥がしていますが、処理を変えればより柔軟にカスタマイズできそうです。Corp.引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。