我有一个日志文件,其中包含以时间戳开头的行。每个这样的带时间戳的行可能会有不确定数量的额外行:
SOMETIMESTAMP some data
extra line 1 2
extra line 3 4
额外的行将为带时间戳的行提供补充信息。我想提取1,2,3和4并将它们保存为变量。如果我知道有多少行,我可以将额外的行解析成变量。例如,如果我知道有两个额外的行,下面的grok过滤器将起作用。但如果我事先不知道会有多少额外的线路,我该怎么办呢?在应用多线过滤器之前,是否有某种方法可以逐个解析这些线?这可能有所帮助。
另外,即使我知道我只会有2条额外的线路,过滤器下面的过滤器是否最好?
filter {
multiline {
pattern => "^%{SOMETIMESTAMP}"
negate => "true"
what => "previous"
}
if "multiline" in [tags] {
grok {
match => { "message" => "(?m)^%{SOMETIMESTAMP} %{DATA:firstline}(?<newline>[\r\n]+)%{DATA:secondline}(?<newline>[\r\n]+)%{DATA:thirdline}$" }
}
}
# After this would be grok filters to process the contents of
# 'firstline', 'secondline', and 'thirdline'. I would then remove
# these three temporary fields from the final output.
}
(我将这些行分成单独的变量,因为这样我可以分别对行的内容进行额外的模式匹配,而不必再次参考整个模式。例如,基于第一个的内容我可能想要为其他行提供分支行为。)
答案 0 :(得分:1)
你为什么需要这个?
您是要插入一个包含所有值的单个事件,还是它们真的是单独的事件,只需要共享相同的时间戳?
如果它们都需要出现在同一事件中,您需要求助于ruby
过滤器将额外的行分隔到事件的字段中,然后您可以继续处理。
例如:
if "multiline" in [tags] {
grok {
match => { "message" => "(?m)^%{SOMETIMESTAMP} %{DATA:firstline}(?<newline>[\r\n]+)" }
}
ruby {
code => '
event["lines"] = event["message"].scan(/[^\r\n]+[\r\n]*/);
'
}
}
如果它们确实是单独的事件,您可以使用memorize插件来执行logstash 1.5及更高版本。
答案 1 :(得分:0)
这已更改为ELK版本 直接事件字段引用(即event ['field'])已被禁用,有利于使用事件get和set方法(例如event.get('field'))。
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:logtime} %{LOGLEVEL:level}%{DATA:firstline}" }
}
ruby { code => "event.set('message', event.get('message').scan(/[^\r\n]+[\r\n]*/))" }
}