Logstash匹配文件路径失效求助:Filebeat传输时if条件不生效
问题原因与解决方案
我之前也碰到过一模一样的坑,咱们来拆解下问题所在:
核心原因:字段来源不一致
Logstash的file输入插件(本地读日志)会自动生成嵌套字段[log][file][path]来存储文件路径,但Filebeat发送到Logstash的日志,默认是把文件路径存在source这个顶级字段里,根本没有[log][file][path]这个字段——这就是你的if条件被跳过的原因。
你可以去Kibana的文档详情里核对:本地读取的日志会有[log][file][path]字段,而Filebeat传过来的日志里,只有source字段的值是/var/log/commands.log,你的判断条件自然永远不成立。
三种可行的解决方法
方法1:直接用source字段做判断
这是最简单直接的方式,修改Logstash的过滤规则:
if [source] == "/var/log/commands.log" { grok{ match => { "message" => "*some grok stuff*" } } }
方法2:统一字段(兼容本地和Filebeat输入)
如果你希望不管是本地读还是Filebeat传的日志,都用同一个字段判断,可以在Logstash里把source的值复制到[log][file][path]字段:
# 在grok过滤之前添加这个mutate操作 mutate { add_field => { "[log][file][path]" => "%{source}" } } # 然后继续使用你原来的if条件 if [log][file][path] == "/var/log/commands.log" { grok{ match => { "message" => "*some grok stuff*" } } }
这样不管是哪种输入方式,[log][file][path]都会有正确的路径值。
方法3:在Filebeat里自定义字段
如果你的日志路径是固定的,也可以在Filebeat配置里添加自定义字段,比如:
# Filebeat配置文件中添加 fields: log_file_path: "/var/log/commands.log"
然后在Logstash里判断这个自定义字段:
if [fields][log_file_path] == "/var/log/commands.log" { grok{ match => { "message" => "*some grok stuff*" } } }
这种方式适合需要区分不同来源日志的场景,但灵活性不如前两种。
验证建议
可以在Logstash的output里临时添加stdout输出,看看日志的完整字段结构:
output { stdout { codec => rubydebug } # 保留你原来的Elasticsearch输出 elasticsearch { # ...你的配置 } }
启动Logstash后,就能在控制台看到Filebeat传过来的所有字段,确认source或者其他字段的具体情况。
内容的提问来源于stack exchange,提问作者HeadTea
相关产品推荐
相关产品推荐

