Amplify Logger から CloudWatchLogsに送信する の補足、或いはAmplifyで未ログイン状態でもAWSリソースを操作したいときの覚書
Amplifyを組み込んだアプリケーションからCloudWatchLogsにログイベントを送信するには amplify add auth
で認証関連の機能を組み込んでログ送信用のIAMロールを作る必要があると書いた。
amplify add auth
を実行すると対話的に認証設定ができるのだけど、デフォルトの設定だけでは未ログインのときにはAWS側の操作ができない状態になるので
このコマンドによって生成されたamplify
ディレクトリ配下のファイルを一箇所書き換えてあげる必要がある。
認証機能をつけない場合はだいたい適当に答える感じでOK。
ddd4143c63e0:/workspaces/amplify-dev# amplify add auth Using service: Cognito, provided by: awscloudformation The current configured provider is Amazon Cognito. Do you want to use the default authentication and security configuration? Default configuration Warning: you will not be able to edit these selections. How do you want users to be able to sign in? Email Do you want to configure advanced settings? No, I am done. Successfully added auth resource amplifyapp locally Some next steps: "amplify push" will build all your local backend resources and provision it in the cloud "amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
$ tree amplify
amplify
├── backend
│ ├── amplify-meta.json
│ ├── auth
│ │ └── amplifyapp1122334455
│ │ ├── amplifyapp1122334455-cloudformation-template.yml
│ │ └── parameters.json # これをいじる
この parameters.json
の allowUnauthenticatedIdentities
を true
に書き換える。
{ "identityPoolName": "amplifyapp1122334455_identitypool_00aabbcc", "allowUnauthenticatedIdentities": true, "resourceNameTruncated": "amplifyapp1122334455", "userPoolName": "amplifyapp1122334455_userpool_00aabbcc", "autoVerifiedAttributes": [ "email" ],
この変更をしてから amplify push
を実施すると以下のようにフェデレーテッドアイデンティティが作成される。
これでログインしていなくてもAWS側のリソースを扱うことができるようになる。
もしAuth関連のリソースが作成済の場合は amplify update auth
を実行し、Walkthrough all the auth configurations
を選んで
Allow unauthenticated logins? (Provides scoped down permissions that you can control via AW
S IAM)
を Yes
にする。
その他
どのファイルで設定しているのかわからなくてdiffで頑張って調べました。
Amplify Logger から CloudWatchLogsに送信する
Amplify Logger というのだから、ただのログ出力じゃなくて CloudWatchLogsにいい感じインテグレーションしてくれるものと思っていたら全然そんなことはなかった。
通常の使い方は前回の記事を見てみてください。
で、issueを漁ってみたら同じことを考えている人はいて、AWSCloudWatchProvider
を通してAmplify Loggerでログを出すだけで CloudWatchLogsにログを飛ばしてくれるようになるプルリクエストがあって、既にマージされていた。
マージされてはいるものの、公式のドキュメントには何も記載は無かったのでプルリクエストのコードとかコメントを読みつつ試してみた(ちなみに、かなり手間取った)
手順など
その前に余談
Amplify で Storage
とか Geo
を追加するときに、一緒に Auth
関連のリソースも作らされるの、何でなんだろう?って思ってたんだけど、AmplifyのアプリケーションからAWSのリソースを操作するためのロールが必要だから一緒に作られるんですね。
なので、ログイン機能とかが不要な場合は後述する unauthRole
だけ見ておけばいい。
(多分必要)ログ送信用のIAMロールを作る
amplify add auth
で認証情報を作る。ログイン機能とかは付けないので、認証情報に関する問いには雑に回答して大丈夫。
XXXX-authRole
と XXXX-unauthRole
の2つのロールが作られる。認証していなくてもログを送信したいので、コンソールから unauthRole
に以下のロールを付与する。
.amplify
配下に生成される parameters.json
をいじればロールも一緒に登録できそうだけども、今回はマネジメントコンソールから登録した。
DescribeLogGroups
DescribeLogStreams
CreateLogGroup
CreateLogStream
PutLogEvents
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:DescribeLogGroups", "logs:DescribeLogStreams", "logs:CreateLogGroup", "logs:PutLogEvents" ], "Resource": "*" } ] }
アプリケーションに Amplify Loggerを組み込む
プルリクのコメント欄にサンプルコードが記載されてたのでそれを参考に。
import { Amplify, Logger, AWSCloudWatchProvider } from 'aws-amplify'; import awsconfig from './aws-exports'; Amplify.configure({ Logging: { logGroupName: 'app-logs', logStreamName: `${process.env.VUE_APP_ENV}_LOGS`, }, ...awsconfig }); const amplifyLogger = new Logger('app-logs', "INFO"); Amplify.register(amplifyLogger); amplifyLogger.addPluggable(new AWSCloudWatchProvider());
ログを送信する
amplifyLogger.info("hello world!!");
これで送信されるはずなのだけど、こんなエラーになる。
Failed to load resource: the server responded with a status of 400 (Bad Request) ConsoleLogger.js?7aaf:127 [ERROR] 31:13.887 AWSCloudWatch - failure during log push: InvalidParameterException: 1 validation error detected: Value '' at 'sequenceToken' failed to satisfy constraint: Member must have length greater than or equal to 1
sequenceToken
がブランクなのでエラーになっている様子。
CloudWatchEventsにログを送信する場合は、sequenceTokenをパラメータに含めることでログの連続性を保つ仕組みになっているみたい。
この sequenceToken
の解決自体は AWSCloudWatchProvider
でやってくれているようなのだけど、最初のログ送信に失敗してしまう。
プルリクのコメントを見てみると同じ問題に遭遇した人がいて、曰く
After adding an event to the stream manually, the sequenceToken value was populated correctly and subsequent log calls worked without issue.
ログストリームの中身が空なのが良くないみたい。
ということで、マネジメントコンソールから適当なログイベントを一個登録してみた。
このあとアプリケーションからログを出力してみると・・・!
ここまで長かった。。。
まとめ
AmplifyからカジュアルにCloudWatchLogsにログを送ることができるようになるとアプリケーションの監視やデータ分析がかなり便利になると思う。
エラーの収集はもとより、ユーザーの操作履歴などを CloudWatchLogs => S3 に溜めておいてS3 SelectとかAthenaで分析するみたいな使い方ができると絶対楽しい。
(ユーザーの行動分析は amplify analytics
があるけど、あれは Amazon Pinpointとのインテグレーションなので、CloudWatchにログを飛ばしてざっくり検証してみたいな〜みたいのとは使い所が異なるという認識です)
Amplify Loggerの使い方について
AWS Amplifyの utilitiesに loggerがある。
https://docs.amplify.aws/lib/utilities/logger/q/platform/js/
使い方
import { Logger } from 'aws-amplify'; const logger = new Logger("my-logger"); logger.warn("warning message");
デバッグコンソールにはこのように出力される。
[WARN] 56:32.69 my-logger - warning message
注意点としては、インスタンスに指定されているレベル以上のログしか出力されないということ。 ログレベルは上から順に以下のようになっている。
- ERROR
- WARN
- INFO
- DEBUG
- VERBOSE
デフォルトのログレベルはWARN
。
例えば、以下のようなloggerがある場合、WARN
・ERROR
のログでないと出力されないので logger.info
を実行してもログは出力れない。
import { Logger } from 'aws-amplify'; const logger = new Logger("my-logger"); logger.info("this is info message"); // これはconsoleに出力されない
INFOレベルのログを出したい場合は以下のようにインスタンス生成時にログレベルを指定しておく必要がある。
import { Logger } from 'aws-amplify'; const logger = new Logger("my-logger", "INFO"); logger.info("this is info message"); // これならconsoleに出力される続きを読む
Rubyで動的クラスを使ったクラス設計を考える
地元鉄道の時刻表や駅の情報を返すAPIを考えている。 (Alexaのスキルを作りたくて、そのためのデータを返すAPIがほしいのだった)
欲しいのは、駅の情報(info)・時刻表(timetable)・運賃(fare)。
Akaden
というのは地元鉄道の愛称。正式名称は遠州鉄道、略して遠鉄。車体が赤いので市民は「赤電」と呼んでいる。
駅名をメソッドにする
::Akaden::Info.shin_hamamatsu => { name: '新浜松', address: '' , ...}
::Akaden::Timetable.kamijima => [ { detection: 'upto', week: 'weekday', time: '10:35' }, ... ]続きを読む
Amplify Geo for AWS Amplify を試してみる
AWS Amplify に AWS Location Serviceのリソースを作成してくれる Amplify Geo のデベロッパープレビューが公開されたので試してみた。
できたものはこちらです。
amplifygeo-20210929141446-hostingbucket-dev.s3-website-ap-northeast-1.amazonaws.com
実は AWS Location Serviceが出た頃に Location Service は試していて、以下のような簡単なアプリケーションを作っていたのだけど、
master.d1h878o7did8z6.amplifyapp.com
Amplify Geo を使うとこんな感じの機能をもっと簡単に作れるようになる。
続きを読むAlexaスキルのindex.js の見通しを良くする
Alexa Hostedで自動生成されるコードは index.js
にすべてのインテントハンドラのコードが実装されていてすこぶる見通しが悪い。
そこでハンドラごとに handers
配下に切り出してみた。
毎回これやるの面倒だな。。