静的WEB via CloudFrontにRUMを入れてモニタリングしてみる

# TL;DR
re:Invent 2021で発表されたCloudWatchの新機能[「CloudWatch RUM(Real-User Monitoring)」](https://aws.amazon.com/jp/blogs/aws/cloudwatch-rum/)を使ってCloudFrontで配信中のNext.js製WEBをモニタリングしてみました。

# CloudWatch RUM is 何？

 以下、[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-RUM.html) より引用。

> CloudWatch RUM を使用すると、現実的なユーザーモニタリングを実行できます。ウェブアプリケーションのパフォーマンスに関するクライアント側のデータを、ほぼリアルタイムで実際のユーザーセッションから収集し、それを表示できます。ページの読み込み時間、クライアント側のエラー、およびユーザーの活動などのデータを、視覚化および分析することが可能です。この表示機能では、すべてのデータを集約的に見ることができ、同時に、顧客が使用しているブラウザやデバイスに関する詳細も確認できます。

はい、WEBのアクセス解析サービスですね。
他社サービスだと、[Google Analytics](https://marketingplatform.google.com/intl/ja/about/analytics/)や[Adobe Analytics](https://business.adobe.com/jp/products/analytics/adobe-analytics.html)があります。アクセス解析サービスとしては他社と比較すると後発ですが、本機能の登場でAWSでホスティング〜アクセス解析まで一気通貫で実現できるようになりました。「WEBはAWSでホスティングしているけど、アクセス解析は他社サービスを利用」といった具合の泣き別れも解消できるはず！


# Next.js製WEBに導入してみる

## 全体構成
![Screen Shot 2022-02-14 at 15.43.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/f58c71e2-3a27-11dc-486c-bf0a4fdb5c62.png)


CloudWatch RUMでは、S3に格納している静的コンテンツにRUM用JavaScriptを仕込んでおき、クライアントからのリクエスト時にトラッキング用スクリプトが発火、CloudWatch RUMに対してデータを投げ込む、という仕組みです。


## 1. アプリケーションモニターを追加
CloudWatchコンソールからRUMの設定をしていきます。デフォ設定のままでトレースできます。優しい。

![Screen Shot 2022-02-14 at 15.47.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/539a30bd-3bb5-d797-661b-87dbc42bc857.png)
![Screen Shot 2022-02-14 at 15.48.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/3dc42765-1464-2daa-651a-24637d58cad5.png)
![Screen Shot 2022-02-14 at 16.09.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/40f9d6d1-02eb-73a4-3250-98e9d6b92d9d.png)
![Screen Shot 2022-02-14 at 16.11.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/6277070f-a4ae-3f26-058b-ec89e37c5171.png)

**設定項目を何個かピックアップ**
- **データストレージ**
    - 「CloudWatch RUM により収集されたエンドユーザーデータは、30日間保持された後で自動的に削除されます」と公式ドキュメントに記載が。30日以上前のデータに遡及して分析したい場合はこのチェックをONにしておきましょう。CloudWatchLogsにデータを保存してくれます。（CWLogs側の期限設定も忘れずに）
- **承諾（Authorization）**
    - 日本語訳に違和感ありですが、原文だとAuthorizationです。Cognito IDプールを利用してクライアントからのデータ送信を許可する模様。[Cognitoでは無認証のIDがサポートされており](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/switching-identities.html#switching-identities-1.javascript)、この機能を利用することでクライアント側にてCloudWatch RUMへのデータ送信が許可されたIAMロール(※)を引き受けることが可能となります。「新しいIDEAプールを作成する」を選択でOK。
    -  (※) ``rum:PutRumEvents`` の``Allow``権限が付与されます
- **アクティブトレース**
    - X-Rayトレースを有効化することができます。有効化することでセッション中の``XMLHttpRequest``および``fetch``リクエストをトレースする事が可能になり、RUMダッシュボード、CloudWatch ServiceLensコンソール、X-Rayコンソール上で確認できるようになります。今回はONに設定を変更。設定項目「セッションサンプル」で100%指定しているので、今回の場合だと全セッショントレース対象となります。
    

## 2. スニッペスト取得

必要項目の入力が完了すると、コードスニッペストが表示されます。これを控えて静的コンテンツに貼り付けます。（控えるの忘れても後で再確認可能）
![Screen Shot 2022-02-14 at 16.43.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/3870def0-9e01-9a7f-26bc-afd35c546e94.png)

## 3. スニッペストを埋め込み

ぶっちゃけ、ここが一番苦労しました。。
Next.jsでは``_app.tsx``に全ページ共通の項目を記載するのですが、``<Head>``タグの中にスクリプトを埋め込むとエラーが複数発生。
![Screen Shot 2022-02-14 at 16.51.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/c898dd4f-f78e-4a55-dc00-aee434ee4341.png)

~~``SyntaxError: '}' expected.`` だの ``Cannot find name 'sessionSampleRate'.ts``、等 エラー吐きまくりでSSGできませんでした。
結局、静的コンテンツを生成した後の生HTMLファイルに先程のスニッペストを貼り付けてデプロイをすると問題なく動きました。(フロント強者の方、是非良い方法を教えていただきたく、、！)~~ 
Scriptタグで下記画像のように埋め込んであげるとビルドできました。

![Screen Shot 2022-02-17 at 2.06.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/b4c33ea4-f5a3-0b1e-4b16-5baaca18990d.png)

# ダッシュボードを眺めてニヤニヤする
ダッシュボードに表示できる物が多すぎるので、全量は紹介しきれませんが、幾つか面白いものをピックアップしてみます。

## パフォーマンス>リソースリクエスト
各種リソース取得にかかったロード時間を表示することが可能です。
WEBページの表示が遅いんだけど！といった際に、どこがボトルネックになっているのかを確認することができます。
（今回のパターンだと、RUM実行用スクリプトの取得に一番時間がかかっています）
![Screen Shot 2022-02-14 at 17.35.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/95c65c4c-9015-a948-5006-4e2df39942b2.png)

## パフォーマンス>経時的なリソースリクエスト
リクエスト数を可視化することができます。今回の例だとCloudFront＋S3なのであまり考慮する必要はありませんが、EC2やECSでWEBホスティングをしている場合、リクエスト数が多い時間帯は事前にスケールアウトしておく、といったリソース戦略を実現することが可能となります

![Screen Shot 2022-02-14 at 17.52.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/02b8ee0d-6af7-0602-a1fd-c5402d2caf35.png)

## ユーザージャーニー
ページ遷移をマッピングし、ドロップオフ（=WEB離脱）を確認することができます。
例えば複数ページにまたがるフォームを実装している際に、どのページで離脱したか？を確認することでページ構成を最適化するためのヒントとして活用、コンバージョン率の向上を期待できます。
![Screen Shot 2022-02-14 at 17.43.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/6aca9ef4-2859-26a0-7ce2-82b8e69bd51f.png)

## ブラウザとデバイス
WEBにアクセスしてきたブラウザ内訳を確認することができます。
クライアントから飛んでくるUserAgentを元に集計して統計を出してくれます。
エンタープライズのシステムだと、エンドユーザに対して動作保証ブラウザを設定していたりしますが、その際の保証ブラウザ×バージョン選定に役立てることができそうですね。IE対応しなきゃいけないんだよ！といってくる人にはこの画面を見せつけましょう。
![Screen Shot 2022-02-14 at 19.22.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290494/3cb95b1b-ead6-31f7-46b7-d47aeaa52dcd.png)

# まとめ
とうとうAWS純正のWEBアクセス解析サービスが登場したので使ってみました。
他社製品と比べても利用できる機能は遜色なく、ようやくAWSだけでWEB監視やトレースを完結させることが可能となりました。
もちろんAWSの他サービスとの連携も可能で、RUMのメトリクスを監視、CloudWatch Alarmを仕込んで閾値を超えたらLambdaやSlackをフック といった使い方も可能です。外形監視のCloudWatch Synthetics等も組み合わせるとより信頼性の高いWEB運用が可能になるのではないでしょうか。

# 備考
GoogleAnalyticsについて調べていると、日経新聞にこんな記事がありました。
[米にGoogleアナリティクスの情報送信　仏当局「違法」](https://www.nikkei.com/article/DGXZQOGR122SG0S2A210C2000000/)
フロントエンド界隈では3rdパーティ製Cookieも制限されたことですし、そのうちWEBアクセス解析ツールも規制されるのか..!?