「AWS 春の Observability 祭り 2025」というイベントを行いました。
多くの皆様にご参加頂きありがとうございました。
せっかくなので、私が話した内容をここにも公開しておこうと思います。
このセッションでは Amazon CloudWatch で始めるエンドユーザー体験のモニタリングと題しまして説明させて頂きます。
こちらは皆様もよく見られる内容だと思いますが、
Eコマースサイトの閲覧に関して、読み込み時間が予想よりも遅い場合、70%近いユーザーで購入意欲が低くなり、また将来、サイトに再び訪問する可能性が低くなると言われています。
このように、サービスを提供する上で、ユーザー体験は ビジネスに直結する重要な指標の1つとなっていることは皆様もご存知だと思います。
ユーザー体験のモニタリングの重要性についてもう少し掘り下げてみましょう。
そもそも、サービスをモニタリングする目的は、ビジネスにおいて重要なサービスの健全性を把握することです。
そのためにも、実際に利用するユーザーの体験をモニタリングすることは最も重要なモニタリングといえます。
極論、サーバーのCPU利用率が100%でも、ユーザー体験が損なわれていない場合はビジネス上、大きな問題ではありません。
逆に、CPU利用率が低くても、ユーザーの体験に影響がある場合は、ビジネス上、大きな問題に繋がる可能性があります。
また、ユーザーの体験を継続してモニタリングすることで、問題があった場合、いつ時点にロールバックを行えば良いのかを簡単に把握することができます。
もちろん、フロントエンドのエラーを収集することで、エンドユーザーで起きた問題を早く解決できます。
エンドユーザーの行動を収集することで、ユーザーがサイト内でどのような行動をとっているのかを分析し、コンテンツの良し悪しを判断することができます。
さらに、アクセス数やアクセス内容から必要なキャパシティをより正確に見積もることが可能です。
このようにエンドユーザー体験のモニタリングはビジネス上、そしてサービスの運営上、さまざまな利点をもたらします。
もちろん、実際にサービスを運営する場合、フルスタックでオブザーバビリティ戦略を構築して頂く必要があります。
エンドユーザー体験のモニタリングでは、エンドユーザーにとって何か快適かを把握し、関連する情報を収集することが重要です。
例えば、表示時間、アクション応答時間、購入失敗、JavaScript エラー を把握しておくことで、エンドユーザー体験が悪化していないかを把握することができます。
一方で、問題を調査するにはバックエンドで問題が発生していないか?も把握する必要があります。
例えば、調査に必要な情報として、CPUやメモリの利用率だけでなく、アプリケーションのログやスロークエリログ、ヘルス状態、サーバーの再起動やレイテンシーを収集しておく必要があります。
さらに、エンドユーザー体験のモニタリングデータとバックエンドアプリケーションのモニタリングデータを紐付けておくことをお勧めします。
これにより、エンドユーザー体験に問題が生じた場合に、バックエンドアプリケーション側の問題を迅速に把握することができるようになります。
つまり、ワークロードを完全に把握するには、エンドユーザーの体験を含む、すべての層を紐付け可視化することが重要です。
ユーザー体験のモニタリングの方法は大きく2つあります。
1つは定期的なエンドユーザー体験のテストを行うことです。
これは Synthetic Monitoring と言われ、 特に、短期的な問題を検知することに優れています。
もう一つは Real User Monitoring と言われ、実ユーザーのアクセスの情報を取得することで、中長期のユーザー傾向を把握することができます。
また、テストでは網羅できなかった、想定していなかった操作によるエラー発生などをユーザーの行動データとともに収集することも可能です。
CloudWatch はこれら2つに対応しており、それぞれ、Amazon CloudWatch Synthetics と Amazon CloudWatch RUM を利用いただけます。
CloudWatch RUM は実際ユーザーのパフォーマンスデータを収集し、ブラウザやデバイスの種類、位置、ネットワークの接続性の問題などを把握できます。
収集されたデータは用意されたダッシュボードを利用することで、ページの読み込み順序や JavaScript / HTTP レスポンスのエラーなど、パフォーマンス問題に関する情報を簡単に把握できます。
また、問題が発生している場合には同じ問題の影響下にあるユーザーセッションを確認できるため、影響度合いをすぐに把握できます。
これにより、問題の優先順位を付けることが容易に行えるため、開発工数の最適化が行えます。
CloudWatch RUM. で収集したイベントデータは CloudWatch Logs に連携できます。
そのため、CloudWath Logs Insight や Contributor Insight などでの分析や、Grafana などの既存のオブザーバビリティソリューションで簡単に把握することができます。
もちろん、X-Ray と連携できるため、簡単にエンドユーザー体験とバックエンドアプリケーションをトレースで紐付け、問題発生時にはバックエンドを含めて原因調査を簡単に行えるようになっています。
こちらは CloudWatch RUM の動作イメージです。
ウェブアプリケーションに CloudWatch RUM を導入すると、ナビゲーションイベント、JavaScriptエラー、HTTPエラー、クライアントサイドのパフォーマンスメトリクスをCloudWatch RUMに自動で送信します。
その他にも、カスタムイベントなど独自のイベントを定義して送ることもできます。
メトリクス収集後の、問題の根本原因の特定や改善をするための可視化機能も提供されています。
CloudWatch RUM をサービスに導入するのはとても簡単です。
CloudWatch RUM. のアプリケーションモニターを作成するとコードスニペットをマネジメントコンソールから確認できます。
コードスニペット には TypeScript、JavaScript、 HTML のサンプルコードが用意されていますので、これをアプリケーションに挿入するだけで動作します。
CloudWatch RUM のクライアントソリューションは GitHub にも公開されていますので、詳細な機能を把握することができます。
CloudWatch Synthetics は Web アプリケーション と API を簡単に監視できるようにするサービスです。
実際のユーザートラフィックがなくても、所定のユーザー行動やエンドポイントを継続的にモニタリングすることができます。
また、想定外の問題があった場合に、CloudWatch アラーム などと連携し、問題をすぐに検知することができます。
また、X-Ray と連携できるため、簡単にエンドユーザーテストとバックエンドアプリケーションをトレースで紐付け、問題発生時にはバックエンドを含めて原因調査を簡単に行えるようになっています。
CloudWatch Synthetics の構成イメージも見てみましょう。
CloudWatch Synthetics Canary を作成すると、自動的にLambdaが作成され、実際には Lambda が定義したテストを実行します。
WEBアプリケーションの操作に対しては、Headless Chrome ブラウザを用いて操作が行われ、実行ログ やクリーンショット、HAR ファイル がS3バケットに保存されます。
Synthetics Canary のコンソール画面では、テストの成功、失敗の情報や、これらログやスクリーンショット、HARファイルの内容も確認できるようになっており、失敗の原因を調査しやすくなっています。
CloudWatch Synthetics には さまざまな Blueprint が用意されており、基本的なユースケースにおいては、ノーコードでテストを作成可能です。
例えば、Chrome 拡張 である Canary レコーダー を利用することで、実際に皆様が行うブラウザ操作からテストスクリプトを生成できます。
また、独自のスクリプトを利用することもできるため、既存のテスト資産を活用することができます。
ではここからは、CloudWatch RUM と CloudWatch Synthetics のユースケースについて紹介します。
あるサービスではリリースのテスト効率を上げるために、CloudWatch Synthetics Canary を利用し、ユーザーテストを自動化しています。
また、エンドユーザーの体験を把握するために CloudWatch RUM を導入しています。
今回、新しい機能をリリースしたところ、 CloudWatch RUM で Javascript エラーが検知されました。
また、CloudWatch Synthetics Canary の失敗を検知したため調査を開始しました。
このサービスでは フロントは Vue.js のフレームワークである Nuxt を利用しています。
そのため、RUM の導入は RUM Client である aws-rum-web パッケージを導入し、RUMのマネジメントコンソールで提示された コードユニスペクト をプラグインの形で実装しています。
サービスでは RUM イベントがどのユーザーからのものなのかを把握するために、RUM セッションに User ID (uid) を属性として追加しています。
これにより、問題発生時にどのユーザーへ影響を与えたかを簡単に把握できるようにしています。
では、トラブルシューティング行なっていきましょう。
まず、CloudWatch RUM で検知したエラーを確認してみます。
マネジメントコンソールでRUMアプリケーションモニターを選択し、エラータブを選択すると undefined
に対して id
プロパティを参照しようとしていることがわかります。
エラーを選択しするとエラーが発生したセッションを確認でいます。
セッションを選択するとセッション属性に追加した ユーザーIDからどのユーザーで起きているかを確認するようなこともできます。
次に、Javascriptエラーの詳細を確認してみます。
Javascriptエラーのスタックトレースは通常 minifyされているJavascriptファイルを指すため、問題発生箇所を特定することは時間がかかりますす。
今回は3月にリリースされた Source Map との連携を利用することで、 生の Javascript でのスタックトレースを確認できるようにしています。
これにより、「index.vue」ページのテーブルレイアウトコンポーネントのレンダリングでエラーが発生していることが分かりました。
この情報から実際のソースコードの エラー箇所を簡単に特定できます。
さらに、 Http requests
タブを確認すると、500エラーが起きていることが分かりました。
エラーの詳細を確認します。
すると、先ほどと同様に、どの ユーザーID
で起きたかを確認することができます。
また、Http requests
の トレースID
もわかりましたので、バックエンドも含め調査を行うことにしました。
X-Rayのトレースマップで先ほどのトレースIDで検索すると、APIサーバーのエラーと共にBedrockへのリクエストでエラーが起きていることが分かりました。
そのため、Bedrockへのリクエストに問題があることがここで分かりました。
このように、フロントエンドの情報とバックエンドの情報をトレースで紐付けることで、問題のあったセッションを簡単に調査できます。
次にCloudWatch Syntheticsを確認してみましょう。
すると、テストが途中から失敗していることがわかります。
また、失敗したステップの画面も確認することができます。
次に、Trace タブを開くと 500エラーが起きていることが分かました。
「Go to trace map」を選択すると、X-Ray トレースマップが開きます。
該当のトレースで APIサーバーへのエラーが確認できます。
さらに、APIサーバーからBedrock へのリクエストでエラーが起きていることが分かりました。
せっかくなので、X-Ray でさらにエラーを Dive Deep してみましょう。
トレースの詳細を確認すると、アプリケーションサーバーのログやセグメントの詳細情報を確認できます。
APIサーバーであるFargateのセグメントの詳細を確認すると、指定した Bedrock モデル に誤りある旨のメッセージがありました。
さらに、Bedrockへのリクエストから東京リージョンに対し、「us.anthropic.claude-3-7-sonnet」モデルを利用していることが原因と判明しました。
このように、CloudWatch Synthetics を利用することで、テストの失敗をトリガーに、問題のあった箇所を簡単に調査することができます。
最後に、さらに便利な機能として、Application Signals を活用することができます。
CloudWatch RUM と CloudWatch Synthetics. は Application Signals と連携させることが可能です。
さらに、去年リリースされた Transaction Search を有効化すると、既存の X-Ray トレースの情報から自動で Application Signals と連携させることができます。
これにより、事前に定義した SLO と CloudWatch Synthetics や CloudWatch RUM の状態を紐づけて、より簡単にサービス全体を把握できるようになります。
まとめです。
このセッションでは ユーザー体験モニタリングの重要性と 対応するサービスである CloudWatch RUM、CloudWatch Synthetics をご紹介しました。
また、CloudWatch RUM や CloudWatch Synthetics と X-Ray を利用した障害調査をご紹介しました。
皆様のサービスでまだユーザー体験のモニタリングを導入されていない場合は、CloudWatch RUM や CloudWatch Synthetics を試して頂ければと思います。
以上です。