(節約レシピ)Sentryの安いplanでも対象のエラーだけ取得してクウォータ数を制限する
概要
Sentryのbasic planではエラー検知数上限が月次で決まっており、制限をすることが必要になるが、管理画面でのerror messageなどのフィルタリングができない。(business planより使用可能)
そのような際に行った調査をまとめる。
経緯
開発にて、jsファイルを配信して、そのjsファイルを利用した処理を顧客サイト内一部に記載してもらうような製品を作成した際に、エラー検知をSentryで行おうとなりました。従来製品ではSentryは導入していなかったので、初めての試みでした。
いざ導入してみるやいなや、増え続けるエラー検知数、内容を見てみると
下記など、全く自分達の処理に関係のない処理ばかり...
$ is not defined
このままでは月次のエラー制限を超える、自動的には課金はされないが、自分達はbusiness planを用いる方針だったので、
どうにか自分達のjsファイルに関連するエラーのみ取得しようと試みたといった感じです。
方法・調査
方法からいうと、
beforeSendメソッドを用いてstacktraceの中身が自社jsファイル起因かでフィルタリング
を実施することで、自社のエラーは拾え、顧客サイトのエラーは検知しないようにできます。
結論に至るまでの調査としては、
まず、sentryの管理画面上からどのようなエラーがきているかを確認、そのほとんどが当社jsの関係のないjqueryのエラーだったりで制御する必要があることを再認識しました。
次に以下を参考に、管理画面上でフィルタリングできるのに行っていない機能がないかどうか確認しました。
確認したところ、spike protection(短期間にエラーイベントが大量発生し、クウォータを圧迫することを防ぐための保護機能)はONにしていたので、Inbound Filtersにて制御できないかと考慮しました。
Inbound Filtersを確認したところ、デバイスごとの制御や、IP Addressや特定URLなどの制御は要件外だった中、Error Messageの欄を用いることでエラーをフィルタリングできることがわかりました。
ただ問題なのが、Error Messageはbusiness planからしか使えないのです。
どうしたもんかとドキュメントを探ってみたところ、
sentry.initの中でイベントを送信する前に、フィルタリングできるbeforeSendメソッドがあるとのことを発見しました。
そもそも、sentry初期化の際に、読み込まれた後に発生する他jsエラーも自動で検知するのが問題だったので、こちらでフィルタリングすれば良いと方針を決め、
一緒に働いている方のご意見から、stacktraceを確認して、自社対象ファイル名称が入っているかどうかでフィルタリングするようにしました。
function onSentryLoaded() {
if (window.Sentry) {
window.Sentry.init({
dsn: {sentry.ioのurl},
denyUrls: ['localhost'],
beforeSend(event, hint) {
// もし例外が発生した場合
if (event.exception) {
try {
const errorType = event.exception.values[0].type;
const stacktrace = event.exception.values[0].stacktrace;
// スタックトレースに'hogehoge.js'が含まれている場合のみ検知
if (stacktrace && !/hogehoge\.js/.test(stacktrace)) {
return null;
}
} catch (err) {
// 例外へのアクセスに問題があった場合、そのイベントをそのまま通す
return event;
}
}
// 例外ではないイベントはそのまま通す
return event;
}
});
}
}
このコードを実装した後、下記を中心に検証し、確認が取れれば完了です。
- このハンドリングによって無関係なサイトのフロントエラーは検知されないようになるかどうか
- このハンドリングによってhogehoge.js起因のエラーは検知されるかどうか
結果
business planでもエラーのフィルタリングを柔軟にできるのだとsentryの知識がほんの少しだけ上がったのではないかと思えるような調査内容でした。
また効果検証出来次第、どれだけ効果があったかも追記させていただきたいと思います!
参考資料
Discussion