Logstash中为Elasticsearch索引生成小写字段且不修改原文档
解决Logstash用小写字段名做索引且不保留临时字段的问题
你猜的没错,问题根源就是那个remove_field!Logstash的执行流程是输入 → 过滤 → 输出,过滤阶段删掉appNameIndex之后,输出阶段根本访问不到这个字段了,所以索引名就变成了字面量%{appNameIndex},自然触发无效索引名的错误。
给你两种解决方案,优先推荐第一种,更符合Logstash的最佳实践:
方案1:使用@metadata临时字段(推荐)
@metadata是Logstash专门用来存储内部临时数据的特殊字段,它不会被写入到最终的Elasticsearch文档里,完全匹配你的需求。
修改后的配置如下:
input { stdin { type => stdin } } filter { csv { separator => " " columns => ["appName", "field1", "field2", ...] convert => { ... } } # 将appName复制到@metadata下的临时字段 mutate { copy => { "appName" => "[@metadata][appNameIndex]" } } # 对@metadata里的字段转小写 mutate { lowercase => ["[@metadata][appNameIndex]"] } # 这里不需要删除任何字段,@metadata的内容不会出现在最终文档中 } output { amazon_es { hosts => ["my-es-cluster.us-east-1.es.amazonaws.com"] # 引用@metadata里的小写字段作为索引名 index => "%{[@metadata][appNameIndex]}" region => "us-east-1" } }
这样配置后,既可以用小写的appName值作为索引名,最终写入ES的文档里也只会保留原始的appName字段,没有多余的临时字段。
方案2:在输出阶段删除临时字段
如果你不想用@metadata,也可以在输出插件里直接配置删除字段。amazon_es插件继承自官方的elasticsearch插件,支持remove_field参数,可以在写入ES时移除指定字段:
input { stdin { type => stdin } } filter { csv { separator => " " columns => ["appName", "field1", "field2", ...] convert => { ... } } mutate { copy => ["appName", "appNameIndex"] } mutate { lowercase => ["appNameIndex"] } # 这里不要删除字段,留着给输出阶段用 } output { amazon_es { hosts => ["my-es-cluster.us-east-1.es.amazonaws.com"] index => "%{appNameIndex}" region => "us-east-1" # 在写入ES时移除临时字段 remove_field => ["appNameIndex"] } }
这种方式也能达到效果,但临时字段会在过滤阶段之后一直存在,直到输出阶段才被移除,不如@metadata方案优雅。
内容的提问来源于stack exchange,提问作者sedavidw
相关产品推荐
相关产品推荐

