ForgeVision Engineer Blog

フォージビジョン エンジニア ブログ

Amazon Athena で CloudFront のログを集計する

「燃えろ!!俺の小宇宙(コスモ)」
心は小4、体は中年。3 月生まれ ピスケスのアフロディーテ・尾谷です。

テレワークで動けないのを理由に食っちゃ寝を繰り返してとうとう体重が 86kg を超えました。「コスモを燃やす前に体脂肪を燃やさないと。。 」

ということで今日は Amazon Athena で CloudFront のログを集計する方法をご紹介したいと思います。

Amazon Athena とは

Amazon S3 内のデータを標準 SQL を使用して簡単に分析できます。
Athena はサーバーレスなのでインフラストラクチャの管理は不要です。
実行したクエリに対してのみ料金が発生します。

Amazon Athena(SQL を使用した S3 でのデータクエリ)| AWS

Athena ってお高いんでしょ?

Athena は SQL がサクサク実行できるのと、一瞬で数百メガのスキャンをしてしまうため、気づいたら高額な利用料になっていたという「しくじり案件」を思い浮かべる方が多いかもしれませんが、

www.itmedia.co.jp

Athena の料金は 1TB あたり 5.00 USD で 10MB 単位で課金されるため、本記事でご案内するような手動検索においては消費した容量も可視化されるので安心してご利用いただけるのではないかと思います。

先月 3GB クエリして、0.01 USD かかりました

Lambda や EventBridge などを使って自動処理する場合は、考慮漏れがないか綿密な設計が必要です。

CloudFront ログの設定

CloudFront のログは、ディストリビューションの [一般] タブから [編集] ボタンをクリックして、

ページ下部にある 標準ログ記録 の項目をオンにして設定します。
設定前に予め s3 バケットを用意しておきます。

すると、エッジローケーションごとに .gz ファイルで s3 バケットにアクセスログが格納されていきます。

この .gz ファイルを一つずつダウンロードして解凍して、テキストエディタで開くと以下のようなアクセスログが確認できます。

以上が、CloudFront のログの出力方法です。

アクセスログの出力を オン にすると、サイトでエラーが多発したときや、ダウンしたとき、DoS 攻撃などの有事の際に解決の糸口となります。
ただ、s3 バケットから複数の .gz ファイルをダウンロードして、それぞれのファイルを解凍してテキストファイルを結合して、場合によってはスプレッドシートや Excel に貼り付けてフィルターして...と手動で加工する方法だと手間がかかります。  
ケースによっては本記事で紹介する Athena の方が効率的に検索ができます。

クエリ結果を格納する s3 バケット

ここから Athena の操作をご説明していきますが、まず Athena はクエリ結果を保存するためのバケットを設定する必要があります。
これを設定しないとクエリが実行できません。設定手順は以下の通りです。

  1. 結果保存用の s3 バケットを作成します。
  2. Athena コンソールにアクセスして、[設定] タブをクリック、[管理] ボタンをクリックします。
  3. s3 バケットを指定します。

[ s3 を参照 ] ボタンをクリックすると、

s3 バケットがエクスプローラー的に GUI で選択できて便利です。

データベース、テーブルを作成

Athena を使って CloudFront のログをクエリするに、両者のカラム情報を一致させたテーブルを作成する必要があります。 公式ドキュメントにコピペして使える SQL コードがあるので、

docs.aws.amazon.com

貼り付けます。
なお、本記事は CloudFront のログを集計するのがテーマですが、ALB ログの場合は以下の公式ドキュメントを参照ください。

docs.aws.amazon.com

s3 バケット内すべてを検索すると場合によっては対象が多くなってしまうので、LOCATION で絞ります。

例えば、複数のディストリビューションを一つのバケットでプレフィックスごとに分けて格納している場合は

LOCATION 's3://バケット名/ディストリビューション名/'

という形でディストリビューション単位で絞ると検索する範囲がグッと狭くなります。
本記事は CloudFront ですが、ALB のログの場合は、yyyy/mm/dd という形でさらにプレフィックスを絞ることも可能です。

[実行] ボタンをクリックします。
すると、テーブルが出来上がります。

テーブル名の右側にあるオプションボタンをクリックして、テーブルをプレビューを選択します。

すると、クエリに SQL が発行されます。
limit10 がついているので、10 行だけ出力されます。

あとは実行ボタンを押せば結果が表示されます。
スキャンしたデータに消費した容量が表示されます。
その月の消費容量が月末に請求されます。

ログの集計

以下のような SQL を実行すると、リクエスト元の IP アドレスごとに合計した集計できます。

SELECT request_ip, count(*) AS num
FROM "データベース名"."テーブル名"
WHERE date BETWEEN date 'yyyy-mm-dd' AND date 'yyyy-mm-dd'
GROUP BY 1
ORDER BY 1;

以下のように、request_ip (リクエスト元 IP アドレス) ごとに num (カウント) が表示されます。

表示結果は実際のアドレスではありません

まとめ

いかがだったでしょうか。
お試しいただいた方は、聖闘士も驚愕する集計スピードにびっくりされたのではないでしょうか。
Athena は出力先のバケットを設定しておかないと動かないため、僕のようにぽちぽちして利用方法や感覚を掴む方は取っ付きにくい印象ですが、慣れるとすごく便利です。
まだ利用されていない方や、使うのをためらっている方がいらっしゃったら、是非使ってみてください!