获取在 logstash 的 grok 中匹配的模式名称
get name of pattern that matched in grok in logstash
如果我有一个带有一堆正则表达式模式的模式文件,如下所示
A .*foo.*
B .*bar.*
C .*baz.*
我的 grok 过滤器如下所示:
grok {
patterns_dir => ["/location/of/patterns"]
match => { "request" => [ "%{A}", "%{B}", "%{C}",]
}
}
有什么方法可以知道哪一个匹配。即 SYNTAX 的名称。我想用匹配的名称注释文档
你通常会做的是命名匹配的变量。其语法为:
(以你为例):
grok {
patterns_dir => ["/location/of/patterns"]
match =>
{
"request" => [ "%{A:A}", "%{B:NameOfB}", "%{C:SomeOtherName}",]
}
}
因此,您的 grok 匹配现在将命名为:
一个:一个
B: NameOfB
C: 其他名字
因此在您的情况下,您可以根据模式命名它们。那应该可以正常工作。
或者(我刚刚用 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_patterna
和 prefix_patternb
。因此,我决定使用前缀 "prefix" 并使用它来确定要检查的事件字段。 (如果你想要的话,你也可以 grok 删除空事件)。
然后在我的过滤器中,我使用 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
"
}
这段代码所做的就是检查前缀的事件键,并查看该字段的值是否为空或 nil。如果找到具有值的字段,它会将其写入名为 "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"。
希望这能解决您的问题,
阿图尔
您可以通过使用多个 grok 过滤器来标记匹配(或添加字段),如下所示。
感觉不太优雅,可扩展性不强,因为它容易出现大量重复(不是 DRY),但似乎是 "flag" 匹配复杂模式的唯一方法 - 特别是预定义的库模式。
请注意,您必须向后续过滤器添加条件,以避免在先前的过滤器已经匹配时它们也成为 运行。否则你仍然会为后面的过滤器获得 _grokparsefailure 标签。 Source
您还需要删除除最终 "else" 过滤器之外的所有过滤器的失败标记。否则你会得到虚假的 _grokparsefailures 例如当 B 或 C 匹配时来自 A。 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" ]
}
}
可能有一些方法可以简化/调整它,但我不是专家(还!)。
如果我有一个带有一堆正则表达式模式的模式文件,如下所示
A .*foo.*
B .*bar.*
C .*baz.*
我的 grok 过滤器如下所示:
grok {
patterns_dir => ["/location/of/patterns"]
match => { "request" => [ "%{A}", "%{B}", "%{C}",]
}
}
有什么方法可以知道哪一个匹配。即 SYNTAX 的名称。我想用匹配的名称注释文档
你通常会做的是命名匹配的变量。其语法为:
(以你为例):
grok {
patterns_dir => ["/location/of/patterns"]
match =>
{
"request" => [ "%{A:A}", "%{B:NameOfB}", "%{C:SomeOtherName}",]
}
}
因此,您的 grok 匹配现在将命名为:
一个:一个
B: NameOfB
C: 其他名字
因此在您的情况下,您可以根据模式命名它们。那应该可以正常工作。
或者(我刚刚用 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_patterna
和 prefix_patternb
。因此,我决定使用前缀 "prefix" 并使用它来确定要检查的事件字段。 (如果你想要的话,你也可以 grok 删除空事件)。
然后在我的过滤器中,我使用 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
"
}
这段代码所做的就是检查前缀的事件键,并查看该字段的值是否为空或 nil。如果找到具有值的字段,它会将其写入名为 "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"。
希望这能解决您的问题,
阿图尔
您可以通过使用多个 grok 过滤器来标记匹配(或添加字段),如下所示。
感觉不太优雅,可扩展性不强,因为它容易出现大量重复(不是 DRY),但似乎是 "flag" 匹配复杂模式的唯一方法 - 特别是预定义的库模式。
请注意,您必须向后续过滤器添加条件,以避免在先前的过滤器已经匹配时它们也成为 运行。否则你仍然会为后面的过滤器获得 _grokparsefailure 标签。 Source
您还需要删除除最终 "else" 过滤器之外的所有过滤器的失败标记。否则你会得到虚假的 _grokparsefailures 例如当 B 或 C 匹配时来自 A。 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" ]
}
}
可能有一些方法可以简化/调整它,但我不是专家(还!)。