Fluentbit读取重建的EC2日志文件时重复发送日志的问题求助
解决Fluentbit重复读取EC2实例日志的问题
问题根源
每次运行ecs-logs-collector.sh都会创建全新的日志文件(而非追加内容),Fluentbit的tail插件默认通过inode识别文件,新文件的inode与旧文件不同,会被判定为全新文件,因此会从头读取全部内容,导致重复日志发送到Firehose。
可行解决方案
方案1:修改日志收集脚本,改为追加写入
直接调整ecs-logs-collector.sh的日志输出逻辑,将覆盖写入(>)改为追加写入(>>),让每次脚本运行都把新增日志追加到同一个文件中,而非创建新文件。
- 找到脚本中类似以下的写入语句:
cat /var/log/ecs/ecs-agent.log > /ecs/logs/sample.log - 修改为:
cat /var/log/ecs/ecs-agent.log >> /ecs/logs/sample.log - 额外优化:如果脚本是全量收集日志,可以先通过
grep或awk过滤出上次收集后新增的内容再追加,避免文件体积过大。
方案2:配置Fluentbit的tail插件,基于文件名追踪读取位置
如果无法修改脚本,可调整Fluentbit的tail插件配置,让它基于文件名而非inode记录读取偏移量,同时持久化偏移量数据:
- 在Fluentbit的INPUT配置中添加以下参数:
[INPUT] Name tail Path /ecs/logs/sample.log # 持久化读取偏移量的数据库文件路径,需挂载持久化存储卷 DB /fluentbit/tail/ecs_logs.db # 用文件名作为偏移量记录的标识,而非inode Persist_Key filename # 不从文件头部开始读,只读取新增内容 Read_from_Head false # 每隔10秒检查文件变化 Refresh_Interval 10 - 确保
/fluentbit/tail/路径挂载了持久化存储(比如EC2本地存储、EFS卷),避免Fluentbit容器重启后偏移量数据丢失。
方案3:结合日志轮转工具避免重复读取
如果脚本必须生成新文件,可使用logrotate对日志文件进行轮转,配合Fluentbit的多文件追踪配置:
- 配置
logrotate规则(示例):/ecs/logs/sample.log { # 每天轮转一次 daily # 保留7天的历史日志 rotate 7 # 文件不存在时不报错 missingok # 文件为空时不轮转 notifempty # 复制文件内容后截断原文件,避免inode变化 copytruncate # 压缩历史日志 compress delaycompress } - 修改脚本为追加写入到
sample.log,由logrotate负责处理文件轮转。 - 调整Fluentbit的INPUT配置:
[INPUT] Name tail # 追踪所有轮转后的日志文件 Path /ecs/logs/sample.log* DB /fluentbit/tail/ecs_logs.db # 忽略超过24小时的旧文件,避免重复读取 Ignore_Older 24h Refresh_Interval 10
内容的提问来源于stack exchange,提问作者Prathyush Peettayil
相关产品推荐
相关产品推荐

