Logstash File Input插件重复输出事件问题咨询
这种重复输出倒数第二行的情况我之前碰到过好几次,大概率和日志文件的换行规范以及Logstash File插件对「完整行」的判断逻辑有关,具体拆解如下:
核心原因:不完整行的重复读取
Logstash File插件默认以换行符作为行的结束标记。如果你的日志文件末尾的行没有以标准换行符(\n或\r\n,取决于操作系统)结尾,插件会把这行标记为「不完整行」,不会更新sincedb(记录文件读取位置的本地数据库)里的偏移量。
举个实际场景:
假设a1.txt初始内容是:
2024-05-20 10:00:01 [INFO] 启动成功 2024-05-20 10:00:05 [DEBUG] 加载配置
注意第二行末尾没有换行符,Logstash读取时会认为这是不完整行,只会输出第一行,而第二行的位置不会被记录到sincedb。
当你往a1.txt添加带换行符的新日志:
2024-05-20 10:01:00 [INFO] 接收请求
此时文件内容变成:
2024-05-20 10:00:01 [INFO] 启动成功 2024-05-20 10:00:05 [DEBUG] 加载配置 2024-05-20 10:01:00 [INFO] 接收请求
Logstash检测到文件变化后,会从上次未记录的位置(第一行结尾)重新读取,原来的「加载配置」行因为现在有了换行符,会被当作完整行输出,同时新的「接收请求」行也会输出——这就导致了倒数第二行(原末尾行)被重复输出。
其他次要可能原因
- sincedb记录异常:如果sincedb文件损坏或权限不足,可能导致插件无法正确记录读取位置,但这种情况一般会导致更多内容重复,而非仅倒数第二行。
- 日志写入工具问题:某些自定义脚本或工具在追加内容时,可能先覆盖原末尾部分内容再写入,导致Logstash读取到重复内容,但这种情况比较少见。
解决方法
1. 规范日志文件的换行格式
这是最根本的解决方法:确保所有日志写入工具在写完每一行后,都添加标准换行符。比如用echo "日志内容" >> a1.txt(echo默认会加换行),而非printf "日志内容" >> a1.txt(默认不加换行)。
2. 配置插件处理不完整行
在File插件配置中添加incomplete_line_timeout参数,让插件等待指定时间后,将未结束的不完整行当作完整行处理,避免后续重复读取:
input { file { path => "/path/to/a*.txt" start_position => "beginning" incomplete_line_timeout => 30 # 等待30秒后处理不完整行 } }
3. 重置sincedb(测试环境临时方案)
如果是测试环境,可以删除Logstash自动生成的sincedb文件(默认路径为~/.sincedb_*,不同系统略有差异),然后重启Logstash。这会让插件重新读取所有文件,但只是临时解决,仍需从根源上规范换行。
内容的提问来源于stack exchange,提问作者Shahrukh khan

