我有以下格式的日志行,想要提取字段:
[field1: content1] [field2: content2] [field3: content3] ...
我既不知道字段名称,也不知道字段数。
我尝试使用反向引用和sprintf格式,但没有得到任何结果:
match => [ "message", "(?:\[(\w+): %{DATA:\k<-1>}\])+" ] # not working
match => [ "message", "(?:\[%{WORD:fieldname}: %{DATA:%{fieldname}}\])+" ] # not working
这似乎仅适用于一个领域而不是更多领域:
match => [ "message", "(?:\[%{WORD:field}: %{DATA:content}\] ?)+" ]
add_field => { "%{field}" => "%{content}" }
kv过滤器也不合适,因为字段的内容可能包含空格。
是否有任何插件/策略可以解决此问题?
答案 0 :(得分:8)
Logstash Ruby插件可以帮到你。 :)
以下是配置:
input {
stdin {}
}
filter {
ruby {
code => "
fieldArray = event['message'].split('] [')
for field in fieldArray
field = field.delete '['
field = field.delete ']'
result = field.split(': ')
event[result[0]] = result[1]
end
"
}
}
output {
stdout {
codec => rubydebug
}
}
使用您的日志:
[field1: content1] [field2: content2] [field3: content3]
这是输出:
{
"message" => "[field1: content1] [field2: content2] [field3: content3]",
"@version" => "1",
"@timestamp" => "2014-07-07T08:49:28.543Z",
"host" => "abc",
"field1" => "content1",
"field2" => "content2",
"field3" => "content3"
}
我尝试了4个字段,它也有效。
请注意,ruby代码中的event
是logstash事件。您可以使用它来获取所有事件字段,例如message, @timestamp
等。
享受它!!!
答案 1 :(得分:5)
我找到了使用正则表达式的另一种方式:
ruby {
code => "
fields = event['message'].scan(/(?<=\[)\w+: .*?(?=\](?: |$))/)
for field in fields
field = field.split(': ')
event[field[0]] = field[1]
end
"
}
答案 2 :(得分:0)
我知道这是一个旧帖子,但我今天刚看到它,所以我想我会提供一个替代方法。请注意,作为一项规则,我几乎总是使用 ruby 过滤器,如前两个答案中的任何一个所建议的。不过,我想我会提供这个作为替代方案。
如果有固定数量的字段或最大数量的字段(即可能少于三个字段,但永远不会超过三个字段),这可以通过组合{{1 }} 和 grok
过滤器,以及。
mutate
对于那些可能不熟悉正则表达式的人,# Test message is: `[fieldname: value]`
# Store values in [@metadata] so we don't have to explicitly delete them.
grok {
match => {
"[message]" => [
"\[%{DATA:[@metadata][_field_name_01]}:\s+%{DATA:[@metadata][_field_value_01]}\]( \[%{DATA:[@metadata][_field_name_02]}:\s+%{DATA:[@metadata][_field_value_02]}\])?( \[%{DATA:[@metadata][_field_name_03]}:\s+%{DATA:[@metadata][_field_value_03]}\])?"
]
}
}
# Rename the fieldname, value combinations. I.e., if the following data is in the message:
#
# [foo: bar]
#
# It will be saved in the elasticsearch output as:
#
# {"foo":"bar"}
#
mutate {
rename => {
"[@metadata][_field_value_01]" => "[%{[@metadata][_field_name_01]}]"
"[@metadata][_field_value_02]" => "[%{[@metadata][_field_name_02]}]"
"[@metadata][_field_value_03]" => "[%{[@metadata][_field_name_03]}]"
}
tag_on_failure => []
}
中的捕获是可选的正则表达式匹配,这意味着如果没有匹配,则表达式不会失败。 ()?
过滤器中的 tag_on_failure => []
选项可确保在重命名之一失败时不会将错误附加到 mutate
,因为没有要捕获的数据,因此没有要重命名的字段。