Sentry入門@マナリンク
本記事について
オンライン家庭教師マナリンクで利用しているSentryの入門記事です。
マナリンクでは、WebフロントエンドおよびReact NativeアプリにてSentryを活用してエラーを捕捉しています。
本記事の内容はほぼそのままREADMEとしてリポジトリに置こうと思っているので、多少前提条件などを飛ばして記載しますがご了承ください。記事として発信しつつREADMEが充実する一石二鳥の施策として取り組んでいます。
Sentryの概要
Sentryはアプリケーションで発生したエラーを収集して管理画面上で一覧できるサービスです。
Sentryへのエラーの送信は各言語・フレームワークごとに用意されているSDKで実装できます。
なので、Sentryを使いこなす上では大きく以下の2つの点を理解する必要があります。
- SDKを使ってアプリケーションからエラーを送信する方法
- 管理画面でエラーを見たり、Slack等に送信する方法
順に説明していきます。
Sentry SDKの使い方
マナリンクでは大きく分けてReact Nativeアプリと、Nuxt製のフロントエンドでSentryを活用しています。
どちらかというとReact Nativeアプリのほうがより多くSentryを活用しているのでReact Nativeのコードで解説しますが、Nuxtでもほぼ同様の仕様で扱えます。
React Native
マナリンクではReact NativeアプリにExpoを利用しています。
そのためsentry-expo
パッケージを利用してSentryのセットアップをします。
セットアップ
App.tsxなどでinit
メソッドを実行します。dsn
には、Sentryの管理画面上から取得できるURLを設定します。
Sentry.init({
dsn: Constants.manifest?.web?.config?.sentry.dsn,
release: Constants.manifest?.revisionId || 'DEV',
debug: __DEV__,
});
基本的にはこれで完成です。これでJavaScriptアプリケーション上で発生したエラー(Catchされなかったエラー)がSentryに対して送信されるようになります。
ユーザーと紐付ける
エラーが送信されても、そのエラーがどのユーザーによって起こされたものか分からなければ意味は半減します。
以下のように実装することで、Sentryにあらかじめユーザー情報を送信することができます。マナリンクではユーザーIDとユーザー名、revisionId(ExpoでOTAアップデートをしたときのリリースID)を紐付けています。Sentryのドキュメントではemailを送信するような例が載っていますが、不必要に色々なサービスにユーザーのメールアドレスを共有するのは好ましくないと思うので、IDにするほうが良いかなと思ってます。
useEffect(() => {
if (auth) {
Sentry.Native.setUser({
id: auth.uid,
name: auth.displayName,
revisionId: updateManifest?.revisionId,
});
setUserメソッドの実行後に発生したエラーは、Sentryの管理画面で調べたときにユーザー情報と紐付いているので、どのユーザーが起こしたエラーなのかをすぐ特定できて便利です。
エラーの前に起こったイベントをトレースする
ユーザーがエラーを起こしたことが特定できても、その直前まで何をしていたのか、という文脈が重要になることはあります。たとえばチャットアプリを開発していて、チャットメッセージの送信直後にエラーが出ていた場合などです。
その文脈はSentryではBreadcrumbsという機能で保存できます。
なにかキーになる操作を行った際に、以下のようにaddBreadcrumb
を実行することで、エラー発生時にSentryの管理画面でエラー直前のユーザーの操作内容が特定できます。category, messageだけでなく、data属性で任意のデータを投げることができます。
Sentry.Native.addBreadcrumb({
category: 'ACTION',
message: 'SEND_MESSAGE',
data: {
roomId: props.route.params.room.id,
userId: user!.id,
},
});
実際役に立った例でいうと、ログイン関連と見られるエラーが起こったときに、直前に何度もログインを繰り返していることがBreadcrumbsのおかげで分かったことがありました。直接的な原因分析にはつながらないことが多いですが、ユーザーからのお問合せと、起こっているエラーを紐付けて確度を高めるときに役立ちます。
手動によるエラー送信
実際には、全くキャッチされずにエラーがThrowされることはそこまで多くなく、Catchしてユーザーにフィードバックを返すことが多いと思われます。その際にSentryにエラーを送信できないわけではなく、手動によるエラー送信も可能です。
.catch((error) => {
Sentry.Native.captureException(error);
setError(error);
})
captureException
メソッドにError型の変数を渡すことで、エラーとしてSentryに送信できます。
警告メッセージ等の送信
Error型の値として現れていなくても、たとえばDeprecatedになっているはずの実装が動いていることを検知したいなど、単なる警告程度のメッセージをSentryに記録することもできます。
Sentry.Native.captureMessage(`○○の取得に失敗`, Severity.Warning)
captureMessage
は単なるStringをSentryに送信できます。第2引数としてレベルを指定でき、InfoやDebug、Warningなどが選択できます。
たとえばErrorレベルのものだけ社内Slackに通知するようにアラート設定し、Warning以下はSentryにストックするだけにしておき、バグが起こりそうな実装や削除したはずの機能がまだ動いていることの検知などが可能です。
マナリンクではErrorレベルのものだけSlackチャンネルに通知しています。その設定はSentry管理画面からできます。
このへんはまだマナリンクでしっかり運営しているわけではないので、規模に応じてメッセージ形式に縛りを掛けるなど工夫の余地がありそうです。
Sentry管理画面の使い方
続いて管理画面の使い方を説明します。
マナリンクはSentryのTeam planに入っているので、月に50,000エラーまで捕捉でき、メンバー招待も何人でも可能です。すでに入っているメンバーに招待してもらってください。
エラーの見方
Issuesという画面から起こっているエラーや、captureMessageで投げている文字列の一覧を見ることができます。
それぞれクリックすると詳細ページに遷移し、ユーザーの利用している端末のOSやアプリのバージョンを始め、以下のような見た目でBreadcrumbsで記録した内容を見ることができます。
実際のエラーの内容はSentryの画面で見てください。
Slack連携
Alertsという画面からSlack連携の設定ができます。マナリンクではErrorレベル以上のものだけ通知していますが、条件設定が柔軟にできるのでWarning等のレベルでも通知することができます。
Issueを無視する
特にWebフロントエンドでは、ブラウザ依存のエラーなどどうしようもないエラーログがしょっちゅう流れますし、Network Errorなどユーザー側の通信状況に依存するようなエラーが流れることも多いです。これらのエラーが毎回Slackに流れるとうるさいので、マナリンクの場合はIssueの詳細画面で「Ignore」を押してAlertの対象外にしています。
継続的に改善する
Sentryには日頃から相当数のエラーが流れるし、実装次第で簡単にエラーやメッセージを投げれてしまうので、管理体制をどうするかは継続的に改善する必要がありそうです。
- 何をSentryに投げて何を投げないのか
- どんな情報を投げるのか
- どんなレベルとして投げるのか
- 検知体制はSlackで十分なのか
改善提案をお待ちしています。
以上でSentryの活用内容についての記事を終わります。運用面についてはまだ改善するところがある気がするので、いろいろな事例を知りたいです。
オンライン家庭教師マナリンクを運営するスタートアップNoSchoolのテックブログです。 manalink.jp/ 創業以来年次200%前後で売上成長しつつ、技術面・組織面での課題に日々向き合っています。 カジュアル面談はこちら! forms.gle/fGAk3vDqKv4Dg2MN7
Discussion