Elastic Stack技术咨询:Logstash过滤与geoip配置问题
问题解决:Logstash过滤器配置优化
环境背景
.NET程序生成包含用户IP等键值对的JSON日志,通过log.json → Filebeat → Logstash → Elasticsearch → Kibana流程传输,现有Logstash配置如下:
input { beats { port => 5044 } } filter { json { source => "message" } geoip { source => "Portal-IPAddress" } mutate { remove_field => ["Timestamp","message","MessageTemplate","log.offset","@version"] } } output { elasticsearch { hosts => ["http://localhost:9200"] index => "%{[@metadata][beat]}-%{+YYYY.MM}" } stdout { codec => rubydebug } }
当前存在两个问题:
- 如何将
Properties中的所有键值对提取为独立顶层字段; - 使用
Portal-IPAddress进行GeoIP查询失败,即使填入有效IP也无法生效。
问题1:提取Properties中的所有字段
从Logstash输出可见,Properties是嵌套的键值对结构,要将其所有子字段提升为顶层字段,可使用Ruby过滤器遍历并添加:
在filter块中插入以下配置:
ruby { code => " event.get('Properties').each do |key, value| event.set(key, value) end " }
完成提取后,可通过mutate过滤器删除原Properties字段(按需选择是否保留):
mutate { remove_field => ["Properties"] }
问题2:修复GeoIP查询失败
原配置中geoip插件的source字段路径错误——Portal-IPAddress并非顶层字段,而是嵌套在Properties下,需修正为:
geoip { source => "Properties.Portal-IPAddress" }
注意:若使用IPv6地址(如示例中的::1),GeoIP插件可能无法解析,需确保传入的是有效IPv4地址或使用支持IPv6的GeoIP数据库。
完整修改后的Logstash配置
input { beats { port => 5044 } } filter { # 解析message中的JSON内容 json { source => "message" } # 提取Properties中的所有字段到顶层 ruby { code => " event.get('Properties').each do |key, value| event.set(key, value) end " } # 基于Properties中的Portal-IPAddress执行GeoIP查询 geoip { source => "Properties.Portal-IPAddress" } # 删除不需要的字段 mutate { remove_field => ["Timestamp", "message", "MessageTemplate", "log.offset", "@version", "Properties"] } } output { elasticsearch { hosts => ["http://localhost:9200"] index => "%{[@metadata][beat]}-%{+YYYY.MM}" } stdout { codec => rubydebug } }
验证结果
重启Logstash后,通过stdout的rubydebug输出可验证:
Properties中的所有字段已成为独立顶层字段;- 有效IP对应的
geoip字段(如geoip.city_name、geoip.country_name等)已生成。
内容的提问来源于stack exchange,提问作者Adrion Katon
相关产品推荐
相关产品推荐

