# dissect

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

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

## 示例

```
filter {
    dissect {
        mapping => {
            "message" => "%{ts} %{+ts} %{+ts} %{src} %{} %{prog}[%{pid}]: %{msg}"
        }
        convert_datatype => {
            pid => "int"
        }
    }
}
```

## 语法解释

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

* %{+key}

  这个 `+` 表示，前面已经捕获到一个 key 字段了，而这次捕获的内容，自动添补到之前 key 字段内容的后面。
* %{+key/2}

  这个 `/2` 表示，在有多次捕获内容都填到 key 字段里的时候，拼接字符串的顺序谁前谁后。`/2` 表示排第 2 位。
* %{?string}

  这个 `?` 表示，这块只是一个占位，并不会实际生成捕获字段存到 Event 里面。
* %{?string} %{\&string}

  当同样捕获名称都是 string，但是一个 `?` 一个 `&` 的时候，表示这是一个键值对。

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

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

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

```
{
  domain => "rizhiyi.com",
  id => "123"
}
```
