1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Real-User Monitoring for Amazon CloudWatch (RUM) をCDKで設定し、ReactのSPAでページ遷移時のイベントを取得したメモ

Posted at

概要

AWSでGoogle Analyticsのようなログ収集ができるCloudWatch RUM(Realtime User Monitor)を試してみる。
CDKで作成したいが、L2はまだ未対応の模様(2022/12/31)。L1で作成できるか試してみる。

ReactのSPAでのページ遷移時にイベントが送信されるところまで確認する。

ソースコード:CDK
ソースコード: client - rum
ソースコード: client - router

CDK構成

cdk/lib/cloudfront-stack.ts
import * as core from 'aws-cdk-lib'
import * as s3 from 'aws-cdk-lib/aws-s3'
import * as cf from 'aws-cdk-lib/aws-cloudfront'
import * as iam from 'aws-cdk-lib/aws-iam'
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins'
import * as cognito from '@aws-cdk/aws-cognito-identitypool-alpha';
import { Construct } from 'constructs'
import { basePath } from '../constants/paths'
import { aws_rum as rum } from 'aws-cdk-lib';

interface Props extends core.StackProps {
  bucketName: string
  identityName: string
  defaultCachePolicyName: string
  distributionName: string
  projectNameTag: string
}

export class AWSCloudFrontStack extends core.Stack {
  constructor(scope: Construct, id: string, props: Props) {
    super(scope, id, props)
    // CloudFront オリジン用のS3バケットを作成
    const bucket = this.createS3(props.bucketName)
    // CloudFront で設定する オリジンアクセスアイデンティティ を作成
    const identity = this.createIdentity(bucket, props.identityName)
    // S3バケットポリシーで、CloudFrontのオリジンアクセスアイデンティティを許可
    this.createPolicy(bucket, identity)
    // CloudFrontディストリビューションを作成
    const distribution = this.createCloudFront(bucket, identity, props)

    // 確認用にCloudFrontのURLに整形して出力
    new core.CfnOutput(this, `${props.distributionName}-top-url`, {
      value: `https://${distribution.distributionDomainName}/${basePath}`,
    })

    new core.CfnOutput(this, `${props.distributionName}-distribution-id`, {
      value: `${distribution.distributionId}`,
    })
+    this.createRUM(distribution.distributionDomainName, props.env!.account!, props.env!.region!);
    core.Tags.of(this).add('Project', props.projectNameTag)
  }

  private createS3(bucketName: string) {
    // s省略
  }

  private createIdentity(bucket: s3.Bucket, identityName: string) {
    // 省略
  }

  private createPolicy(bucket: s3.Bucket, identity: cf.OriginAccessIdentity) {
    // 省略
  }

  private createCloudFront(
    bucket: s3.Bucket,
    identity: cf.OriginAccessIdentity,
    props: {
      defaultCachePolicyName: string
      distributionName: string
    },
  ) {
   // 省略
  }


+  private createRUM(domain: string, accountId: string, region: string) {
+    const { identityPool, role } = this.createIdentityPool();
+    const cfnAppMonitor = new rum.CfnAppMonitor(this, 'MyCfnAppMonitor', {
+      domain,
+      name: `rum-for-croudront-${domain}`,
+      appMonitorConfiguration: {
+        identityPoolId: identityPool.identityPoolId,
+        guestRoleArn: role.roleArn,
+        // サンプルレート。デフォルトは0.1(10%)。
+        // 1にするとセッションの100%をモニタする。高くするほどコストがかかるので注意。
+        // 今回は動作確認のため1を設定
+        sessionSampleRate: 1,
+      },
+    });
+    // CognitoIdのIAMロールにRUMへの送信権限を付与
+    role.addToPrincipalPolicy(new iam.PolicyStatement({
+      effect: iam.Effect.ALLOW,
+      actions: ['rum:PutRumEvents'],
+      resources: [`arn:aws:rum:${region}:${accountId}:appmonitor/${cfnAppMonitor.name}`],
+    }));
+    return cfnAppMonitor
+  }


+  private createIdentityPool(): {
+    identityPool: cognito.IIdentityPool
+    role: iam.IRole,
+  } {
+    const identityPool = new cognito.IdentityPool(this, 'IdentityPool', {
+      allowUnauthenticatedIdentities: true,
+    });
+    return { identityPool, role: identityPool.unauthenticatedRole };
+  }


}

デプロイ

image.png

RUMがデプロイされたことをコンソールから確認できた。

アプリケーションに反映。

コンソールの「JavaScriptを表示」からスニペットを取得する。
reactを参考に設定。

client/src/domain/rum/aws-rum.ts
import { AwsRum, AwsRumConfig } from 'aws-rum-web';
let cwr: AwsRum | null = null;
try {
  const config: AwsRumConfig = {
    sessionSampleRate: 1,
    guestRoleArn: "arn:aws:iam::00000000:role/AWSCloudFrontStack-IdentityPoolUnauthenticatedRole-1U7PMD1IH60RX",
    identityPoolId: "ap-northeast-1:00000000-0000-0000-0000-xxxxxx",
    endpoint: "https://dataplane.rum.ap-northeast-1.amazonaws.com",
    telemetries: [],
    allowCookies: false,
    enableXRay: false
  };

  const APPLICATION_ID = '00000000-0000-0000-0000-xxxxxxxxxx';
  const APPLICATION_VERSION = '1.0.0';
  const APPLICATION_REGION = 'ap-northeast-1';


  const awsRum: AwsRum = new AwsRum(
    APPLICATION_ID,
    APPLICATION_VERSION,
    APPLICATION_REGION,
    config
  );
  cwr = awsRum

} catch (error) {
  // Ignore errors thrown during CloudWatch RUM web client initialization
}
export const getRum = () => {
  return cwr
}
client/src/routes/RoutsApp.tsx

const App: React.FC = () => {
+  const location = useLocation()


+  React.useEffect(() => {
+    if (import.meta.env.DEV) return
+    const cwr = getRum()
+    if (!cwr) return
+    cwr.recordPageView(location.pathname)
+  }, [location])

  return (
    <Routes>
      <Route path="/admin" element={<AdminRoute />}>
        <Route path="/admin/top" element={<Top />} />
      </Route>
      <Route path="/private" element={<PrivateRoute />}>
        <Route path="/private/top" element={<Top />} />
      </Route>

      <Route element={<PublicRoute />}>
        <Route path="/" element={<Redirect />} />
        <Route path="/login" element={<Login />} />
        <Route path="/test" element={<Test />} />
      </Route>
    </Routes>
  )
}

デプロイ

クライアントの確認

RUM用の通信が行われていることを確認
image.png

コンソールの確認

反映までは少し時間がかかる。
イベントが送信されることを確認できた。

image.png

参考

AWS 公式 - CloudWatch RUM を使用する
新機能 – Amazon CloudWatch RUM をご紹介
One Observability Workshop - 新しい CloudWatch RUM アプリケーションを作成する
CloudWatch新機能増えすぎ問題。Synthetics? RUM? Evidently?? ... Next.jsでの設定例
One Observability Workshop をやってみた
アプリケーションのクライアント側のパフォーマンスをモニタリングする Amazon CloudWatch RUM の紹介
CloudWatch RUMでReactアプリのパフォーマンスやエラーのモニタリングを試してみた

CloudWatch RUM App Monitor with AWS CDK ... cfnCognito sample
cdk - CfnAppMonitor
AWS CDKでデプロイ時の値を使ってフロントエンドとバックエンドを一発でデプロイできるようになったので試してみる
AWS CDKでWebフロントエンドをデプロイする3つの方法
github - cdk-rfc - RFC L2 AppMonitor
github - cdk - L2 AppMonitor ... v1 sample

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?