Logstash数据流输出字段引用失效问题求助
我在编写logstash.conf将日志接入ELK栈时,在output配置里使用字段引用创建动态数据流,结果报错导致Logstash崩溃,报错信息如下:
Badly formatted index, after interpolation still contains placeholder: [logs-%{[@metadata][ds_dataset]}-default];
我不确定Logstash是否支持在数据流中使用字段引用,但使用索引模式配置时该功能正常。我的logstash.conf配置如下:
input { beats { port => 5044 } } filter { # 将需要的字段存入@metadata mutate { add_field => { "[@metadata][ds_dataset]" => "test" # 如果需要动态命名空间可以打开下面这行 # "[@metadata][ds_namespace]" => "%{[fields][namespace]}" } } } output { stdout { codec => rubydebug } elasticsearch { hosts => ["http://elasticsearch:9200"] data_stream => true data_stream_type => "logs" data_stream_dataset => "log-%{[@metadata][ds_dataset]}" data_stream_namespace => "default" # 可以改成: %{[@metadata][ds_namespace]} } }
原因与解决方法
Logstash的data_stream_dataset、data_stream_namespace这类数据流专属参数不支持直接使用%{field}格式的字段引用。这和索引模式的index参数逻辑不同:index参数会在处理事件时动态插值,但数据流的专属参数是在Logstash启动阶段就会校验格式,不会等到事件处理时替换占位符,因此会报错“占位符未被替换”。
有两种可行的解决方式:
方式一:用index参数指定完整数据流名称(推荐)
放弃单独配置data_stream_type/dataset/namespace,直接通过index参数指定符合规则的完整数据流名称,同时开启data_stream => true。index参数支持动态插值,完美适配动态场景:
output { stdout { codec => rubydebug } elasticsearch { hosts => ["http://elasticsearch:9200"] data_stream => true index => "logs-log-%{[@metadata][ds_dataset]}-default" } }
注意数据流名称必须严格遵循{type}-{dataset}-{namespace}的格式,示例中type为logs,dataset为log-%{[@metadata][ds_dataset]},namespace为default,完全符合Elasticsearch数据流的命名要求。
方式二:在filter阶段提前拼接好参数值
如果想保留数据流参数的写法,可以在filter阶段提前把dataset或namespace的完整值拼接完成,确保输出时没有残留的占位符:
filter { mutate { add_field => { "[@metadata][ds_dataset]" => "test" "[@metadata][full_dataset]" => "log-%{[@metadata][ds_dataset]}" # 如果需要动态命名空间可以打开下面这行 # "[@metadata][ds_namespace]" => "%{[fields][namespace]}" } } } output { stdout { codec => rubydebug } elasticsearch { hosts => ["http://elasticsearch:9200"] data_stream => true data_stream_type => "logs" data_stream_dataset => "%{[@metadata][full_dataset]}" data_stream_namespace => "default" } }
这种方式要保证filter阶段的字段插值完全完成,[@metadata][full_dataset]中不再有%{}格式的占位符。
内容的提问来源于stack exchange,提问作者Phạm Thanh Kiến

