情况:
我的输入日志如下所示:
{
"key1":"value1"
"key2":"value2"
"events":
[{
"Level":"Information",
"Code":"100"
},
{
"Level":"Information",
"SomeKey":"SomeValue"
},
{
"Level":"Error",
"Message":"Something went wrong"
}
]}
我想:
拆分事件数组以创建单个对象,其中所有外层字段仍然填充(key1和key2)。
分割后选择性地删除日志。我只想保留“信息级”日志,如果它们包含“代码”属性。
我的logstash配置看起来像
filter {
split {
field => "[events]"
}
}
filter {
if ![events][Code]
{ drop {} }
}
output {
elasticsearch {}
}
问题:
Logstash似乎在执行第二个过滤器之前不会分隔事件。
换句话说,如果日志中的任何事件没有“代码”字段,则会删除整个日志,包括我必须保留的“错误”级别信息。
我已经待了大约一整天了,这让我很紧张。我会手动尝试创建自己的插件,但我从未使用任何Ruby。
我很确定这无关紧要,但我在Docker中运行ELK堆栈。我确信配置文件正确加载并且它们被Logstash使用。
答案 0 :(得分:0)
这实际上似乎是某种logstash错误。这是一个错误的演示:
配置文件:
input {
stdin { codec => "json" }
}
filter {
split { field => "events" }
if ([events] == "" or [events][Code] == "") {
drop {}
}
}
output {
stdout { codec => "rubydebug" }
}
命令行:
echo '{"key1":"value1","key2":"value2","events":[{"Level":"Information","Code":"100"},{"Level":"Information","SomeKey":"SomeValue"},{"Level":"Error","Message":"Something went wrong"}]}' | bin/logstash -f test.conf
结果:
Exception in thread "[main]>worker7" java.lang.NumberFormatException: For input string: "Code"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at org.logstash.Accessors.fetch(Accessors.java:130)
at org.logstash.Accessors.get(Accessors.java:20)
at org.logstash.Event.getUnconvertedField(Event.java:160)
at org.logstash.ext.JrubyEventExtLibrary$RubyEvent.ruby_get_field(JrubyEventExtLibrary.java:113)
at org.logstash.ext.JrubyEventExtLibrary$RubyEvent$INVOKER$i$1$0$ruby_get_field.call(JrubyEventExtLibrary$RubyEvent$INVOKER$i$1$0$ruby_get_field.gen)
所以基本上它仍然认为事件是一个数组,它试图通过“代码”
对其进行索引这似乎解决了这个问题:
mutate {
add_field => ["code", "%{[events][Code]}"]
}
if ([code] == "%{[events][Code]}") {
drop {}
}
mutate {
remove_field => ["code"]
}