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 へ転送
問題
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 の設定を修正
/etc/fluent-bit/fluent-bit.conf(設定変更前)
[INPUT]
Name systemd
Tag system_logs
Path /var/log/journal
/etc/fluent-bit/fluent-bit.conf(設定変更後)
[INPUT]
Name systemd
Tag system_logs
Path /var/log/journal
+ Read_From_Tail On
+ Max_Entries 100
設定項目 | 説明 | デフォルト値 |
---|---|---|
Read_From_Tail | 起動時に過去ログをスキップ | Off |
Max_Entries | 1 ラウンドあたりに処理できるログ エントリの最大数 | 5000 |
補足
ディスク退避すればよいのでは?
今回はInputのsystemdの設定に問題があった。ディスクに退避すれば問題ないかと思ったが、systemdはディスク退避の設定値(storage.type)がなかった、、、
そのため、過去分のログをSKIPさせる設定と、一回に読み込む行数の制限をおこなった。
tailなどはディスク退避の設定値があるので以下のようにすれば良い
/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
/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: