これは何?
CloudFrontの配信ログをS3に保存し、Athenaでアクセス数を分析できるようにするまでの手順のメモです。
CloudFront ディストリビューションは作成している前提とします。
1. CloudFrontのアクセスログを有効化する
1.1 アクセスログ保存用のS3バケットを作成
CloudFrontログ配信用に専用バケットを用意します。
| 設定項目 | 値 |
|---|---|
| バケット名 | example-cf-access-logs |
| ACL | 無効(推奨) |
| パブリックアクセス | すべてブロック |
| バージョニング | 無効 |
| 暗号化 | SSE-S3(デフォルト) |
1.2 CloudFrontのログ送信設定
CloudFrontコンソールで以下を設定します。
- 対象ディストリビューションを選択
- 「General」タブ → 「Settings」 → 「Logging」 を開く
- 「ログ配信を作成」をクリック
- 送信先S3バケットに
example-cf-access-logsを指定 - 「Additional settings」に以下を設定
/{distributionid}/{yyyy}/{MM}/{dd}/{HH}
ほか設定は以下
- Output format :
W3C - Field delimiter
\t
設定が完了すると、CloudFrontが自動でS3バケットにアクセスログを書き込み始めます。
2. Athenaの設定
2.1 データベースを作成
Athenaクエリエディタで以下を実行します。
DB名は適当なものをつけてください。
CREATE DATABASE cloudfront_access_logs_db;
2.2 CloudFrontログ用テーブルを作成
CloudFrontのログを解析するための外部テーブルを作成します。
CREATE EXTERNAL TABLE IF NOT EXISTS cloudfront_access_logs(
`date` DATE,
`time` STRING,
x_edge_location STRING,
sc_bytes BIGINT,
c_ip STRING,
cs_method STRING,
cs_host STRING,
cs_uri_stem STRING,
sc_status INT,
cs_referrer 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 BIGINT,
time_taken FLOAT,
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 INT,
c_port INT,
time_to_first_byte FLOAT,
x_edge_detailed_result_type STRING,
sc_content_type STRING,
sc_content_len BIGINT,
sc_range_start BIGINT,
sc_range_end BIGINT
)
PARTITIONED BY (`timestamp` string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LOCATION 's3://example-cf-access-logs/AWSLogs/123456789012/CloudFront/E1234567ABCDEF/'
TBLPROPERTIES (
'skip.header.line.count'='2',
'projection.enabled'='true',
'projection.timestamp.format'='yyyy/MM/dd',
'projection.timestamp.interval'='1',
'projection.timestamp.interval.unit'='DAYS',
'projection.timestamp.range'='2024/01/01,NOW',
'projection.timestamp.type'='date',
'storage.location.template'='s3://example-cf-access-logs/AWSLogs/123456789012/CloudFront/E1234567ABCDEF/${timestamp}'
);
修正が必要な箇所
| 修正箇所 | 内容 |
|---|---|
LOCATION |
自分のS3ログバケットのパスに変更 |
123456789012 |
自分のAWSアカウントIDに変更 |
E1234567ABCDEF |
CloudFrontディストリビューションIDに変更 |
example-cf-access-logs |
ログバケット名に変更 |
'projection.timestamp.range' |
ログの保存開始日付に合わせて変更(例:2025/01/01,NOW) |
3. Athenaでアクセス集計する
Athenaでクエリを実行して集計が可能になります。
CloudFrontのログでは date と time が UTC で記録されます。
日本時間(JST)で分析するには、9時間を加算して補正する必要があるので注意.
以下は status=200 のアクセス結果を集計する例です
-- 日付ごとのアクセス数を集計する例
-- CloudFrontのログはUTC時刻で記録されるため、必要に応じて +9時間してJST変換を行う
WITH base AS (
SELECT
from_iso8601_timestamp(concat(CAST("date" AS varchar), 'T', "time", 'Z')) AS ts_utc,
sc_status,
cs_uri_stem,
cs_method,
c_ip
FROM cloudfront_access_logs
WHERE
sc_status = 200
AND "timestamp" BETWEEN '2025/08/01' AND '2025/08/07' -- 期間を指定
),
jst AS (
SELECT
from_unixtime(to_unixtime(ts_utc) + 9*3600) AS ts_jst -- JSTへ変換
FROM base
)
SELECT
CAST(ts_jst AS DATE) AS log_date,
COUNT(*) AS access_count
FROM jst
GROUP BY CAST(ts_jst AS DATE)
ORDER BY log_date;
4. 注意点と補足
ファイル構造
CloudFrontのログは以下のディレクトリ構造でS3に出力されます。
s3://example-cf-access-logs/AWSLogs/{account_id}/CloudFront/{distribution_id}/YYYY/MM/DD/HH/
その他
-
dateとtimeは UTC で記録されるため、JSTに変換が必要 -
projection.timestampにより自動パーティションが有効 - WHERE句で日付範囲を絞るとスキャン量が減る