获取在logstash中的grok中匹配的模式的名称

时间:2016-06-28 18:29:33

标签: logstash logstash-grok grok

如果我的模式文件包含许多正则表达式模式,例如以下

A .*foo.*
B .*bar.*
C .*baz.*

我的grok过滤器如下所示:

grok {
  patterns_dir => ["/location/of/patterns"]
  match => { "request" => [ "%{A}", "%{B}", "%{C}",] 
 }
}

有没有办法知道哪一个匹配。即SYNTAX的名称。我想用匹配

的名称来注释文档

2 个答案:

答案 0 :(得分:1)

您通常会做的是命名匹配的变量。其语法如下:

(举个例子):

grok {
    patterns_dir => ["/location/of/patterns"]
    match => 
    { 
        "request" => [ "%{A:A}", "%{B:NameOfB}", "%{C:SomeOtherName}",] 
    }
}

因此,您的grok的匹配现在将被命名为:

A:A

B:NameOfB

C:SomeOtherName

因此,在您的情况下,您可以在模式之后命名它们。这应该工作得很好。

或者(我刚用grok调试器测试过)看来,如果你没有为匹配的模式命名,它们将默认为模式的名称(我认为是你想要的)。这种情况的缺点是,如果重用模式,结果将是一个值数组。

这是我跑的测试:

输入:

 Caused by: com.my.application.IOException: null Caused by: com.my.application.IOException: null asd asd

神交:

(.*?)Caused by:%{GREEDYDATA}:%{GREEDYDATA}

输出:

{
  "GREEDYDATA": [
    [
      " com.my.application.IOException: null Caused by: com.my.application.IOException",
      " null asd asd"
    ]
  ]
}

希望能解决你的问题,

阿图尔

编辑:

基于OP的另一个问题是我动态解决该问题的方法。

您仍需要匹配名称。确定如何命名匹配的通用前缀。我将我的示例基于2个json字符串,以使这更容易:

{"a" : "b", "prefix_patterna" : "", "prefix_patternb" : "bla"}
{"a" : "b", "prefix_patterna" : "sd", "prefix_patternb" : ""}

请注意,有2个人工匹配,prefix_patternaprefix_patternb。所以,我决定使用前缀“prefix”,我用它来识别要检查的事件字段。 (如果这是你想要的东西,你可以去掉空事件)。

然后在我的过滤器中,我使用ruby迭代所有事件以找到与我的模式匹配的事件:

ruby {
    code => "
         toAdd = nil;
         event.to_hash.each { |k,v|
              if  k.start_with?('prefix_') && v.to_s != ''
                  toAdd = k
              end
         }
         if toAdd.to_s != ''
             event['test'] = toAdd
         end
    "
}

所有这些代码都是检查前缀的事件键,并查看该字段的值是空还是零。如果它找到具有值的字段,则将其写入名为“test”的新事件字段。

以下是我的测试:

Settings: Default pipeline workers: 8
Pipeline main started
{"a" : "b", "prefix_patterna" : "sd", "prefix_patternb" : ""}
{
            "message" => "{\"a\" : \"b\", \"prefix_patterna\" : \"sd\", \"prefix_patternb\" : \"\"}",
           "@version" => "1",
         "@timestamp" => "2016-09-15T09:48:29.418Z",
               "host" => "pandaadb",
                  "a" => "b",
    "prefix_patterna" => "sd",
    "prefix_patternb" => "",
               "test" => "prefix_patterna"
}
{"a" : "b", "prefix_patterna" : "", "prefix_patternb" : "bla"}
{
            "message" => "{\"a\" : \"b\", \"prefix_patterna\" : \"\", \"prefix_patternb\" : \"bla\"}",
           "@version" => "1",
         "@timestamp" => "2016-09-15T09:48:36.359Z",
               "host" => "pandaadb",
                  "a" => "b",
    "prefix_patterna" => "",
    "prefix_patternb" => "bla",
               "test" => "prefix_patternb"
}

注意第一个测试如何写入“prefix_patterna”,而第二个测试写入“prefix_patternb”。

我希望这能解决你的问题,

Artur

答案 1 :(得分:0)

您可以通过多个grok过滤器标记匹配,(或添加字段),如下所示。

它不太优雅,不易扩展,因为它容易重复(不是DRY),但似乎是“标记”复杂模式匹配的唯一方法 - 尤其是预定义的库模式。 / p>

请注意,您必须向后续过滤器添加条件,以避免在先前过滤器已匹配时也运行它们。否则你仍然会为后来的过滤器获得_grokparsefailure标签。 Source

您还需要删除除最终“else”过滤器之外的所有故障标记。否则你会得到假的_grokparsefailures,例如来自A时B或C匹配。 Source

grok {
    patterns_dir => ["/location/of/patterns"]
    match => { "request" => "%{A}"
    add_tag => [ "pattern_A" ]
    add_field => { "pattern" => "A" } # another option
    tag_on_failure => [ ] # prevent false failure tags
}
if ("pattern_A" not in [tags]) {
    grok {
        patterns_dir => ["/location/of/patterns"]
        match => { "request" => "%{B}"
        add_tag => [ "pattern_B" ]
        tag_on_failure => [ ] # prevent false failure tags
     }
}
if (["pattern_A","pattern_B"] not in [tags]) {
    grok {
        patterns_dir => ["/location/of/patterns"]
        match => { "request" => "%{C}"
        add_tag => [ "pattern_C" ]
     }
}

可能有一些方法可以简化/调整这个,但我不是专家(还是!)。