MacBookProのローカル環境でDuckDBを使用してAWS S3およびCloudflare R2に保存されたログを解析する方法

**DuckDB**を使用して、MacBookProのローカル環境で**AWS S3**と**Cloudflare R2**に保存されているログファイルを効率的に解析する方法を紹介します。Pythonなどのプログラムを使用せず、DuckDBのコマンドラインインターフェース（CLI）を使って操作します。

## はじめに

ログ解析において、異なるオブジェクトストレージに保存されたデータを統合的に処理することは重要です。DuckDBは、S3互換のオブジェクトストレージに対応しており、AWS S3だけでなく、Cloudflare R2にもアクセスすることが可能です。本記事では、各ストレージへのアクセス方法と、両方のデータを組み合わせて解析する方法を解説します。

## DuckDBとは

[DuckDB](https://duckdb.org/)は、組み込み型の高速なOLAPエンジンで、以下の特徴があります。

- **組み込み型データベース**：追加のサーバー設定が不要
- **高性能なクエリ処理**：列指向ストレージ形式と高度な最適化により高速化
- **SQL標準準拠**：既存の知識でクエリが可能
- **S3互換ストレージへのネイティブアクセス**：外部ライブラリなしでAWS S3やCloudflare R2にアクセス可能
- **多様なデータフォーマットのサポート**：CSV、Parquet、JSONなど

---

## 環境設定

### 必要なツールのインストール

#### Homebrewのインストール（未インストールの場合）

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

#### DuckDBのインストール

```bash
brew install duckdb
```

#### AWS CLIのインストール（必要に応じて）

```bash
brew install awscli
```

---

## AWS S3へのアクセス

### AWS認証情報の設定

#### AWS CLIでの設定

```bash
aws configure
```

以下の情報を入力します。

- **AWS Access Key ID**
- **AWS Secret Access Key**
- **Default region name**
- **Default output format**

#### 環境変数での設定

```bash
export AWS_ACCESS_KEY_ID='your_aws_access_key_id'
export AWS_SECRET_ACCESS_KEY='your_aws_secret_access_key'
export AWS_REGION='your_aws_region'
```

### DuckDBでの操作

#### DuckDBシェルの起動

```bash
duckdb
```

#### S3設定の確認（必要に応じて）

DuckDBは環境変数からAWS認証情報を自動的に取得しますが、DuckDB内で明示的に設定することもできます。

```sql
SET s3_region='your_aws_region';
SET s3_access_key_id='your_aws_access_key_id';
SET s3_secret_access_key='your_aws_secret_access_key';
```

#### AWS S3のデータにクエリを実行

```sql
SELECT * FROM read_parquet('s3://your-aws-bucket/path/to/logs/*.parquet');
```

- `read_parquet`関数でParquetファイルを読み込みます。
- ファイルパスは`s3://`で始まります。

---

## Cloudflare R2へのアクセス

### Cloudflare R2の認証情報の取得

Cloudflareダッシュボードから以下の情報を取得します。

- **Access Key ID**
- **Secret Access Key**
- **Account ID**

### 環境変数での設定（推奨）

```bash
export R2_ACCESS_KEY_ID='your_r2_access_key_id'
export R2_SECRET_ACCESS_KEY='your_r2_secret_access_key'
```

### DuckDBでの操作

#### S3設定を関数内で指定

DuckDBでは、関数ごとにS3の設定を指定できます。

```sql
SELECT * FROM read_parquet(
    's3://your-r2-bucket/path/to/logs/*.parquet',
    s3_access_key_id='your_r2_access_key_id',
    s3_secret_access_key='your_r2_secret_access_key',
    s3_endpoint='https://<account_id>.r2.cloudflarestorage.com',
    s3_region='auto'
);
```

- `<account_id>`はあなたのCloudflareアカウントIDに置き換えてください。
- `s3_endpoint`を指定することで、Cloudflare R2に接続します。
- `s3_region`は`'auto'`に設定します。

---

## AWS S3とCloudflare R2のデータを組み合わせて解析

DuckDBでは、関数ごとにS3の設定を指定できるため、一度のクエリで異なるストレージからデータを読み込むことが可能です。

### データの統合クエリ

```sql
WITH aws_data AS (
    SELECT * FROM read_parquet(
        's3://your-aws-bucket/path/to/logs/*.parquet',
        s3_region='your_aws_region',
        s3_access_key_id='your_aws_access_key_id',
        s3_secret_access_key='your_aws_secret_access_key'
    )
),
r2_data AS (
    SELECT * FROM read_parquet(
        's3://your-r2-bucket/path/to/logs/*.parquet',
        s3_access_key_id='your_r2_access_key_id',
        s3_secret_access_key='your_r2_secret_access_key',
        s3_endpoint='https://<account_id>.r2.cloudflarestorage.com',
        s3_region='auto'
    )
)
SELECT * FROM aws_data
UNION ALL
SELECT * FROM r2_data;
```

- `WITH`句を使用して、一時的なテーブル`aws_data`と`r2_data`を作成します。
- `UNION ALL`で両方のデータを結合します。

### 特定条件でのデータ解析

エラーログを抽出する例：

```sql
WITH combined_data AS (
    SELECT * FROM read_parquet(
        's3://your-aws-bucket/path/to/logs/*.parquet',
        s3_region='your_aws_region',
        s3_access_key_id='your_aws_access_key_id',
        s3_secret_access_key='your_aws_secret_access_key'
    )
    UNION ALL
    SELECT * FROM read_parquet(
        's3://your-r2-bucket/path/to/logs/*.parquet',
        s3_access_key_id='your_r2_access_key_id',
        s3_secret_access_key='your_r2_secret_access_key',
        s3_endpoint='https://<account_id>.r2.cloudflarestorage.com',
        s3_region='auto'
    )
)
SELECT *
FROM combined_data
WHERE event_type = 'ERROR';
```

---

## まとめ

DuckDBを使用すると、AWS S3とCloudflare R2に保存されたログデータを同時に解析できます。関数ごとにS3の設定を指定することで、異なるストレージサービスからのデータを統合し、効率的なログ解析が可能になります。ぜひ活用してみてください。

---

## 注意点

- **セキュリティ**：認証情報はコード内に直接記述しないことが推奨されます。環境変数や設定ファイルを使用する方法も検討してください。
- **エンドポイントの指定**：Cloudflare R2などのS3互換ストレージを使用する場合、`s3_endpoint`を正しく設定する必要があります。
- **パフォーマンス**：大量のデータを扱う場合、DuckDBの設定（例：`PRAGMA threads`）を調整することでパフォーマンスを最適化できます。

---

## 参考資料

- [DuckDB公式サイト](https://duckdb.org/)
- [DuckDBでのS3アクセスに関するドキュメント](https://duckdb.org/docs/extensions/httpfs/s3api_legacy_authentication.html)
- [DuckDBでのParquetファイルの読み込み](https://duckdb.org/docs/data/parquet)
- [AWS CLIのインストールガイド](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)
- [Cloudflare R2 Documentation](https://developers.cloudflare.com/r2/)
- [DuckDBとS3を使ったログ解析の実践例](https://zenn.dev/shiguredo/articles/duckdb-jsonlines-log)
- [DuckDBによるCloudflare R2へのアクセス方法](https://www.f-wind.co.jp/blog/000505.html)

---

**最後に**、DuckDBを使用することで、MacBookProのローカル環境上でAWS S3とCloudflare R2の両方に保存されたログデータを効率的に解析できます。異なるストレージからのデータを統合し、強力なSQLクエリで解析することで、ログ解析の生産性を大幅に向上させることができるとおもいます。