Parsing Logstash:嵌套的grok搜索?将一个字段解析为多个字段?

Parsing Logstash:嵌套的grok搜索?将一个字段解析为多个字段?,parsing,logstash,logstash-grok,Parsing,Logstash,Logstash Grok,我有这样的日志条目 2014-02-25 00:00:03,936 INFO - something happened...bla bla bla 2014-02-25 00:00:03,952 INFO - ***Request Completed*** [ 78.002] mS [http://cloud.mydomain.local/schedule/search?param=45] 2014-02-25 00:00:04,233 INFO - something else ha

我有这样的日志条目

2014-02-25 00:00:03,936 INFO  - something happened...bla bla bla
2014-02-25 00:00:03,952 INFO  - ***Request Completed*** [   78.002] mS [http://cloud.mydomain.local/schedule/search?param=45]
2014-02-25 00:00:04,233 INFO  - something else happened...bla bla bla
grok {
    match => [ 
              "message", "%{TIMESTAMP_ISO8601:logdate} %{WORD:severity}%{SPACE}- \*\*\*Request Completed\*\*\* \[%{SPACE}%{NUMBER:elaspedms}\] mS \[%{URI:uri}\]",
              "message", "%{TIMESTAMP_ISO8601:logdate} %{WORD:severity}%{SPACE}- %{GREEDYDATA:body}"
             ]
}
我有一个grok过滤器,可以正确解析行

grok {
    match => [ "message", "%{TIMESTAMP_ISO8601:logdate} %{WORD:severity}%{SPACE}- %{GREEDYDATA:body}" ]
}
如果“body”以“***请求已完成***”开头,我想从“body”中解析附加数据。即'elaspsedms'和'uri'。我该怎么做

在其他地方,有人建议我在grok筛选器中添加另一个消息条目,如下所示

2014-02-25 00:00:03,936 INFO  - something happened...bla bla bla
2014-02-25 00:00:03,952 INFO  - ***Request Completed*** [   78.002] mS [http://cloud.mydomain.local/schedule/search?param=45]
2014-02-25 00:00:04,233 INFO  - something else happened...bla bla bla
grok {
    match => [ 
              "message", "%{TIMESTAMP_ISO8601:logdate} %{WORD:severity}%{SPACE}- \*\*\*Request Completed\*\*\* \[%{SPACE}%{NUMBER:elaspedms}\] mS \[%{URI:uri}\]",
              "message", "%{TIMESTAMP_ISO8601:logdate} %{WORD:severity}%{SPACE}- %{GREEDYDATA:body}"
             ]
}
…这是可行的,但对于计时线,“body”的值不设置。理想情况下,我希望body始终包含条目的最后一部分,如果条目是一条计时线,则执行elapsedms和uri的额外解析

你知道我该怎么做吗

是否有解析字段的方法?这样我就可以尝试将“body”解析为elapsedms/uri,如果失败,请继续。或者是否有方法在grok表达式中嵌套字段匹配

想法


编辑:如果设置了“elaspedms”,我是否可以从“elaspedms”和“uri”创建body,而不是确保始终设置“body”?

这是可行的。有更好的办法吗

grok {
   match => [ 
          "message", "%{TIMESTAMP_ISO8601:logdate} %{WORD:severity}%{SPACE}- \*\*\*Request Completed\*\*\* \[%{SPACE}%{NUMBER:elaspedms}\] mS \[%{URI:uri}\]",
          "message", "%{TIMESTAMP_ISO8601:logdate} %{WORD:severity}%{SPACE}- %{GREEDYDATA:body}"
         ]
}

# if body is NOT set (timing line) make one
if ![body] {
    mutate { 
        add_field => [ "body", "***Request Completed*** [%{elapsedms}] mS [%{uri}]"] 
    }
}

我认为您需要在grok中使用
break\u on\u match
选项并将其设置为false:

以下是已知的在Logstash 1.5.3中工作的更好方法:

grok {
   match => [ 
          "message", "%{TIMESTAMP_ISO8601:logdate} %{WORD:severity}%{SPACE}- %{GREEDYDATA:body}"
         ]
}

# if body is set (which should always be true, but it's good to check anyway)
if [body] {
    grok {
       break_on_match => true
       match => [ 
          "body", "\*\*\*Request Completed\*\*\* \[%{SPACE}%{NUMBER:elaspedms}\] mS \[%{URI:uri}\]"
         ]
    }
}
这样,每个记录都将有一个
正文
字段,但只有包含
“***请求已完成***”的行
将有
elapsedms
uri
字段。您可以使用子字段和子字段继续此逻辑,并尽可能深入到杂草中

我还包括了
“break\u on\u match”
语法,以防对您有所帮助。您可以将其设置为
true
false

关键是使用
正文
字段(或您正在解析的任何字段)作为匹配源,而不是
消息