(Logstash,Grok)如果字段包含特定单词,则从中保存一些字符

时间:2016-10-10 16:12:42

标签: apache logstash logstash-grok grok

我有以下过滤器可以满足我的大部分需求:

过滤器{
grok {
    match => { "message" => [ "%{IPORHOST:clientip} - %{NGUSER:user} \[%{HTTPDATE:timestamp}\] (?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest}) %{NUMBER:response} (?:%{NUMBER:bytes}|-) (-|(%{DATA:referrer})) ] }

但是,我正在解析的一些(并非所有)日志包含用户在我的Apache服务器上使用的频道的名称。

包含“频道”一词的正常日志如下:

10.40.80.11 - alex@example.com [03 / Jan / 2014:13:08:21 +0000]“GET / cgi-bin / feed / epg?channel = Bloomberg%20English& date = 2016-01- 03 HTTP / 1.1“200 368”http://example.net/cgi-bin/feed/epg“”Mozilla / 5.0“

字段“rawrequest”保存在单独的字段中,如下所示:

“GET / cgi-bin / feed / epg?channel = Bloomberg%20English& date = 2016-04-04 HTTP / 1.1”

问题: 考虑到并非所有日志都包含字段“rawrequest”中的单词channel,我如何在单独的字段中保存频道名称?。

我已经看过很多例子,但没有相似之处。将频道与字符串其余部分分开的字符是“&”。 我将不胜感激任何帮助。

解决方案:

match => { "request" => [ "channel=(?<Channels>[^&]+)" ] }

1 个答案:

答案 0 :(得分:1)

你现有的grok正在创建字段。您可以使用另一个grok从那些字段创建更多字段。正如

这样的正则表达式
channel=(?<myField>[^&]+)

应该有效,所以你的grok可能看起来像这样(未经测试):

grok {
    match => { "request" => [ "channel=(?<myField>[^&]+)" ] }
}

这会让你成为一个名为'myField'的新领域。根据需要重命名。

另一种选择是使用更具体的内置模式而不是NOTSPACE来更改原始的grok模式。查看URI模式。不幸的是,该模式不会为您创建字段,因此您必须对其进行修改。如果您将URIPATHPARAM信息放在另一个字段中,则可以在其上使用kv {}过滤器并将所有对解析为它们自己的字段。

很多选择......