このブログは CloudFront + S3 で運用しています。アクセス解析に関しては Google Analytics を使っていますが、せっかくなので CloudFront が出力しているログを Amazon Athena を使って解析してみようと思います。

CloudFront でログ出力を有効にする

そもそもログが出力されていなかったら意味がありません。
CloudFront の Distribution Settings でログ出力が有効になっていることを確認します。なっていなかったら、適当な S3 バケットを作ってそこに出力されるようにしておきます。

Distribution Settings

Athena で CloudFront のログ解析

Athena で CloudFront のログを解析するためには、解析に使用するテーブルを作成する必要があります。テーブルを作成すれば、そこに対して慣れ親しんだ SQL を発行することによってログの解析ができるようになります。

Athena で CloudFront のログ解析用のテーブルを作成する

テーブルを作成するための CREATE 文を作成します。
必要なフィールドは、 CloudFront のログ、または 公式ドキュメントを確認します。

今回は CloudFront のログから必要なフィールドを確認してみます。ちなみにCloudFront の Distribution には WebRTMP がありますが、今回は Web の場合についてです。

CloudFront のログは一定時間ごとに gzip 圧縮された状態で出力されます。それぞれのログファイルの 2 行目にフィールドが半角スペース区切りで出力されています。

CloudFront Log Fields

このままではフィールド名として使用できない名前・文字が含まれているので、それらの変更と見た目の問題も考慮して適宜変更します。具体的には、

  • date, time は予約語なので、先頭に request_ を付ける
  • -, (_ に置換
  • ) を削除
  • すべて小文字にする

という処理をします。

これでフィールド名が確定したので、下記のような CREATE 文を作成します。

CREATE EXTERNAL TABLE IF NOT EXISTS michimani_cf_logs (
    request_date DATE,
    request_time STRING,
    x_edge_location STRING,
    sc_bytes INT,
    c_ip STRING,
    cs_method STRING,
    cs_host STRING,
    cs_uri_stem STRING,
    sc_status STRING,
    cs_referer STRING,
    cs_user_agent STRING,
    cs_uri_query STRING,
    cs_cookie STRING,
    x_edge_result_type STRING,
    x_edge_request_id STRING,
    x_host_header STRING,
    cs_protocol STRING,
    cs_bytes INT,
    time_taken DECIMAL(8,3),
    x_forwarded_for STRING,
    ssl_protocol STRING,
    ssl_cipher STRING,
    x_edge_response_result_type STRING,
    cs_protocol_version STRING,
    fle_status STRING,
    fle_encrypted_fields STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
    'serialization.format' = '\t',
    'input.regex' = '\t'
)
LOCATION 's3://S3_BACKET_NAME/michimani.net-cf-log/'
TBLPROPERTIES ('has_encrypted_data'='false');

ここで変更が必要なのは LOCATION 部分です。ここは、 CloudFront のログが出力される S3 バケット名を指定します。あとテーブル名も適宜指定します。

CREATE 文の実行は、Athena のコンソール画面で テキストエリアに上記 SQL をコピペして Run query ボタンを押すだけです。

Athena で CloudFront のログを解析する

テーブルが作成できれば、あとは普通に SQL 文で解析ができるようになります。

SELECT request_date, request_time, cs_method, cs_uri_stem FROM michimani_cf_logs 
WHERE cs_method = 'GET' 
AND (cs_uri_stem LIKE '%/' OR cs_uri_stem LIKE '%index.html') 
AND sc_status = '200' 
AND request_date = DATE '2019-01-28'
AND request_time > '04:10:00' AND request_time < '04:20:00'
ORDER BY request_time DESC
limit 10;
Execute select query

Athena を利用せずに解析しようとすると、すべてのログファイルを unzip してゴニョゴニョする必要があるので、非常に面倒です。それがこんなに簡単に出来てしまうのは凄い以外の感想がないです。

Athena の料金

気になるのはお値段です。
Athena の利用用金は、発行したクエリの対象となるデータ(sキャンされたデータ)のサイズによって決まり、そのデータサイズ 1TB ごとに 5 USD の料金が発生します。
スキャンされたデータサイズは、クエリ実行画面で確認することができます。例えば上の実行結果では、クエリのテキストエリアの下に Run time: 3.29 seconds, Data scanned: 822.59 KB と出力されています。この 822.59 KB というのがスキャンされたデータサイズとなります。 バイト数はメガバイト単位で切り上げられるため、この場合は 10 MB として計算されます。

Athena に関して発生する料金はクエリ実行に対してのみですが、その他に、もちろんですが S3 にログを保持しておくための料金は発生します。

ひとこと

以上、 Amazon Athena を使って CloudFront のログを解析してみた話でした。
Athena って凄く難しいというか、使い所がよくわかっていませんでしたが、こんなにも簡単に使えるのは驚きでした。本当にスタンダードな、初歩的な使い方ではありますが、とりあえず触ってみると親近感が湧きますね。


以上、よっしー (michimani) でした。

Share to ...

Follow on Feedly

comments powered by Disqus