🔍

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 側でカンマを目印にログをパース
  • 加工(&必要に応じて集計)

具体的な作業

  1. API リクエストを処理する Lambda 側で、集計用文字列を標準出力へ書き出す => 集計用文字列が Cloudwatch Logs へ書き出される
  2. Cloudwatch logs insight にて、集計用文字列を含むログを抽出する
  3. 抽出したログを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