从单个 grok 查询中分离输出值?

Separate output values from a single grok query?

我一直在使用 logstash 捕获网络日志,特别是我正在尝试捕获网络 URLs,但也将它们分开。

如果我以日志条目为例 URL: "GET https://www.whosebug.com:443/some/link/here.html HTTP/1.1"

我使用这个 grok 模式:

\"(?:%{NOTSPACE:http_method}|-)(?:%{SPACE}http://)?(?:%{SPACE}https://)?(%{NOTSPACE:http_site}:)?(?:%{NUMBER:http_site_port:int})?(?:%{GREEDYDATA:http_site_url})? (?:%{WORD:http_type|-}/)?(?:%{NOTSPACE:http_version:float})?(?:%{SPACE})?\"

我明白了:

{
  "http_method": [
    [
      "GET"
    ]
  ],
  "SPACE": [
    [
      " ",
      null,
      ""
    ]
  ],
  "http_site": [
    [
      "www.whosebug.com"
    ]
  ],
  "BASE10NUM": [
    [
      "443"
    ]
  ],
  "http_site_url": [
    [
      "/some/link/here.html"
    ]
  ],
  "http_type": [
    [
      "HTTP"
    ]
  ]
}

问题是,我正在尝试 ALSO 捕获整个 URL: https://www.whosebug.com:443/some/link/here.html

总的来说,我正在寻找 4 个独立的输出:

http_site_complete https://www.whosebug.com:443/some/link/here.html

http_site www.whosebug.com

http_site_port 443

http_site_url /some/link/here.html

有什么办法吗?

首先,查看用于处理 URL 的内置模式。在您的模式中放入类似 URIHOST 的东西将更容易阅读和维护一堆 od WORD 或 NOTSPACE。

其次,一旦你有很多小字段,你总是可以使用 logstash 的过滤器来操作它们。您可以使用:

 mutate {
     add_field => { "http_site_complete", "%{http_site}:%{http_site_port}%{http_site_url}" }
     }
 }

或者您可以使用正则表达式并使用命名组:

(?<total>%{WORD:wordOne} %{WORD:wordTwo} %{WORD:wordThree})

这将分别捕获三个字段并从整个字符串中再生成一个字段。