[アップデート] Amazon CloudFront でリアルタイムなログ出力が可能になりました

CloudFrontのログをすぐに確認したいんや!
2020.09.01

本日のアップデートにより Amazon CloudFront でリアルタイムログの取得が可能となりました。

リアルタムログが取得できると何が嬉しいの?

ログ出力までの時間

従来の CloudFront アクセスログは通常は数分以内に出力されますが、ベストエフォートではあるため公式ガイド上では 1 時間以内 または 最大で 24 時間 遅れることもあると記載されています。

アクセスログを即時に確認したい、リアルタイムログ分析を行いたい場面では、このログ出力までの時間差にヤキモキされたユーザーも居られるのではないでしょうか。

リアルタイムログは Kinesis Data Streams を使用し、S3、Amazon Redshift、Amazon Elasticsearch Service、またはサードパーティのログ処理サービスにログを配信することが出来ます。リクエストから数秒以内にアクセスログ出力が可能となりましたので CloudFront のアクセスログをもとにリアルタイムなダッシュボードを作成し、アラート検知、異常調査といった運用が可能となります。

ログ出力がより詳細に

従来のアクセスログに比べて、より詳細な内容を出力することが可能です。例えば従来のアクセスログではビューワーリクエストの HTTP ヘッダーは限られた内容しか出力することが出来ませんでしたが、リアルタイムログではエッジサーバーがビューワーへの応答で送信した HTTP ヘッダーなども確認することができます。(取得可能なログの内容は、公式ガイドを参照ください)

パーティション分割やログ変換で効率的にログ分析

従来のアクセスログは指定した S3 バケット直下にログファイルが出力されます。Athena などで分析する際に特定の月や日で絞り込んでクエリを投げたいときに、ちょっと不便でした。

$ aws s3 ls cm-marumo-cflog-test
                           PRE /
2020-08-31 20:34:32        853 E1MDQG7G4UXGMH.2020-08-31-20.06cd3344.gz
2020-08-31 23:59:32        545 E1MDQG7G4UXGMH.2020-08-31-23.562a0ef5.gz
2020-08-31 23:54:32        528 E1MDQG7G4UXGMH.2020-08-31-23.bd5b746c.gz
2020-09-01 00:14:32        535 E1MDQG7G4UXGMH.2020-09-01-00.1b5517b7.gz

リアルタイムログは Kinesis Data Streams を介して出力します。コンシューマーとして Kinesis Data Firehose を使うことで YYYY/MM/DD/HH のようなパーティション分割が簡単に出来ます。加えて Parquet などのフォーマット変換もできますので、効率的にログ分析することが出来るようになりますね。

料金

  • Kinesis Data Streams の料金
    • リアルタイムアクセスログは Kinesis Data Streams に出力されます
  • リアルタイムログ料金
    • 1,000,000ログ行ごとに $0.01

やってみる

事前準備

今回は S3 にリアルタイムログを出力したいので、以下のリソースを事前に作成しておきます。

  • Kinesis Data Streams
    • 今回は検証のためシャード数 1 で作成しています
  • Kinesis Data Streams コンシューマー
    • CloudFront がサポートするのは Kinesis Data Streams への出力までです。Kinesis Data Streams に入ったログを取り出すためのコンシューマーは別途、必要です
    • 今回は Kiesis Data Firehose で S3 に出力するように設定していますが、最短のインターバルが 60 秒ですので、もっと短時間で処理したい場合は別のコンシューマーを採用してください

設定方法等については suzuki の記事を参照ください!

リアルタイムログ設定

CloudFront の管理コンソールを開くと [Telemetry] - [Logs] という項目が増えています。Real-time log configurations タブを開き、Create Configuration をクリックします。

Configuration settings ではサンプルレート、ログ出力するフィールド、Kinesis Data Streams のエンドポイント、CloudFront が Kinesis Data Streams に出力するための IAM ロールを設定します。

今回は必ずログ出力させるためにサンプルレート 100 を設定していますが、実環境で利用の場合はログ量が増えすぎて Kinesis Data Streams でスロットリングが発生する可能性がありますので注意ください。アクセス傾向を分析する目的であれば、すべてのログを必ずしも取得する必要はないかと思いますので、分析するにあたって十分なサンプルレートまで下げることでコストも抑えることが出来るでしょう。(不要なログフィールドを削ることも効果的です)

Distribution で取得対象のディストリビューションおよび、Cache behavior を設定し、Create configuration をクリックします。ひとつのリアルタイムログ構成に複数のディストリビューション、複数の Cache behavior を紐付けることも可能です。

設定は以上です。

ログ確認

以下のような TEST ヘッダーを付与したリクエストを送りました。

$ curl -I -H 'TEST:logtest' dju74f8c9avbq.cloudfront.net
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 34
Connection: keep-alive
Date: Mon, 31 Aug 2020 20:28:55 GMT
Last-Modified: Fri, 05 Jun 2020 22:45:36 GMT
ETag: "7ac80a3561ea29c1d841e6de60edef05"
Accept-Ranges: bytes
Server: AmazonS3
X-Cache: Hit from cloudfront
Via: 1.1 fc06711606c1d4d320aca2fe6bfea503.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: NRT51-C3
X-Amz-Cf-Id: vQi2pOsjGC8TcTaE_81jf3GM0DALVfr43J7a4L_Y3GbeshhkN1NNwg==
Age: 13396

~ $ date
2020年 9月 1日 火曜日 09時12分16秒 JST

従来ログの確認

まずは従来のアクセスログを確認します。リクエストから出力までに約 2分16秒 掛かっています。ベストエフォートですので、もちろんもっと遅くなる場合もあります。

$ aws s3 ls cm-marumo-cflog-test                           
                PRE /
2020-09-01 00:14:32        535 E1MDQG7G4UXGMH.2020-09-01-00.1b5517b7.gz

ログの内容は以下のようになります。TEST ヘッダーに関するログは見当たりません。

リアルタイムログの確認

次にリアルタイムログを確認します。今回は Kinesis Data Firehose の最短インターバル時間(60 秒)後の出力になっていますが、実際にはリクエストの数秒後に Kinesis Data Streams で取得できる状況になります。

$ aws s3 ls cm-marumo-cflog-test/realtime/2020/09/01/00/
2020-09-01 00:13:17        407 cf-logs-2-2020-09-01-00-12-14-b2f4571f-b5d7-4791-a9fa-3fb233b62467

リアルタイムログの内容は以下のようになります。cs-headers(後列から3番目)curl で付与したヘッダーと値 TEST:logtest が記録されていることが判ります。従来のアクセスログよりも詳細な内容が確認可能であることが判りますね!

検証は以上です!

注意点

CloudFront のリアルタイムログが Kinesis Data Streams の処理レコード数を超えるとスロットリングが発生します。そのため、アクセスログ量をもとにしたシャード数の設計が必要となります。

シャード数の算出方法

  1. CloudFront 使用状況レポート、または CloudFront Requests メトリクスをもとに 1 秒あたりのリクエスト数を確認
  2. 単一のリアルタイムログレコードサイズを決める
    • 一般的に約 500 バイトですが、すべてのフィールドを含む場合は約 1 Kバイト
  3. 1.2. を掛けてリアルタイムログが Kinesis Data Streams に送る 1 秒あたりデータ量が決まります
  4. ひとつのシャードが 1 秒あたりに処理できるデータ量は 1 MB、または 1000 レコードです。10 〜 20 % 程度のバッファを持たせてシャード数を決めることが推奨

さいごに

これまでトラブルシュートやアクセスログ分析においては、CloudFront のログ出力までの時間差や、パーティション分割されていないログ配置はやや使いにくいところがありましたが、今回のアップデートでログの活用がしやすくなりましたね。

とはいえ、基本的には従来のアクセスログを置き換えるものではなく、あくまでトラブルシュートで一時的に利用したり、サンプリングしながら傾向を掴むためのログ分析など用途に応じて利用するための追加機能かな、と思います。

以上!大阪オフィスの丸毛(@marumo1981)でした!