こんにちは、ミツカリCTOの塚本こと、つかびー(@tsukaby0) です。
今回はエラーモニタリング(エラートラッキング)サービスであるSentryの扱い方についての記事です。
Sentryとは
Sentryとはエラーモニタリングサービスであり、アプリケーション上で発生した例外を検知して通知することができるというものです。
今ではSentryも機能が増えてAPMなどの側面も持っており、エラーモニタリングだけではないのですが、今回はエラーモニタリング部分だけについて触れます。
類似の製品としてDatadogやAirbrakeなどがあります。
詳細な使い方は公式ドキュメントが豊富ですし、解説している記事はいくらでもあるので、ここでは省略します。
基本的に各種言語のSDKをアプリに組み込めば、勝手に例外を補足してSentryのWebダッシュボード上で見れるようになります。また、アラート設定次第ではSlack等に通知することも可能です。
Sentryのエラー通知(Issue)の2種類の対応方法
プログラム内で例外が発生するとSentry SDKがそれを捕捉して、Sentryのサーバーに送信してくれます。このエラーはSentry上ではIssueという名称・データで記録されます。
https://docs.sentry.io/product/issues/
このIssueの発生およびアラート通知はインシデントと捉えることができます。インシデントが発生した場合、エンジニアや運用担当者は対応を開始しなければなりません。放置するとビジネス上の損失に繋がる可能性があるため基本的には即時何かしらの行動を開始するかと思います。
Issueの中にスタックトレースなどの各種情報があるため、それらをヒントにしてどうしてエラーが発生したのか、具体的にどのような問題が発生しているのか特定します。
特定後にSentry上では以下の2つの対応を取ることができます。
- IssueをResolve(解決)する
- IssueをArchive(アーカイブ)する
正確には削除したり、担当者をアサインしたり、他にも選択肢はあります。詳細は以下の資料が参考になります。
https://docs.sentry.io/product/issues/states-triage/
ただ、私の観測範囲ではあまりResolveとArchive以外の選択肢は活用されている例を聞きません。理由としてはインシデントはSentry以外の経路でも発生するために、インシデント管理を別のシステムや方法でやっているからだと予想しています。ちなみにミツカリでもこの辺りはうまく活用できていないです。基本的にはResolveかArchiveで済ませています。
SentryのIssueをArchiveするときの考え方とエラーバジェット
SentryのArchive
エラー通知を受けてプログラムのバグなどを修正し、リリースしたらResolveすることでIssueを完了の状態にできます。
しかし中には、原因が分からないが影響がほぼない優先度の低いIssueや、問題は分かっているが優先度が低く修正コストを払えないケースのIssueなどもあります。そのような場合はArchiveを使います。
アーカイブしたIssueは設定によりますが、次回発生したとしてもアラートにはしない、というようなことができます。そのため、優先度の低い通知で開発者が煩わされているようなケースではArchiveすることで徐々に通知を減らしてインシデントの監視体制を整えることができます。
Archiveは以下のように細かく設定することができます。
この設定は以下のように異なります。
- Until escalating
- エスカレーション中になるまで
- エスカレーションについてはこちら参照
- 簡単に言うと、前週と比較してエラー数増加など状況が悪化するまでアーカイブ、という設定。つまり自動アーカイブ。ミツカリでは使いこなせていないが状況次第ではうまくはまってくれそう
- Forever
- 永久
- これは問題がないエラー通知だと断言できる場合のみ使う
- 安易に使ってしまうと、実は問題があった、悪化したという状況で気づけなくなってしまうというデメリットをはらんでいる
- For... (30 minutes ... Custom)
- 一時的にアーカイブしたい場合に時間を選択する
- 例えば特定の問題があるリリースによってIssueが発生しており、現在復旧作業中のため6時間は通知不要のためアーカイブとして良い、というようなケースで使う
- Until this occurs again... (one time ... Custom) (from now ... per week)
- 今回の発生からn回発生するまで
- 例えば10 times from nowとした場合、今から10回発生するまではアーカイブとできる。つまり10回発生したら再度アラート通知になる。状況次第では使って良いし、使わないほうが良いケースもある
- 例えば100 times per dayとした場合、1日に100回以上発生するまではアーカイブとできる
- Until this affects an additional (one user ... Custom) (from now ... per week)
- 追加でnユーザーで問題が発生するまで
- 例えば10 users per weekとした場合、1週間で10ユーザー以上で問題が発生するまではアーカイブとできる
どうやって使い分ければ良いかですが、エラーバジェットという考え方や頻度について考えると良いと思います。
エラーバジェット
詳細はGoogleのSRE本を読むと詳しく理解できると思います。エラーバジェットとはざっくり説明すると「サービスレベル目標(SLO)に対して許容される失敗の余地・予算」です。
SLOをどのように設定するかはチームによって異なりますが、例えば以下のような設定例が考えられます。
- 全てのAPIは99.0%の成功率(2XXレスポンスの割合)である
- 重要な画面群AのLargest Contentful Paint(LCP)の95%が2.5秒以下である
実際には上記のようなSLOの達成度合いを測る場合はマクロに見る必要があるので、ミクロのエラー通知であるSentryは使わないかもしれませんが、考え方は適用できます。
例えばAPIの成功率目標が99.0%であるならば1.0%は許容できるため、この1%はエラーバジェットであると言えます。Sentryの通知でよく使われる特定のAPIが月に1度だけ特定のエラーを出す場合、それは許容できるとも言えそうです。そのため、このようなケースでは例えば、 Until this occurs again 10 times per week
のような設定をすることでこの頻度を超えない限りは次回の通知を避けることができます。
ただし、月に10回しか呼ばれないようなAPIで月に1度エラーが出る場合は10%のエラーになるため、無視はできません。また、Sentryの通知はよく吟味する必要があります。例えばSentryのアラートでは以下のように1ヶ月で10回以上発生した場合のみエラー通知するということもできます。
しかし、この場合、何らかのリリースによって特定の機能に障害が出てしまっていてもすぐに気づけない可能性があります。
サービスの特性によっても考え方を変える必要がありそうです。例えばtoCとtoBではエラーの重要度や深刻度が異なる可能性もあります。toBの場合、特定の顧客が売上の8割を占める重要顧客だとして、その顧客の環境下でのみ起きるエラーというケースもあります(toCの場合も重課金者などで似たようなケースはあるかもしれないので一概には言えないですが)。このような場合は、例えそのエラーがエラーバジェットに収まっているからと言って無視はできません。
結局は機械的に判断を下せないのがインシデント対応の難しいところですね。ただ、SentryのArchive設定については思慮を巡らせることでどういう設定が最適かは議論できるはずです。
基本的には Until this occurs again...
のアーカイブを行うのが良いと思いますが、特にFrontend JSのエラーのときはブラウザ等の環境が非常に多岐にわたるので特定の環境(ユーザー)でしか再現しないようなエラー通知も来たりします。そういう場合は Until this affects an additional...
の方が適しているかもしれません。頻度については画面やAPIの特性次第と言えそうですね。
今回はSentryのArchiveの扱い方やエラーバジェットの考え方について説明しました。Sentryはまだまだ深堀りできる部分が多いですし、日本語で深く解説している記事は少ない印象です。日々のアップデートで機能も増えていますし、今後も定期的にドキュメントをチェックして理解度を深めていきたいです。
現在、ミツカリではITエンジニアを募集しています。興味のある方はぜひお気軽にご連絡ください!