如何在 Logstash 中获取部分 Filebeat 源文件名
How to get parts of Filebeat source filename in Logstash
我有一个 Filebeat 实例(7.5.0 版,运行在 Windows 服务器上运行)监控本地文件夹中的日志文件,并将此数据发送到 Logstash(7.5 版) .0,运行宁在 Docker 大陆)。在 Logstash 中,我想提取其中一个文件夹名称(最后一个)并将其添加为一个字段。
一个具体的例子是,从两个日志条目中,一个来自文件 d:\Logs\Foo\Bar\lorem\currentlog.txt
,一个来自文件 d:\Logs\Foo\Bar\ipsum\currentlog.txt
,我想提取值 lorem
和 ipsum
分别.
为此,我设置了以下(简化示例):
input {
pipeline { address => "test" }
}
filter {
grok {
match => { "source" => ".*\\.*\\(?<product>.*)\\.*" }
}
}
output {
stdout { codec => rubydebug }
}
我已经在多个地方(grockconstructor, grockdebug and rubular)测试了用于在源字段上查找匹配项(名为 product
)的正则表达式,它们似乎都产生了所需的结果:我使用路径中最后一个文件夹的预期值获得产品的命名匹配项。
但是,当我 运行 具有上述管道配置的 Logstash 时,它无法提取文件夹名称并将其值放入产品字段。相反,我看到一个标记被添加到 logstash 输出,其值为 grokparsefailure
,表明我的 grok 表达式有问题。但是我在上述参考工具中的所有测试表明我的表达没有任何问题...
完整的 logstash 输出如下所示:
{
"@version" => "1",
"tags" => [
[0]"beats_input_codec_plain_applied",
[1]"_grokparsefailure"
],
"host" => {
"name" => "test"
},
"message" => "Another line in the log",
"agent" => {
"id" => "e00d2f50-b10c-406a-a4fa-be381d15b869",
"ephemeral_id" => "28dfe105-b936-40de-bc97-16c4a9196e30",
"hostname" => "my-host",
"name" => "test",
"type" => "filebeat",
"version" => "7.5.0"
},
"@timestamp" => 2019 - 12 - 16T14: 04: 09.064Z,
"ecs" => {
"version" => "1.1.0"
},
"log" => {
"file" => {
"path" => "d:\Logs\Foo\Bar\ipsum\currentlog.txt"
},
"offset" => 21
},
"input" => {
"type" => "log"
}
}
我曾尝试将匹配项更改为 log.file.path
属性,但这给了我相同的 _grokparsefailure
标签。
我也很确定这适用于 Filebeat/Logstash 的早期安装(可能是一两个主要版本),但我记不清了。
所以问题是:为什么 Logstash 不能从 Filebeat 源中提取文件夹名称?有什么办法可以进一步调试这个 grok 问题吗?
上面的配置没有生效的原因是复合的,但我最终弄明白了:
首先,没有来自 Filebeat 的 source
字段(我很确定以前有一些版本,但那是另一回事),这显然会导致 grok 过滤器失败。
接下来,当我尝试在 log.file.path
字段上进行 grok 时,我使用了错误的语法。访问嵌套字段的正确方法是这样的:[log][file][path]
最后,即使输出显示 log.file.path
的值为 "d:\Logs\Foo\Bar\ipsum\currentlog.txt"
,双反斜杠显然已添加到输出管道的某处。因此,当我更改我的正则表达式以匹配单个反斜杠而不是双反斜杠时,它从 "d:\Logs\Foo\Bar\ipsum\currentlog.txt"
中正确地提取了 ipsum
我的最终管道配置如下所示:
input {
pipeline { address => "test" }
}
filter {
grok {
match => { "[log][file][path]" => ".*(\|\/).*(\|\/)(?<product>.*)(\|\/).*"}
}
}
output {
stdout { codec => rubydebug }
}
现在我成功获取了提取到 product
字段的路径中最后一个文件夹的名称,没有 _grokparsefailure
标记。
我有一个 Filebeat 实例(7.5.0 版,运行在 Windows 服务器上运行)监控本地文件夹中的日志文件,并将此数据发送到 Logstash(7.5 版) .0,运行宁在 Docker 大陆)。在 Logstash 中,我想提取其中一个文件夹名称(最后一个)并将其添加为一个字段。
一个具体的例子是,从两个日志条目中,一个来自文件 d:\Logs\Foo\Bar\lorem\currentlog.txt
,一个来自文件 d:\Logs\Foo\Bar\ipsum\currentlog.txt
,我想提取值 lorem
和 ipsum
分别.
为此,我设置了以下(简化示例):
input {
pipeline { address => "test" }
}
filter {
grok {
match => { "source" => ".*\\.*\\(?<product>.*)\\.*" }
}
}
output {
stdout { codec => rubydebug }
}
我已经在多个地方(grockconstructor, grockdebug and rubular)测试了用于在源字段上查找匹配项(名为 product
)的正则表达式,它们似乎都产生了所需的结果:我使用路径中最后一个文件夹的预期值获得产品的命名匹配项。
但是,当我 运行 具有上述管道配置的 Logstash 时,它无法提取文件夹名称并将其值放入产品字段。相反,我看到一个标记被添加到 logstash 输出,其值为 grokparsefailure
,表明我的 grok 表达式有问题。但是我在上述参考工具中的所有测试表明我的表达没有任何问题...
完整的 logstash 输出如下所示:
{
"@version" => "1",
"tags" => [
[0]"beats_input_codec_plain_applied",
[1]"_grokparsefailure"
],
"host" => {
"name" => "test"
},
"message" => "Another line in the log",
"agent" => {
"id" => "e00d2f50-b10c-406a-a4fa-be381d15b869",
"ephemeral_id" => "28dfe105-b936-40de-bc97-16c4a9196e30",
"hostname" => "my-host",
"name" => "test",
"type" => "filebeat",
"version" => "7.5.0"
},
"@timestamp" => 2019 - 12 - 16T14: 04: 09.064Z,
"ecs" => {
"version" => "1.1.0"
},
"log" => {
"file" => {
"path" => "d:\Logs\Foo\Bar\ipsum\currentlog.txt"
},
"offset" => 21
},
"input" => {
"type" => "log"
}
}
我曾尝试将匹配项更改为 log.file.path
属性,但这给了我相同的 _grokparsefailure
标签。
我也很确定这适用于 Filebeat/Logstash 的早期安装(可能是一两个主要版本),但我记不清了。
所以问题是:为什么 Logstash 不能从 Filebeat 源中提取文件夹名称?有什么办法可以进一步调试这个 grok 问题吗?
上面的配置没有生效的原因是复合的,但我最终弄明白了:
首先,没有来自 Filebeat 的 source
字段(我很确定以前有一些版本,但那是另一回事),这显然会导致 grok 过滤器失败。
接下来,当我尝试在 log.file.path
字段上进行 grok 时,我使用了错误的语法。访问嵌套字段的正确方法是这样的:[log][file][path]
最后,即使输出显示 log.file.path
的值为 "d:\Logs\Foo\Bar\ipsum\currentlog.txt"
,双反斜杠显然已添加到输出管道的某处。因此,当我更改我的正则表达式以匹配单个反斜杠而不是双反斜杠时,它从 "d:\Logs\Foo\Bar\ipsum\currentlog.txt"
ipsum
我的最终管道配置如下所示:
input {
pipeline { address => "test" }
}
filter {
grok {
match => { "[log][file][path]" => ".*(\|\/).*(\|\/)(?<product>.*)(\|\/).*"}
}
}
output {
stdout { codec => rubydebug }
}
现在我成功获取了提取到 product
字段的路径中最后一个文件夹的名称,没有 _grokparsefailure
标记。