dissect

grok 作为 Logstash 最广为人知的插件,在性能和资源损耗方面同样也广为诟病。为了应对这个情况,同时也考虑到大多数时候,日志格式并没有那么复杂,Logstash 开发团队在 5.0 版新添加了另一个解析字段的插件:dissect。

当日志格式有比较简明的分隔标志位,而且重复性较大的时候,我们可以使用 dissect 插件更快的完成解析工作。下面是解析 syslog 的示例:

示例

  1. filter {
  2. dissect {
  3. mapping => {
  4. "message" => "%{ts} %{+ts} %{+ts} %{src} %{} %{prog}[%{pid}]: %{msg}"
  5. }
  6. convert_datatype => {
  7. pid => "int"
  8. }
  9. }
  10. }

语法解释

我们看到上面使用了和 Grok 很类似的 %{} 语法来表示字段,这显然是基于习惯延续的考虑。不过示例中 %{+ts} 的加号就不一般了。dissect 除了字段外面的字符串定位功能以外,还通过几个特殊符号来处理字段提取的规则:

  • %{+key}
    这个 + 表示,前面已经捕获到一个 key 字段了,而这次捕获的内容,自动添补到之前 key 字段内容的后面。
  • %{+key/2}
    这个 /2 表示,在有多次捕获内容都填到 key 字段里的时候,拼接字符串的顺序谁前谁后。/2 表示排第 2 位。
  • %{?string}
    这个 ? 表示,这块只是一个占位,并不会实际生成捕获字段存到 Event 里面。
  • %{?string} %{&string}
    当同样捕获名称都是 string,但是一个 ? 一个 & 的时候,表示这是一个键值对。

比如对 http://rizhiyi.com/index.do?id=123 写这么一段配置:

  1. http://%{domain}/%{?url}?%{?arg1}=%{&arg1}

则最终生成的 Event 内容是这样的:

  1. {
  2. domain => "rizhiyi.com",
  3. id => "123"
  4. }