tech-memo


title: ALB アクセスログ(S3 出力と Athena 集計) lang: ja —

ALB アクセスログ(S3 出力と Athena 集計)

Application Load Balancer の行単位のアクセスログAmazon S3 に出力する。CloudWatch Logs への直接配信はサポートされない(メトリクスは別途 CloudWatch に標準出力)。ここではマネジメントコンソール(GUI)での手順をまとめる。

公式: Application Load Balancer のアクセスログを有効にする


1. アクセスログの有効化(ALB 側)

  1. EC2 コンソール → 左メニュー ロードバランサー
  2. 対象の Application Load Balancer を選択。
  3. 属性 タブを開く。
  4. アクセスログ編集
  5. 有効 にし、S3 の場所 を指定する(例: s3://バケット名/ またはプレフィックス付き s3://バケット名/任意プレフィックス/)。実際は、その下に、/AWSLogs/[アカウントID]/elasticloadbalancing/[リージョン]/yyyy/mm/dd となるのでバケット名だけでよい。
  6. 保存する。

プレフィックスに AWSLogs という文字列を含めない(ALB の制約)。

ログは 数分遅れて S3 に到着することがあり、リアルタイム用途ではない。アプリのレイテンシへの影響は通常は問題にならない設計となっている。


2. S3 側の準備とアクセス許可

バケットを用意し、ALB のログ配信サービスが書き込めるようにする必要がある。

公式ページの バケットポリシー の節のサンプルをコピーし、次を自環境用に差し替えて S3 のバケット アクセス許可 → バケットポリシー に貼る。

Principallogdelivery.elasticloadbalancing.amazonaws.com(公式の最新手順に従う)。

動作確認

保存後、しばらく待ってバケット内にログオブジェクトが増えるか確認する。公式手順にある ELBAccessLogTestFile の有無で権限検証できる。


3. Athena でログを集計する

S3 上の gzip ログを Athena からクエリする。テーブルは Glue データカタログ上の外部テーブル定義であり、データ本体は常に S3 にある。

事前設定(GUI)

  1. Athenaクエリエディタ
  2. 設定(Settings)で クエリの結果の場所(Query result location)に、クエリ結果用の S3 プレフィックス を指定(未設定だとクエリが実行できない)。

データベースとテーブル作成

LOCATION の例(アカウント ID・プレフィックス・リージョンは置き換え):

s3://バケット名/プレフィックス/AWSLogs/アカウントID/elasticloadbalancing/リージョン/

クエリ例(パス別の件数)

公式 DDL では URL 部分は request_url 列として取れる想定。特定パス配下だけ数えたい場合のイメージ:

SELECT count(*) AS cnt
FROM alb_access_logs
WHERE request_url LIKE '%/parent/sub%';

内訳:

SELECT request_url, count(*) AS n
FROM alb_access_logs
WHERE request_url LIKE '%/parent/sub%'
GROUP BY request_url
ORDER BY n DESC
LIMIT 50;

日付で絞る

time 列で絞る(基本の公式 DDL の場合こちら) … 公式 DDL に含まれる time(リクエスト時刻の文字列)を使う。形式はログ仕様どおりだが、ISO 8601 風なら日付部分の比較で足りることが多い。

-- 例: 2026-05-11 の1日分(time の先頭が yyyy-mm-dd 形式である前提)
SELECT count(*) AS cnt
FROM alb_access_logs
WHERE request_url LIKE '%/parent/sub%'
  AND substr(time, 1, 10) = '2026-05-11';

-- 例: 期間(多日)
SELECT count(*) AS cnt
FROM alb_access_logs
WHERE request_url LIKE '%/parent/sub%'
  AND substr(time, 1, 10) >= '2026-05-01'
  AND substr(time, 1, 10) <= '2026-05-11';

time のパースで型を揃えたい場合は date_parsefrom_iso8601_timestamp も使えるが、小数秒やタイムゾーン表記が環境と完全一致するかは、まず SELECT time FROM alb_access_logs LIMIT 5 で実データを確認するとよい。

列名・パーティション列が上と違う場合は、作ったテーブル定義に合わせて WHERE を付け替える。

参考: ALB アクセスログのクエリ例


4. 補足(WAF ログとの違い)