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

Logstash:从可选行读取多行数据,logstash,logstash-grok,Logstash,Logstash Grok,我有一个日志文件,其中包含以时间戳开头的行。不确定的额外行数可能跟在每个这样的时间戳行之后: SOMETIMESTAMP some data extra line 1 2 extra line 3 4 额外的行将为时间戳行提供补充信息。我想提取1、2、3和4,并将它们保存为变量。如果我知道有多少额外的行,我可以将它们解析为变量。例如,如果我知道有两个额外的行,下面的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.
}
过滤器{
多行{
模式=>“^%{SOMETIMESTAMP}”
否定=>“真”
什么=>“以前的”
}
如果[标记]中有“多行”{
格罗克{
match=>{“message”=>“(?m)^%{SOMETIMESTAMP}%{DATA:firstline}(?[\r\n]+)%{DATA:secondline}(?[\r\n]+)%{DATA:thirdline}$}
}
}
#在此之后,将使用grok过滤器来处理
#“firstline”、“secondline”和“thirdline”。然后我会删除
#这三个临时字段来自最终输出。
}

(我将行分隔为单独的变量,因为这允许我单独对行的内容进行额外的模式匹配,而不必再次引用整个模式。例如,基于第一行的内容,我可能希望显示其他行的分支行为。)你为什么需要这个

您是要插入一个包含所有值的单一事件,还是它们真的是需要共享同一时间戳的独立事件

如果它们都需要出现在同一个事件中,您可能需要使用
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]*/);
       '
    }
}
如果[标记]中的“多行”{
格罗克{
match=>{“message”=>“(?m)^%{SOMETIMESTAMP}%{DATA:firstline}(?[\r\n]+)”}
}
红宝石{
代码=>'
事件[“行”]=事件[“消息”]。扫描(/[^\r\n]+[\r\n]*/);
'
}
}

如果它们是真正独立的事件,您可以使用logstash 1.5及更高版本的插件。

这在ELK版本中有所改变 已禁用直接事件字段引用(即event['field']),以支持使用event get和set方法(例如event.get('field'))


编辑以添加*而不是+--这样结尾的换行符是可选的。将行分隔为行数组后,是否有方法对该数组中的每一行应用grok筛选器?因此,我可以从输入数据中获得1、2、3和4。看起来您应该能够使用%{[lines][1]}(请参阅)。此外,您可能还使用了拆分过滤器,而不是ruby filterNice find。。。但是,有没有办法将其应用于任意数量的行?所以,我可以在%{[lines][1]}和%{[lines][2]}等上运行一个grok过滤器——正如我碰巧拥有的一样多的额外行,因为这个数字是任意的。你在ruby过滤器中拥有ruby的全部功能,所以你可以做任何你想做的事情。但是在logstash配置语言中没有循环构造。
filter {
    grok {
        match => { "message" => "%{TIMESTAMP_ISO8601:logtime} %{LOGLEVEL:level}%{DATA:firstline}" }
    }
    ruby { code => "event.set('message', event.get('message').scan(/[^\r\n]+[\r\n]*/))" }
}