0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS CloudFrontのアクセスログをAthenaで集計するまでの手順

Posted at

これは何?

CloudFrontの配信ログをS3に保存し、Athenaでアクセス数を分析できるようにするまでの手順のメモです。
CloudFront ディストリビューションは作成している前提とします。

1. CloudFrontのアクセスログを有効化する

1.1 アクセスログ保存用のS3バケットを作成

CloudFrontログ配信用に専用バケットを用意します。

設定項目
バケット名 example-cf-access-logs
ACL 無効(推奨)
パブリックアクセス すべてブロック
バージョニング 無効
暗号化 SSE-S3(デフォルト)

1.2 CloudFrontのログ送信設定

CloudFrontコンソールで以下を設定します。

  1. 対象ディストリビューションを選択
  2. 「General」タブ → 「Settings」 → 「Logging」 を開く
  3. 「ログ配信を作成」をクリック
  4. 送信先S3バケットに example-cf-access-logs を指定
  5. 「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のログでは datetime が 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/

その他

  • datetime は UTC で記録されるため、JSTに変換が必要
  • projection.timestamp により自動パーティションが有効
  • WHERE句で日付範囲を絞るとスキャン量が減る

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?