📊

構造化されたディレクトリ構成の S3 ログファイルを Athena で効率的に分析する

に公開

はじめに

API のアクセスログを S3 に保存して、AWS Athena で分析したいというケースはよくあると思います。
しかし、ログファイルが大量にある場合、効率的にクエリを実行するためには適切なテーブル設計とパーティション設定が重要になります。

今回は、構造化されたディレクトリ構成({bucket}/{dir}/yyyy/mm/dd/xxx.log)で保存された S3 ログファイルを Athena で効率的に分析する方法について説明します。

今回やったこと

  • S3 に保存された API アクセスログの Athena テーブル作成
  • パーティション投影(Partition Projection)の設定
  • コスト効率的なクエリ実行の実現

ログファイルの構成

ディレクトリ構造

{bucket}/{dir}/yyyy/mm/dd/xxx.log

ログファイルの内容

ログファイルは一行一 JSON のプレーンテキスト形式で、以下のような構造になっています。

{
  "date": "2025-10-02T03:01:20.000000Z",
  "level": "INFO",
  "message": {
    "api_user_id": 12345,
    "controller_name": "/controller/path",
    "params": {"user_id": 12345, "name": "John"},
    "response": {"status": "success", "data": {...}}
  }
}

* params, response の内容はエンドポイントごとに異なる

Athena テーブルの作成

データソースの設定

AWS Athena のクエリエディタから「データソース」→「テーブルを作成」→「S3 バケットデータ」を選択します。

alt text

基本設定

  • データセット > 入力データセットの場所: {bucket}/{dir}/
  • データ形式 > ファイル形式: JSON

列の詳細

date: string
level: string
message: struct<
  api_user_id: int,
  controller_name: string,
  params: string,
  response: string
>

パーティション投影の設定

効率的なクエリ実行のために、パーティション投影を設定します。

テーブルプロパティ

{
  "storage.location.template": "{bucket}/{dir}/${year}/${month}/${day}/",
  "projection.year.type": "integer",
  "projection.year.range": "2023,2030",
  "projection.year.digits": "4",
  "projection.month.type": "integer",
  "projection.month.range": "01,12",
  "projection.month.digits": "2",
  "projection.day.type": "integer",
  "projection.day.range": "01,31",
  "projection.day.digits": "2"
}

パーティションの詳細

  • year: string
  • month: string
  • day: string

クエリの実行

基本的なクエリ例

パーティション投影により、通常のカラムと同じように検索できます。
通常のカラムと合わせての絞り込みも可能です。

-- 特定の日付のログを取得
SELECT * FROM api_logs 
WHERE year = '2025' AND month = '10' AND day = '02' AND api_user_id = 1;

範囲検索

比較演算子(<, >, >=, <=)も使用可能です。

-- 2025年の1月から3月のログを取得
SELECT * FROM api_logs 
WHERE year = '2025' AND month >= '01' AND month <= '03';

年跨ぎ・月跨ぎの検索

年、月、日でカラムが分かれているため、年跨ぎや月跨ぎの検索には工夫が必要です。

-- 2024年5月以降のログを取得
SELECT * FROM api_logs 
WHERE (year = '2025' OR (year = '2024' AND month >= '05'));

コスト効率化のポイント

パーティション投影の効果

パーティション投影を設定することで、以下のメリットが得られます:

  1. スキャン対象ファイルの削減: パーティション条件に合致しないファイルは読み込まれません
  2. コスト削減: スキャンされないファイルは課金対象になりません
  3. クエリ性能向上: 必要なファイルのみを処理するため、クエリ実行時間が短縮されます

注意点

  • パーテーションではなくカラムによる絞り込みの場合、ログファイルの読み込み自体は発生してしまうため課金対象になります
  • パーティション投影での絞り込みなら、そもそもファイルをロードしないため課金対象になりません

まとめ

構造化されたディレクトリ構成の S3 ログファイルを Athena で効率的に分析するには:

  1. 適切なテーブル設計: JSON 構造に合わせた列定義
  2. パーティション投影の活用: ディレクトリ構造を活かしたパーティション設定
  3. 効率的なクエリ: パーティション条件を活用したクエリ設計

これらの設定により、大量のログファイルを効率的に分析でき、コストも抑えることができます。

参考資料

ENECHANGE

Discussion