Fluentd无法将解析日志写入MongoDB问题求助
解决Fluentd时间字段解析及MongoDB存储问题
看起来你碰到了两个关键问题:一是日志里的时间字段没出现在解析结果中,导致MongoDB无法正常存储;二是fluent-plugin-mongo的版本警告。我来一步步帮你搞定:
1. 修复时间字段缺失的问题
你的tail配置其实已经正确捕获了日志里的时间,但默认情况下Fluentd只会把这个捕获的时间作为事件的时间戳(就是你看到的输出开头那串2018-01-25 17:50:22.000000000 +0000),不会把time字段保留到最终的JSON记录里。而MongoDB需要这个字段存在(或者正确映射事件时间)才能顺利存储。
修改你的tail源配置,加上keep_time_key true参数,让Fluentd把捕获的时间字段保留到记录中:
<source> @type tail path /home/app-logs/dev/my-app/%Y/%b/dev-main.log tag request.main time_format %Y-%m-%d %H:%M:%S # 新增:保留捕获的time字段到解析后的JSON里 keep_time_key true format /^\[(?<time>[^\]]*)\] (?<ip-address>[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*) (?<request-method>\w*) (?<request-url>[^ ]*) (?<format>[^ ]*) (?<request-size>\d*) (?<user-agent>[^ ]*) (?<response-code>\d*) (?<response-duration>\d*)$/ pos_file /tmp/fluentd--1516882649.pos </source>
修改后,你会发现解析结果的JSON里多了"time":"2018-01-25 17:50:22"字段,这样MongoDB插件就能正确识别并存储这条记录了。
如果想让MongoDB把这个time字段存为Date类型(而不是字符串),可以在Mongo插件配置里再加两个参数:
<match request.*> @type mongo host 127.0.0.1 port 27017 user foo password bar database my-app collection requests capped capped_size 100m # 新增:指定用record里的time字段作为Mongo的时间字段,转为Date类型 time_key time time_type iso8601 </match>
2. 处理fluent-plugin-mongo的警告
这个警告是因为从v0.8版本开始,插件移除了无效记录检测功能(Mongo Driver v2.x不再支持该特性)——意思是如果发送给Mongo的记录不符合要求(比如字段类型错误、包含非法字符等),这些记录会直接丢失,不会被拦截提示。
要解决这个警告并避免丢数据,你可以这么做:
- 先确认你的解析结果是有效的JSON,字段名和数据类型都符合MongoDB要求(比如你的
ip-address带连字符是没问题的,Mongo支持这种字段名) - 添加
error_tag参数,把无效记录路由到其他地方(比如文件),方便排查问题:
<match request.*> @type mongo # 其他原有配置不变 error_tag mongo.error </match> # 新增配置:把无效记录存到文件里 <match mongo.error> @type file path /var/log/fluentd/mongo_errors.log </match>
3. 验证效果
改完配置后重启Fluentd,然后检查:
- 解析后的日志是否包含
time字段 - MongoDB里是否成功存储了日志记录
- 警告信息是否消失(或者无效记录被正确存到了错误日志里)
内容的提问来源于stack exchange,提问作者Veer Shrivastav
相关产品推荐
相关产品推荐

