Logstash:从可选行读取多行数据

时间:2015-06-17 13:54:10

标签: logstash logstash-grok

我有一个日志文件,其中包含以时间戳开头的行。每个这样的带时间戳的行可能会有不确定数量的额外行:

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.
}

(我将这些行分成单独的变量,因为这样我可以分别对行的内容进行额外的模式匹配,而不必再次参考整个模式。例如,基于第一个的内容我可能想要为其他行提供分支行为。)

2 个答案:

答案 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]*/))" }
}