👓

CloudWatch RUMでReactアプリのパフォーマンスやエラーのモニタリングを試してみた

2021/12/02に公開

先日リリースされたAWSのサービス、CloudWatch RUM(Real-User Monitoring for Amazon CloudWatch)をReactアプリで試してみました。Reactアプリは複数ページがある例としてちょうどよかったので、React Routerのexamplesのbasicを使いました。

使ってみた感想を先に書いてしまうと、めっちゃ便利でした。SPAで動作するのか不安でしたが、簡単なコードスニペットをindex.html<head>に追加するだけで、エラーの捕捉やページロード速度などのパフォーマンス、ユーザーの画面遷移(ユーザージャーニー)などが確認できました。また、クライアントからCloudWatch RUMへイベントを送信し、そのイベントの集計結果をダッシュボードに表示しているんだと思いますが、設定することでイベントのログをCloudWatch Logsで確認できました。CloudWatch Logsのサブスクリプションフィルタを活用することで、エラーなどの特定のログが来たらSlackに通知するといったこともできそうです。

CloudWatch RUMとは

ドキュメントでは、CloudWatch RUMについて次のように書かれています。

With CloudWatch RUM, you can perform real user monitoring to collect and view client-side data about your web application performance from actual user sessions in near real time. The data that you can visualize and analyze includes page load times, client-side errors, and user behavior. When you view this data, you can see it all aggregated together and also see breakdowns by the browsers and devices that your customers use.

以下はDeepLで翻訳した内容です。

CloudWatch RUMを使用すると、リアルユーザーモニタリングを実行して、実際のユーザーセッションからWebアプリケーションのパフォーマンスに関するクライアント側のデータをほぼリアルタイムに収集して表示することができます。可視化して分析できるデータには、ページのロード時間、クライアント側のエラー、ユーザーの行動などが含まれます。このデータを表示する際には、すべてのデータをまとめて見ることができ、お客様が使用しているブラウザやデバイスごとの内訳を見ることもできます。

試してみる

ここから実際に試してみた内容を紹介します。

StackBlitzでサンプルアプリを開く

今回利用するReact RouterのexamplesのbasicアプリをStackBlitzで開きます。

StackBlitzを開くと、左側にコード、右側に起動したアプリケーションが表示されます。開いた直後は依存パッケージのインストール処理等が実行されるため、しばらく待つと次のような画面になるかと思います。

右側の上部にアプリケーションのURLが記載されています。この後、CloudWatch RUMにapp monitorを追加する際にアプリケーションのドメインが必要になるため、URLを控えておきます。

CloudWatch RUMにapp monitorを追加する

次に、AWSにログイン後、マネジメントコンソールのCloudWatch RUMのページを開きます。

右上のAdd app monitorをクリックして、app monitorを追加するための設定画面を開きます。

  • App monitor nameにはモニター名を設定します
    • 今回はTestReactApp
  • Application domainにはアプリケーションのドメインを設定します
    • ここで設定したドメイン以外から送信されたイベントは弾かれます
    • 今回は先程控えておいたドメインを設定しますが、今回StackBlitzでホスティングされたアプリケーションのドメインはそのままだと-が2つ並んでいたためか、そのままではエラーになります。今回は該当部分より上位のドメイン(local.webcontainer.io)のみを設定し、Include sub domainsを有効化しておきます
    • ちなみに、localhostを設定することもできます

次はどのようなデータを収集/表示するか、クッキーを有効化するか、収集するサンプルの割合を設定します。

  • Configure RUM data collection: データの収集/表示
    • パフォーマンス情報、JSのエラー、HTTPエラーのそれぞれを収集、表示するかを設定します
    • ここで有効にしない場合、対象データを表示できません
    • この後表示されるウェブクライアント設定用のコードスニペットに反映されますが、アプリに埋め込む際に設定を変更することでここで無効化したデータを収集(送信)することができます
    • 今回は3種類すべて有効にしました
  • Allow cookies: クッキーを有効化するかどうか
    • クッキーを有効化することでユーザーやセッションに基づいたデータ、ユーザージャーニーを収集できます
    • 今回は有効化しました
  • Session samples: 収集するサンプルの割合
    • 収集するサンプルの割合を設定できます
    • サンプルの割合を低くすることでデータ量が少なくなるため、CloudWatch RUMやCloudWatch Logsなどの課金を抑えることができます
    • この後表示されるウェブクライアント設定用のコードスニペットに反映されるだけなので、アプリに埋め込む際に自由に設定可能です
    • 今回は100%で設定しています

Data storageはCloudWatch Logsにデータを保存するかどうかの設定です。CloudWatch RUMは30日間データを保持しますが、それ以上にデータを保持したい場合やサブスクリプションフィルタやメトリクスフィルタなどを使ってデータを活用したい場合には、この設定を有効化します。この設定を有効化した場合に作成されるCloudWatch Logsのロググループのデータ保存期間もデフォルトでは30日間なので、より長くデータを保持したい場合にはロググループの設定を変更する必要があります。今回はデータを見てみたかったので有効にしました。

Authorizationではウェブクライアントの認証に利用するCognitoのアイデンティティプールをどうするかを設定します。

  • Create new identity pool: 新しいアイデンティティプールを作成します
    • 今回はこれを選択しました
  • Select existing identity pool: すでに作成済みのものを利用します
    • このアイデンティティプールは認証されていないアクセスを有効化されている必要があるのと、アイデンティティプールに紐づくロールが作成するapp monitorへのrum:PutRumEvents権限を持っている必要があります。
    • 参考: Use an existing Amazon Cognito identity pool
  • Use private authentication from existing provider.: 何かしらの方法で認証し、app monitorへのrum:PutRumEvents権限をもったIAMロールもしくはIAMユーザーのクレデンシャルをウェブクライアントに設定します
    • この方法を選択した場合、この後表示されるコードスニペットをアプリに埋め込むだけでなく、認証&ウェブクライアントの設定をする必要があります。
    • 参考: Executing Commands

最後に、データを収集するページの設定、X-Rayを設定するかどうか、タグの設定です。

  • Configure pages: データを収集するページ
    • すべてのページでデータを収集するか、特定のページからのみ収集するか、特定のページを除いたページで収集するかを選べます
    • 今回はすべてのページでのデータ収集(All pages)を有効化しました
  • Active tracing: X-Rayを有効化するかどうかを選べます
    • 今回は基本的な機能を試したかったので、有効化しませんでした
  • Tags: 作成するapp monitorにつけるタグを設定できます

すべて設定できたら、右下のAdd app monitorでapp monitorを追加(作成)します。

完了すると、次のようにコードスニペットが表示されます。このコードスニペットをReactアプリのindex.html<head>に追加することでアプリがデータを送信してくれるようになります。このコードスニペットをコピーしておきます。

Reactアプリに変更を加える

最初に触っていたStackBlitzで開いていたサンプルアプリのところに戻ります。次のようにindex.htmlを開き<head>に先程コピーしたコードスニペットを貼り付けます。

このコードはCDNからAmazon CloudWatch RUM Web Clientをダウンロードし、実行します。実行時に渡すプロパティで収集するデータやサンプル割合などを変更することができます。telemetrieshttpの設定を変更することで失敗したHTTPリクエストだけでなく、すべてのHTTPリクエストに関するデータを収集することも可能です。プロパティの詳細についてはドキュメントをご確認ください。

次にCloudWatch RUMでどのようにエラーを確認できるのかを見るために、/aboutを開くとエラーになるようにします。App.tsxAbout関数がエラーを投げるように次のようにコードを変更します。

変更したファイルをそれぞれ保存すると、自動でアプリケーションは更新されます。見た目上は変化はないですが、Aboutを開くとエラーが出るので真っ白になります。エラーで画面が真っ白になったら更新し、再表示します。データを作るために適当に色々な画面開いたりしておきます。

デベロッパーツールのNetworkタブを見てみると、CloudWatch RUMのapp monitorにデータを飛ばしている事がわかります。イベントが発生する都度ではなく、イベントが一定数たまるか、一定時間経つと送信しているように見えます。

CloudWatch RUMのダッシュボードを見る

マネジメントコンソールのCloudWatch RUMのダッシュボードに戻りデータを確認してみます。ページの表示数や表示速度、エラーの数が表示されてます。タブとして、今表示されているパフォーマンスの他に、エラーとセッション、ブラウザーとデバイス、ユーザージャーニー、設定があるようです。左上にあるPagesのところから集計するページを切り替えたりもできます。デフォルトでは全ページが対象のようです。左上の1h 3h ... Customからは集計する期間を変更できます。また、左の中程にあるセレクトボックスでブラウザごとやデバイスごと、国ごとでの集計もできそうです。右の方を見てみると、今表示しているページ表示以外にリクエストやロケーションに関するデータも表示できるようです。

集計対象ページを切り替えると次のようになります。左側のPagesに各ページごとの最も遅い表示時間が表示されています。Slowest load timeの他に、Most page viewsMost errorsFavoritesを選べます。Favorites以外はページ横に特定の数値が表示されますが、Favoritesはお気に入り(星マーク)に設定したページの一覧を表示するというもののようです。

下にスクロールすると、時間帯ごとのページ読み込み速度を表示できます。時間帯や日ごとの特性が分かり、便利ですね。

さらに下にスクロールすると、Web Vitalsを表示されています。Largest contentful paint、First input delay、Cumulative layout shiftの三種類の指標が時系列の折れ線グラフで表示されています。期間を長くして長期的な推移をみたり、改善前後での変化を見たりもできそうですね。

ページ読み込み時の各ステップごとの表示を確認できます。

上に戻ってErrors & Sessionsタブを開くと、エラーに関するデータを確認できます。左側のSessionsをクリックすると、セッションに関するデータも確認できるようです。時間帯ごとのエラー数とエラーの一覧が表示されています。先程埋め込んだAboutページのエラーも確認できます。

エラーごとにブラウザや端末ごとのエラー数も確認できます。

エラーの発生したセッションの一覧も確認できます。

スタックトレースもみれます。

では、次はUser journeyタブを見てみます。多くのユーザーが開く、最初のページ、2つ目、3つ目などユーザーの遷移をたどることができます。ブラウザやデバイス、国ごとでも集計対象を絞ることができるので、それぞれの特性を追えそうです。

右上のセレクトボックスでTop paths with errorsを選択すると、エラーが発生した場合の遷移をみることができます。

収集したデータをCloudWatch Logsから確認する

app monitor作成時に設定を有効化していると、CloudWatch Logsからデータを確認できます。

さいごに

CloudWatch RUMをReactアプリで試してみました。思っていた以上に簡単に色々なデータが取れて驚きました。今回はデータが少なかったからかもしれませんが、ダッシュボードの表示時やタブ切り替えたときなどの表示速度が速い点もストレスが少なく良い点でした。エラーやパフォーマンス、ユーザーの動向それぞれの専用ツールには劣るかもしれませんが、専用ツールを使ってない場合にはとりあえず設定しておくと便利そうです。一方でイベントデータはデータ量が膨大になりうるので、気付いたら課金がえげつないことになってる...といったことも考えられます。アクセス数が多い場合などにおいては、サンプル割合を減らすなどの考慮が必要です。

今回は触れていませんでしたが、ページビューのイベントは自動的に収集するのではなく、自分でパスを指定してページビューイベントを送ることも可能です。/users/1/users/2みたいなidがふくまれるパスを共通に扱いたい場合などに自分でページビューイベントを送ると良さそうです。また、エラーイベントを自分で送ることも可能です。この辺りは、以下のドキュメントを見てみると良さそうです。

参考

Discussion