🔍
cloudwatch logs insight で、お試しデータ集計
ことの始まり
プロダクトにて、「特定のページが閲覧された回数を計測したい」という要望がありました。
該当ページは 特定の API と 1対1 で紐づいていたため、上記要望だけなら API の呼び出し回数の統計情報だけで事足りました。
しかし、要望には以下の条件もありました。
- 特定の ID情報 で集計できること // ★重要
- 実装に時間をかけないこと
- 大規模なデータ分析基盤も、BIツールも不要
上記要望を満たせるような仕組みを探しました。
前提情報 : サービス構成
- API Gateway + Lambda のサーバレス構成
- Log は Cloudwatch Logs へ吐き出す
方針
Cloudwatch logs insight のログ集計を活用。
プログラム上から、以下のように Cloudwatch logs insight で集計する前提のログを吐き出す。
- 集計したいデータを含む、カンマ区切りの文字列を標準出力へ吐き出す
- Cloudwatch logs insight 側でログメッセージを加工
- ログメッセージをカンマで分割
- 集計
その後、 Cloudwatch logs insightで集計を行う。
- Cloudwatch logs insight 側でカンマを目印にログをパース
- 加工(&必要に応じて集計)
具体的な作業
- API リクエストを処理する Lambda 側で、集計用文字列を標準出力へ書き出す => 集計用文字列が Cloudwatch Logs へ書き出される
- Cloudwatch logs insight にて、集計用文字列を含むログを抽出する
- 抽出したログをCSVでダウンロードし、Excel等で集計する
集計用クエリを作成する
◆集計用文字列の例
console.log(`called_hogehoge_service,${some_id}`);
...
console.log(`called_fugafuga_service,${some_id}`);
◆クエリの例
fields @message
| filter @message like /called_hogehoge_service|called_fugafuga_service/
| parse @message "*,*" as logLine, some_id
| parse logLine '*INFO*' as null, request
| display request, some_id, @timestamp
その他構文は以下を参照。
所感
一度クエリの仕組みを作ってしまえば、あとはプログラム上に標準出力を仕込むだけで機能します。
手間は少なく、迅速に導入できたかと思います。
一方で、以下のように、汎用性が求められるような、ある程度の規模のサービスに向いているとは思えません。
- 複数サービスの利用傾向を把握したい
- より多くのカラムを扱いたい
このような要望に対して本記事の手法を導入すると、標準出力コードがあちこちに登場し、アプリケーションコードの汚染につながります。
この場合は、 API Gateway のログ + Kinesis Firehose + S3 のような、ログ集積の仕組みの開発が必要になるかと思います。
以上より、本記事の手法は、特定の使用方法に「特化」した、一時しのぎ的な手法に位置付けられると感じました。
Discussion