Sentryのセッションリプレイ料金を90%以上削減した話
はじめに
現在のプロジェクトでは、主にフロントエンドの開発に従事しています。このプロジェクトでは、Sentryを使用してエラートラッキングを行なっています。その中でもセッションリプレイはエラー前後のユーザーの行動を再現することができ、エラーの解析に非常に有用です。しかし、プランによっては無料枠があるものの、無料枠からはみ出した分は基本料金とは別の支払いとなります。以下は執筆時点(2024/06/10)でのセッションリプレイの料金体系です。
プラン名 | 支払い方式 | 無料枠 | データ保持期間 | 1セッションリプレイあたりの料金 |
---|---|---|---|---|
Team | 月払い | 500リプレイ | 90日 | 約$0.0029 ~ $0.0021 |
Team | 年払い | 500リプレイ | 90日 | 約$0.0026 ~ $0.0019 |
Business | 月払い | 500リプレイ | 90日 | 約$0.0029 ~ $0.0021 |
Business | 年払い | 500リプレイ | 90日 | 約$0.0026 ~ $0.0019 |
TeamとBusinessはプランによって1セッションリプレイあたりの料金に変わりはないものの、支払い方式や総セッションリプレイ数によって変動する仕組みとなっています。
今回は、セッションリプレイのコストを大幅に抑えた設定や運用方法の紹介をしたいと思います。
削減しようとした背景
私が携わっているプロジェクトが他のプロジェクトより100倍セッションリプレイが送信されている報告を受け調査してみると、期待通りの使用量でないことがわかりました。月々のコストも嵩んでいることから早急に設定や運用を見直すことにしました。
原因
結論から言うと、デバッグ目的でSentryに送信していたアプリケーションログと一緒に意図せずセッションリプレイが送られていたことが原因でした。
過剰に送られている原因としては、上記の送信していたエラーは(業務影響はないが)ユーザー側で高頻度で起こるものであったことと、エラーの際にセッションリプレイのサンプル率が100%になっていたことでした。
あまり数はないんですが、環境ごとにサンプル率などを調整する設定を怠っていたことも原因として挙げられます。
あと直接的な原因ではないんですが、Sentryの導入チュートリアルにはreplaysSessionSampleRate
とreplaysOnErrorSampleRate
があらかじめ数値が入力されているので、コピペして使っている方は気をつけたほうが良いかもしれません。
対策
上記の原因からセッションリプレイを送信するルールを定めて、SDK側に設定することにしました。ルールは以下です。
- 開発環境ではセッションリプレイを送らない
-
replaysSessionSampleRate
はどの環境でも0% -
error.level
がdebug
の際にはセッションリプレイは送らない
ルール1の理由は、開発環境は主に開発者が触るのでセッションリプレイを利用してユーザーの操作を再現する必要がないことから開発環境ではセッションリプレイは必要ないと判断しました。
ルール2のreplaysSessionSampleRate
というのは、エラーの有無に関わらずセッションリプレイを送信する比率です。理由としては、私のプロジェクトではエラー事象の再現以外にセッションリプレイを使うユースケースがなかったのでreplaysSessionSampleRate
は0%に設定することにしました。
ルール3理由は、デバッグ目的でSentryに送信しているエラーは高頻度で起こるかつ、現状セッションリプレイから得られる情報が特に必要なかったので送らない、としました。
上記のルールをSentryのSDK側に設定すると以下のようなコードになります(イメージです)
import { init, BrowserTracing, Replay } from '@sentry/react'
import { BUILD_ENV, RELEASE_ID, SENTRY_DSN } from '@/constants/env'
const isSentryEnabled = SENTRY_DSN !== undefined || BUILD_ENV !== 'local'
export const initializeSentry = () =>
isSentryEnabled &&
init({
dsn: SENTRY_DSN,
integrations: [
new BrowserTracing(),
new Replay({
beforeErrorSampling(event) {
return event.level !== 'debug' && BUILD_ENV !== 'development'
},
}),
],
environment: BUILD_ENV,
tracesSampleRate: 0.1,
replaysSessionSampleRate: 0,
replaysOnErrorSampleRate: 1.0,
})
ポイントは、beforeErrorSampling
というメソッドです。こちらは@sentry/react@7.78.0
以上から実装された機能です。このメソッド内では、エラーが起きた時にセッションリプレイを送るか送らないのロジックを実装することができます。
Sentry.withScope((scope) => {
scope.setLevel("debug")
scope.setExtras(data)
Sentry.captureException(error)
})
上記のように、エラーを送信する実装の箇所で、setLevel
にdebug
を渡すと、beforeErrorSampling
でフィルターされる仕組みです。
結果
具体的な金額や数は伏せますが、元々送り過ぎていたこともありその後のコストと比べた結果、90%以上の削減に成功しました。
まとめ
いかがでしたでしょうか?効率的にセッションリプレイを使用しつつコストを大幅に削減することができました!
どういった条件では送らないなどチームで方針を決める必要はあるものの、実装としては軽微なのでセッションリプレイのコストの削減に取り組んでみるのはいかがでしょうか!
Discussion