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

时间:2016-02-10 11:37:32

标签: logstash logstash-grok grok

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

如果我采用示例日志条目URL: "GET https://www.stackoverflow.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.stackoverflow.com"
    ]
  ],
  "BASE10NUM": [
    [
      "443"
    ]
  ],
  "http_site_url": [
    [
      "/some/link/here.html"
    ]
  ],
  "http_type": [
    [
      "HTTP"
    ]
  ]
}

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

所以总的来说,我正在寻求4个单独的输出:

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

http_site www.stackoverflow.com

http_site_port 443

http_site_url /some/link/here.html

有没有办法做到这一点?

1 个答案:

答案 0 :(得分:1)

首先,查看用于处理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})

它将分别捕获三个字段并从整个字符串中再创建一个字段。