はじめに

AWS Amplifyで構築しているReactアプリケーションのログをCloudWatch Logsに送信してみました。

動作確認のバージョン

  • Amplifyのバージョン: 12.8.2

手順

1. 認証基盤の設定確認

今回のシステムはログイン機構を設けていないため、未認証のユーザーによるCognito IDプールを通じてAWSリソースにアクセス(ログを記録)できるようにします。
既に構築済みのシステムの場合、amplify/backend/auth/{appName}/cli-inputs.jsonで確認可能です。

{
  "version": "1",
  "cognitoConfig": {
    "identityPoolName": "xxxxxxxx",
    "allowUnauthenticatedIdentities": true, ← 未認証のユーザーによるCognito IDプール経由のAWSリソースアクセス
    "resourceNameTruncated": "xxxxxxxx",

2. AmplifyプロジェクトのIAMリソースの上書き

Amplify CLIを使用して、Amplifyプロジェクトの未認証のIAMロールに対してCloudWatch Logsに対する権限を追加します。

$ amplify override project

コマンドを実行後、amplify/backend/awscloudformation/override.tsが生成されるので以下のように編集します。
未認証のロール(unauthRole)に対してCloudWatch Logsの権限を付与しています。

import { AmplifyRootStackTemplate,
    AmplifyProjectInfo
} from "@aws-amplify/cli-extensibility-helper";

export function override(
    resources: AmplifyRootStackTemplate,
    amplifyProjectInfo: AmplifyProjectInfo
) {
  const unauthRole = resources.unauthRole;
  const projectName = amplifyProjectInfo.projectName
  const env = amplifyProjectInfo.envName
  const policyName = `amplify-${projectName}-${env}-UILoggerPolicy`

  const basePolicies = Array.isArray(unauthRole.policies)
    ? unauthRole.policies
    : [unauthRole.policies];

    unauthRole.policies = [
    ...basePolicies,
    {
      policyName: policyName,
      policyDocument: {
        Version: "2012-10-17",
        Statement: [
          {
            Resource: "arn:aws:logs:*:*:*",
            Action: [
                "logs:CreateLogStream",
                "logs:DescribeLogGroups",
                "logs:DescribeLogStreams",
                "logs:CreateLogGroup",
                "logs:PutLogEvents"
            ],
            Effect: "Allow",
          },
        ],
      },
    },
  ];
}

ファイル保存後、バックエンドリソースをデプロイします。

$ amplify push

3. ロガーの設定

ReactアプリケーションのソースコードにAmplifyのLogger、AWSCloudWatchProviderを追加して、ログをCloudWatch Logsに送信できるように設定します。

...
import { Amplify, Logger, AWSCloudWatchProvider } from 'aws-amplify';
import awsExports from "./aws-exports";

// Amplifyの設定
Amplify.configure({
  Logging: {
    logGroupName: 'testLogGroup',
    logStreamName: `log-stream-${new Date().toISOString().split('T')[0]}`,
  },
  ...awsExports
});

// Loggerインスタンスの作成
const logger = new Logger('appName', 'DEBUG');
// Loggerの登録
Amplify.register(logger);
// CloudWatchプラグインの追加
logger.addPluggable(new AWSCloudWatchProvider());

...

  logger.info('ログ出力')

実装後の確認

Reactアプリケーションにアクセスし、CloudWatch Logsを確認するとログが出力されていることを確認できました。

感想

比較的手軽にフロントエンドの操作をロギングできるので、便利だと思いました。
クライアントサイドでロギング設定を管理しているため、セキュリティ面やパフォーマンスへの影響は気にしておいた方が良さそうです。
また、デフォルトのログ出力だとDateオブジェクトのフォーマットが分/秒/ミリ秒になっているので、必要に応じてカスタマイズを検討してもいいかもしれません。

参考