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

时间:2014-02-28 13:32:04

标签: 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 happened...bla bla bla

我有一个正确解析行的grok过滤器......

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

如果'body'以“*** Request Completed ***”开头,我想从'body'中解析其他数据。即'elaspsedms'和'uri'。我怎么能这样做?

在其他地方建议我向grok过滤器添加另一个消息条目,如下所示......

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'的值确实 NOT 设置。理想情况下,我希望body 始终包含条目的最后一部分,而iff,条目是一个时间线,执行额外的elapsed和uri解析。

我有什么想法可以做到这一点吗?

有解析字段的方法吗?这样我就可以尝试将'body'解析为elapsed / uri,如果失败,继续。或者有没有办法在grok表达式中嵌套字段匹配?

思想?

编辑:如果设置'elaspedms',我可以直接从'elaspedms'和'uri'创建body吗?

3 个答案:

答案 0 :(得分:3)

这很有效。还有更好的方法吗?

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}]"] 
    }
}

答案 1 :(得分:1)

以下是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}\]"
         ]
    }
}

这样,每条记录都会有body字段,但只有包含"***Request Completed***"的行会有elapsedmsuri字段。您可以使用子子字段和子子子字段继续使用此逻辑,直到您喜欢的杂草。

我还包含了"break_on_match"语法,以防有用。您可以将其设置为truefalse

关键是使用body字段(或您要解析的字段)作为匹配源,而不是message

答案 2 :(得分:0)

我相信你需要在grok中使用break_on_match选项并将其设置为false:http://logstash.net/docs/1.4.2/filters/grok#break_on_match