Fluentd in_tail插件采集日志event key_name不一致问题排查与修复
问题根因
出现key名在Log和message之间跳变、对应字段不存在报错的核心原因是配置调试残留+默认参数未显式指定,和in_tail插件本身逻辑无关:
- td-agent v4版本的in_tail插件,当
<parse>段配置@type none时,默认存储原始日志行的字段名为message,不存在随机生成key名的逻辑。 - 前期调试配置时,曾将字段输出名设置为
Log,当时运行产生的带Log字段的事件残留在插件缓冲、旧pos文件记录了错误的读取点位,叠加logrotate日志轮转时的重复读取逻辑,导致旧格式事件和新采集的默认message字段事件混流,才会出现修改parser的key_name后,两边字段不存在的报错交替出现的现象。 - 现有parser过滤器配置未开容错,只要待解析的key名不匹配就会直接抛出字段不存在的错误,没有降级逻辑。
修复步骤
1. 清理残留脏数据
先停服务,删除旧的点位文件和缓冲文件,彻底清除历史配置遗留的脏数据,这一步是解决新旧事件混流的核心:
systemctl stop td-agent rm -f /var/log/td-agent/tmp/*.pos rm -rf /var/log/td-agent/buffer/*
2. 显式固定in_tail采集的字段名
调整两个in_tail源配置,通过message_key参数强制指定原始日志存储的字段名为Log,不依赖默认值,同时补充logrotate轮转适配参数,避免轮转时重复读、丢日志:
<system> log_level info </system> <source> @type tail @label @condition-service path /XXXX/log1.log,/XXXX/log2.log pos_file /var/log/td-agent/tmp/condition-service.log.pos tag condition-service pos_file_compaction_interval 24h # 显式固定原始日志字段名 message_key Log # 适配logrotate轮转 enable_watch_timer true rotate_wait 5 <parse> @type none </parse> </source> <source> @type tail @label @condition-quotes path /XXXX/log3.log pos_file /var/log/td-agent/tmp/condition-quotes.log.pos tag condition-quotes pos_file_compaction_interval 24h message_key Log enable_watch_timer true rotate_wait 5 <parse> @type none </parse> </source>
3. 调整parser过滤器配置对齐字段,增加容错
所有parser过滤器的key_name和前面固定的Log字段对齐,去掉regexp中多余的gm修饰符(fluentd内置regexp解析逐行匹配,不需要全局/多行修饰符),同时开启容错配置,避免偶发解析失败直接抛错:
<label @condition-quotes> <filter condition-quotes> @type parser key_name Log # 保留原始字段,解析失败不丢数据 reserve_data true emit_invalid_record_to_error false <parse> @type regexp expression /^(?<Log>.*)$/ </parse> </filter> <match condition-quotes> @type elasticsearch host XX.XX.XX.XX port 9200 logstash_format true logstash_prefix ${tag} <buffer> @type file path /var/log/td-agent/buffer/es-condition-quotes flush_interval 5s flush_thread_count 2 </buffer> </match> </label> <label @condition-service> <filter condition-service> @type parser key_name Log reserve_data true emit_invalid_record_to_error false <parse> @type regexp expression /^(?<Log>.*)$/ </parse> </filter> <match condition-service> @type elasticsearch host XX.XX.XX.XX port 9200 logstash_format true logstash_prefix ${tag} <buffer> @type file path /var/log/td-agent/buffer/es-condition-service flush_interval 5s flush_thread_count 2 </buffer> </match> </label>
4. 重启服务生效
配置调整完成后执行systemctl start td-agent启动服务即可,后续所有采集的日志事件都会固定使用Log字段存储原始日志内容,不会再出现字段不存在的报错。
内容的提问来源于stack exchange,提问作者Bryan Chen
相关产品推荐
相关产品推荐

