【React Native】Sentry にログを送る

Article by: Lewis D.

 
 
 

Logs は、開発チームが問題を調査するときに最初に確認することが多い場所です。しかし、Logs は後回しで追加されることが多く、開発者は「ログを出しすぎる/出さなさすぎる」のバランスに悩みがちです。

経験豊富な開発者なら、調査を頼まれて 200MB のプレーンテキストのログファイルを渡された経験を覚えているかもしれません。3 時間と 4 本の Python スクリプトを費やした末に、問題が別のコンポーネントにあると分かる、というようなことです。

これまで、ロギングを簡単にするための多くの標準やライブラリが作られてきましたし、React Native にはロギング関数も豊富にあります。私たちの React Native ロギング入門ガイドは良い出発点です。ただ、さらに一段レベルを上げたいなら、このガイドで Sentry のロギング機能を使う方法を紹介します。これにより、ログが有用になり、必要な情報をすぐに取り出せるようになります。

 

Sentry に Logs を取り込む

このガイドでは、シンプルな React Native(Expo)アプリを使って、Sentry のさまざまなロギング機能の例を示します。

このアプリは、フィールドに基本的なバリデーションがある問い合わせフォームです。手元で同じように試したい場合は、デモリポジトリ内にこのアプリがあります。

デモの React Native アプリのインターフェース

 

既存の React Native アプリケーションがある場合やこれから作る予定がある場合でも、このガイドでは、Sentry を使ったロギングを最大限に活用するために必要な手順を説明します。

 

セットアップ

Sentry の機能を使い始めるには、まずプロジェクトに Sentry を導入する必要があります。最初に Sentry で新しいプロジェクトを作成し、プラットフォームとして React Native を選択します。次に、インストールウィザードを実行して、ローカルのプロジェクトに必要な設定を追加します。

プロンプトが表示されたらロギングを有効にします。設定が完了すると、メインの App.js に次のようなコードが追加されているはずです。

これにより、Sentry SDK が初期化され、Sentry のロギングライブラリによる Logs が有効になります。

 

Sentry Logger API

Sentry を初期化して Logs を有効にしたので、Sentry.logger 名前空間を使って、ログを Sentry のダッシュボードに送信できます。

ログレベルは次のとおりです。

  • trace
  • debug
  • info
  • warn
  • error
  • fatal

 

また、Sentry.logger.fmt 関数を使うと、ログメッセージにプロパティを追加できます。

サンプルアプリでは、handleSubmit 関数に新しいログ呼び出しを追加します。

 
Submit ボタンをクリックすると、Sentry のダッシュボードに info レベルのログが表示されます。
 
 

ログには追加の属性を手動で付与できます。これらはログメッセージ本体の一部にはならず、ログに付随する形で追加され、あとから検索やフィルタに使えます。

試すには、先ほど追加したログを次のように更新します。

フォームを送信すると、ログのペイロードに新しい filterID と extraMessage の両方のフィールドが表示されます。

 

インテグレーション

Sentry Logger API は動くようになりましたが、このアプリにはすでに、デフォルトの JavaScript の console オブジェクトを使ったロギングがあります。幸い、すべてを書き直す必要はありません。Sentry には、デフォルトの JavaScript ロギングと統合する方法も用意されています。

App.js の Sentry.init 呼び出しで、enableLogs: true の行の後に、次のコードを追加します。

 

 

 

 

Logs には次の情報が表示されます。

  • ユーザーが投票しようとした猫(catId: “133”)
  • 投票の種類(voteType: “upvote”)
  • バックエンドからのエラーメッセージ(errorMessage: “API Error: 500″)
  • エラーが発生したタイムスタンプ

 

これは error レベルのイベントなので、Sentry には Issue も記録されます。Issues ダッシュボードへ移動し、該当するエラーイベントをクリックします。

Issue のエントリでは、下へスクロールすると、エラーに至るまでの breadcrumb のトレイルを確認できます。

Logs からは、ユーザーが猫一覧を読み込み、upvote ボタンをクリックし、その後 API リクエストが 500 の HTTP ステータスコードで失敗したことが分かります。

これで、問題がバックエンド側にあることが分かりました。同じタイムスタンプ付近のバックエンドのサーバーログを確認すると、データベースの制約エラーが見つかりました。バックエンドは投票を挿入しようとしましたが、外部キー制約違反(cat ID がデータベースに存在しない)により拒否されていました。

Sentry の Logs に戻り、この猫がいつ追加されたのかを検索します。operation:fetchCats で絞り込むと、アプリが外部 API から猫を取得していたことが分かります。しかし、データベースに保存しようとした際に、リクエストのうち 1 つが失敗していました。Sentry のログには次のように表示されています。

問題は明確です。アプリが新しい猫を取得したとき、一部はデータベースへの追加に成功しましたが、別の一部は ID の重複により失敗していました。結果として、ユーザーにはデータベースに存在しない猫が表示され、その猫に投票しようとすると、バックエンドが投票を拒否していました。

この問題は、猫を取得するロジックのエラーハンドリングを改善することで修正できます。保存に失敗した猫は UI から取り除き、ユーザーがデータベースに存在しない猫に投票できないようにします。

 

パフォーマンス監視

エラーに加えて、Sentry の spans 機能を使えばパフォーマンスも追跡できます。frontend/src/context/CatsContext.js では、猫の読み込みにどれくらい時間がかかっているかを計測できます。

spans を使うと、パフォーマンス追跡の開発者体験が向上します。Sentry ダッシュボードの Performance タブで span データを確認でき、アプリケーション内の遅い処理やボトルネックを簡単に特定できます。

 

 

beforeSendLog 関数

beforeSendLog 関数を使うと、Sentry に送信する前にログをフィルタできます。Sentry に届くデータを細かく制御できるため、十分なログを確保しつつ、ダッシュボードをノイズで埋めないようにバランスを取るのに役立ちます。

たとえば、本番環境では debug レベルのログを除外したり、機密情報を取り除いてから Sentry に送信したりできます。

null を返すことで、そのログが Sentry に送信されないようにできます。この方法は、機密性の高いユーザー情報を保護しつつ、ログを整理して関連性の高い状態に保つのに役立ちます。

 

 

Logs を超えて

Sentry のロギングは、ログをただの生データから、問題の診断で膨大な時間を節約できる有用で直感的なツールへと変えます。

Sentry のロギング機能をセットアップする手順がまだ不明な場合は、logs の設定、または drains と forwarders の設定に関するドキュメントを参照してください。

このガイドでも触れたとおり、ロギングは tracingprofiling といった Sentry の他の機能と密接に連携します。

これらの機能をすべてセットアップすれば、Sentry のツール群を最大限に活用することができます。

 

FAQ


 
■構造化データをメッセージに詰め込むのではなくログに添付できますか?

はい。そうすることをおすすめします。catId や voteType、feature のような属性を追加すると、ログメッセージの読みやすさを保ちつつ、ログを検索・フィルタ可能にできます。ログメッセージは見出し、属性はデバッグ時に助けになる注釈だと考えてください。

 

Sentry では、Logs と Issues はどういう関係ですか?

Logs と Issues はつながっていますが、役割が異なります。Logs は「何が、どの順番で起きたのか」を理解するのに役立ちます。Issues は「対処すべき失敗」を表し、通常はエラーやクラッシュに関連付きます。error レベルのログが記録されると、Sentry は Issue を作成または更新し、Logs、breadcrumbs、スタックトレース、ユーザーコンテキストを 1 か所にまとめて関連付けられます。

 

フロントエンドとバックエンドにまたがる問題のデバッグでは、Logs はどう役立ちますか?

Logs は出来事の流れを語り、トレーシングは時間軸を示します。フロントエンドで意味のあるイベントをログを記録し、バックエンドのログやトレースと組み合わせることで、ユーザーのタップからデータベースエラーに至るまで、リクエストを追跡できます。特に、フロントエンドのエラーが、実は別の姿をしたバックエンド問題だった場合に有効です。

 

最初から選別してログを記録すべきですか?それとも全部記録して後で絞り込むべきですか?

一般的には、意図を持って積極的にログを記録するのがよいでしょう。インシデント後に不足しているログを後追いで追加するより、Sentry 上でノイズの多いログを後からフィルタするほうが簡単です。状態の変化、ユーザー操作、システム境界(API 呼び出し、永続化、非同期処理)を中心に記録してください。量が問題になったら、ログレベルや beforeSendLog で調整します。

 
Logs と breadcrumbs はどう使い分ければよいですか?

単体で検索・クエリできるものにしたいなら Logs を使います。エラーやクラッシュに付随するコンテキストとして残したいなら breadcrumbs を使います。Logs はアプリ全体で何が起きたかを伝え、breadcrumbs は何かが壊れる直前に何が起きたかを伝えます。

 

ロギングを設定した次のステップは何ですか?

Logs をエラー、パフォーマンスの spans、リリースと関連付け始めてください。ロギングはより大きなフィードバックループの一部として使うと最も効果を発揮します。アプリがクラッシュしたかどうかだけでなく、コード変更が実際のユーザーにどう影響するかを理解する助けになります。

 

 

Original Page: Logging in React Native with Sentry

 




IchizokuはSentryと提携し、日本でSentry製品の導入支援、テクニカルサポート、ベストプラクティスの共有を行なっています。Ichizokuが提供するSentryの日本語サイトについてはこちらをご覧ください。またご導入についての相談はこちらのフォームからお気軽にお問い合わせください。

 

シェアする

Recent Posts