Fluent Bitでメモリ使用量が上昇し続ける問題を解決した話（Amazon Linux 2023 ＋ CloudWatch Logs）

# TL;DR
- Amazon Linux 2023 で Fluent Bit を使って CloudWatch Logs にログ転送していたところ、メモリ使用量が上昇し続けていた
- 原因は systemd input プラグインがJournalログを全読み込みし続けていたため
- Read_From_Tail と Max_Entries を設定することで、メモリ使用量の増加が解消された
- tail input には storage.type filesystem を使ってメモリ圧迫も回避した

# 環境
- EC2(Amazon Linux 2023)
- EC2 は毎朝08:00に起動して、20:00に停止
- fluent-bit をインストールしてAmazon Linux 2023 の Journalを CloudWatchLogs へ転送

# 問題
:::note alert
EC2（Amazon Linux 2023）にインストールした Fluent Bit で CloudWatch Logs にログを転送していたところ、起動直後から Fluent Bit のメモリ使用量上昇、最終的に**メモリリーク**が発生
:::


# 原因
- 設定ファイルを見直した結果、以下が問題のポイントだった
    - systemd input を使っていた（Path /var/log/journal）
    - Read_From_Tail を指定していなかったため、全Journalログ（過去分含む）を読み込み続けていた
    - systemd input は storage.type をサポートしておらず、メモリ上にすべて保持
    - また、tail input でも storage.type を指定しないとメモリにチャンクが溜まるため、こちらもディスクバッファを明示する必要があった

# 解決方法
systemd input の設定を修正
```conf:/etc/fluent-bit/fluent-bit.conf(設定変更前)
[INPUT]
    Name              systemd
    Tag               system_logs
    Path              /var/log/journal
```

```diff_conf:/etc/fluent-bit/fluent-bit.conf(設定変更後)
[INPUT]
    Name              systemd
    Tag               system_logs
    Path              /var/log/journal
+    Read_From_Tail   On
+    Max_Entries      100
```

:::note info
各種設定の意味
ref：https://docs.fluentbit.io/manual/pipeline/inputs/systemd
:::
| 設定項目 | 説明 | デフォルト値 |
| ---- | ---- | ---- |
| Read_From_Tail | 起動時に過去ログをスキップ | Off |
| Max_Entries | 1 ラウンドあたりに処理できるログ エントリの最大数 | 5000 |


# 補足
## ディスク退避すればよいのでは？
今回はInputのsystemdの設定に問題があった。ディスクに退避すれば問題ないかと思ったが、systemdはディスク退避の設定値(storage.type)がなかった、、、
そのため、過去分のログをSKIPさせる設定と、一回に読み込む行数の制限をおこなった。
tailなどはディスク退避の設定値があるので以下のようにすれば良い
```diff_conf:/etc/fluent-bit/fluent-bit.conf
[SERVICE]
    Flush             5
    Log_Level         info
+    storage.path     /var/log/flb-storage # 退避先の場所をして
[INPUT]
    Name              tail
    Tag               app_logs
    Path              /var/www/app/storage/logs/*.log
    Mem_Buf_Limit     10MB
+    storage.type     filesystem # この行を指定することにより、[SERVICE]に記載のPathに退避
```

## 修正後の全体Conf
```diff_conf:/etc/fluent-bit/fluent-bit.conf
[SERVICE]
    Flush             1
    Daemon            Off
    Log_Level         info
+   storage.path      /var/log/flb-storage

[INPUT]
    Name              systemd
    Tag               system_logs
    Path              /var/log/journal
+    Read_From_Tail   On
+    Max_Fields       100

[INPUT]
    Name              tail
    Tag               app_logs
    Path              /var/log/app/app-*.log
    Multiline_Flush   5
+   Mem_Buf_Limit     10MB
+   storage.type      filesystem

[OUTPUT]
    Name              cloudwatch_logs
    Match             *
    auto_create_group true
    region            ap-northeast-1
    log_group_name    /aws/ec2/i-xxxxxx
    log_stream_prefix fluent-bit_
+   retry_limit       5

[OUTPUT]
    Name              cloudwatch_logs
    Match             app_logs
    auto_create_group true
    region            ap-northeast-1
    log_group_name    /aws/ec2/app
    log_stream_prefix app
+    retry_limit       5
```

# 所感
今回、毎日EC2を停止/起動していた為、起動したタイミングでfluent-bitが過去の大量Journalログを読み込んでしまい、メモリに蓄積してしまった事が原因
Journalログを日付毎にファイル保存して、fluent-bitはそのファイルを読み込みすれば良いという案もある。

# Ref:

https://docs.fluentbit.io/manual/pipeline/inputs/systemd

https://docs.fluentbit.io/manual/pipeline/inputs/tail