Fluentd × CloudWatch Logs の送信最適化術

# Fluentd × CloudWatch Logs の送信最適化術 〜Ingestion料金を賢く節約する〜

## 🧠 AI生成のドキュメント

本文書はAI生成のドキュメントです。AIとの対話でできた、役に立つ情報をブログ形式に変換して蓄積していきます。

## 📕 概要

CloudWatch Logs を使っていると、いつの間にか **取り込み（Ingestion）料金** が高くなっていて驚くことはありませんか？

本記事では、**Fluentd（td-agent）** を使って CloudWatch Logs にログを送信している環境を対象に、**料金を抑えるための送信最適化テクニック** を紹介します。

---

## 🔍 CloudWatch Logs の課金ポイント

CloudWatch Logs の課金は、主に以下の3つの要素で構成されています。

| 項目 | 内容 |
|------|------|
| **Ingestion（取り込み）** | 圧縮後のログデータサイズ（GB）で課金 |
| **Retention（保存）** | 保存期間に応じたストレージ課金 |
| **Insights（クエリ）** | クエリ実行時のデータスキャン量に応じて課金 |

👉 **ポイントは「Ingestion は圧縮後サイズが対象」** という点です！

---

## 📦 Fluentd のバッファリングで「まとめて送信」

Fluentd（td-agent）には、ログを一時的にバッファリングして **まとめて送信する機能** があります。

これを使うことで CloudWatch Logs への送信効率が上がり、**取り込み料金の節約** に繋がります。

### メリット

- ✅ gzip 圧縮効率が上がる → 圧縮後サイズが減る
- ✅ 小分け送信を防げる → オーバーヘッド削減
- ✅ Lambda 経由などの場合は実行回数も削減可能

---

## ⚙️ Fluentd のバッファ設定例

以下は、`fluent-plugin-cloudwatch-logs` を使って Fluentd から CloudWatch Logs に送信する設定の一例です。

```conf
<match your.log.tag>
  @type cloudwatch_logs
  log_group_name your-log-group
  log_stream_name your-log-stream
  auto_create_stream true
  region ap-northeast-1

  <buffer>
    chunk_limit_size 2M
    flush_interval 30s
    flush_thread_count 2
    retry_max_times 10
    retry_wait 5s
  </buffer>
</match>
```
## 🤔 `flush_interval` と `chunk_limit_size` の関係

| パラメータ           | 意味                                                                 |
|----------------------|----------------------------------------------------------------------|
| `chunk_limit_size`   | チャンクがこのサイズに達したら **即送信** される（`flush_interval` は無視される） |
| `flush_interval`     | チャンクが満たなくても、この時間が経過したら **送信** される                       |

### ✅ つまり：

- **ログが多い場合**：チャンクが `chunk_limit_size` に達した時点で即送信される
- **ログが少ない場合**：`flush_interval` 経過で未送信チャンクが送信される

以下のように動作します：
- 🧠 条件A: chunk_limit_size 到達 → 即 flush（flush_interval を待たない）
- 🕒 条件B: chunk_limit_size 未満 → flush_interval 経過で flush

---

## 🧪 バッチ送信でどれだけ圧縮できるか？

| 送信方法               | 圧縮効率 | Ingestionサイズ（仮） |
|------------------------|----------|------------------------|
| 毎秒送信（小分け）      | 悪い      | 約18KB                 |
| 毎分まとめて送信        | 良い      | 約6KB                  |

> バッチ化することで **Ingestion コストを 1/3 に抑えられる** こともあります。

---

## ⚠️ 注意：CloudWatch Logs の制限

CloudWatch Logs には以下の制限があります。

- 1行あたりの最大サイズ：**256KB**
- 1リクエストあたりの最大バッチサイズ：**1MB**
- 最大イベント数：**10,000件/リクエスト**

Fluentd 側の `chunk_limit_size` 設定もこれを超えないようにしましょう。

---

## 🔧 チューニングのおすすめ

| ログ量 | `flush_interval` | `chunk_limit_size` | `flush_thread_count` |
|--------|------------------|--------------------|------------------------|
| 少量   | 30〜60秒         | 512KB〜1MB         | 1〜2                   |
| 大量   | 5〜15秒          | 2MB〜5MB           | 2〜4                   |

---

## ✅ まとめ

| 対策                         | 効果                                     |
|------------------------------|------------------------------------------|
| チャンクサイズを調整         | 圧縮効率アップ、送信回数削減             |
| `flush_interval` の見直し    | 小さなチャンクの無駄な送信を防止         |
| 行サイズの制限に注意         | CloudWatch でのエラー防止               |
| gzip 圧縮を意識した送信設計 | Ingestion 料金の削減に直結               |

---

## 📘 参考リンク

- [AWS CloudWatch Logs 料金](https://aws.amazon.com/jp/cloudwatch/pricing/)
- [fluent-plugin-cloudwatch-logs GitHub](https://github.com/fluent-plugins-nursery/fluent-plugin-cloudwatch-logs)
- [Fluentd バッファ設定ガイド](https://docs.fluentd.org/buffer/overview)

---

## 🙌 最後に

CloudWatch Logs を使っていると、つい見落としがちな「**取り込み時の圧縮後サイズ**」。

Fluentd のバッファ設定を見直すことで、パフォーマンスとコストのバランスを最適化できます。  
ぜひ一度、自分の `td-agent.conf` を見直してみてください！