Elasticsearch:Dissect 和 Grok 处理器之间的区别
Posted 中国社区官方博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch:Dissect 和 Grok 处理器之间的区别相关的知识,希望对你有一定的参考价值。
针对很多情况我们可以直接使用 Dissect 处理器来对非结构化化的日志进行结构化。在我之前的文章 “Elasticsearch:深入理解 Dissect ingest processor” 有做笔记深入的讲解。在很多的情况下,我们也可以使用 Grok 处理器来进行结构化。那么这两者之间有什么区别呢?在实际的使用中,我们到底首先哪一个呢?
一般来说,我们需要首先 Dissect 处理器,这是因为它的速度比 Grok 要快很多。Grok 是基于正则匹配,执行速度比 Dissect 要蛮很多。当然 Grok 也有自己的独到之处。它可以同时使用多个 patterns 来对日志来进行匹配。这个是 Dissect 不具备的能力。
下面,我们使用一些简单的例子来进行展示。
展示
我们可以使用 Dissect 处理器来对如下的日志来进行格式化。我们知道 Dissect 处理器对空格非常敏感。如果匹配不对,就会解析失败。
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"dissect": {
"field": "message",
"pattern": "%{@timestamp->} %{status}"
}
}
]
},
"docs": [
{
"_source": {
"message": "2019-09-29 STATUS_OK"
}
},
{
"_source": {
"message": "2019-09-29 STATUS_OK"
}
}
]
}
在上面,尽管两个 message 的格式有所不同,但是我们使用了 -> 来避免错误的解析。上面命令显示的结果为:
{
"docs" : [
{
"doc" : {
"_index" : "_index",
"_type" : "_doc",
"_id" : "_id",
"_source" : {
"@timestamp" : "2019-09-29",
"message" : "2019-09-29 STATUS_OK",
"status" : "STATUS_OK"
},
"_ingest" : {
"timestamp" : "2021-07-20T01:29:27.141784Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_doc",
"_id" : "_id",
"_source" : {
"@timestamp" : "2019-09-29",
"message" : "2019-09-29 STATUS_OK",
"status" : "STATUS_OK"
},
"_ingest" : {
"timestamp" : "2021-07-20T01:29:27.14179Z"
}
}
}
]
}
上面的解析,我们也可以使用 Grok 处理器来进行解析:
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"grok": {
"field": "message",
"patterns": [
"%{EVENTDATE:@timestamp} %{WORD:status}"
],
"pattern_definitions": {
"EVENTDATE": "%{YEAR}-%{MONTHNUM}-%{MONTHDAY}"
}
}
}
]
},
"docs": [
{
"_source": {
"message": "2019-09-29 STATUS_OK"
}
}
]
}
在上面,我们使用了定制的 pattern 来完成对 @timestamp 的解析。你可以进一步阅读 “Elastic:在 Grok 中运用 custom pattern 来定义 pattern”。上面运行的结果为:
{
"docs" : [
{
"doc" : {
"_index" : "_index",
"_type" : "_doc",
"_id" : "_id",
"_source" : {
"@timestamp" : "2019-09-29",
"message" : "2019-09-29 STATUS_OK",
"status" : "STATUS_OK"
},
"_ingest" : {
"timestamp" : "2021-07-20T01:31:22.028392Z"
}
}
}
]
}
就像我之前所说的,尽管 Dissect 和 Grok 都可以满足要求,我们首选 Dissect,毕竟它的效率要高很多。正则匹配是一个比较慢的运算。
在 Grok 使用多个 patterns 进行匹配
在上面,我们展示了 Dissect 和 Grok。在许多的情况下,它们都可以派上用场,但是有一种情况是 Grok 独有的。Grok 它可以同时使用多个 patterns 来对日志的文件进行匹配。比如,我们有如下的两种日志:
{
"message": "55.3.244.1 OK"
}
{
"message": "55.3.244.1 0.043"
}
显然上面的两种日志的格式是完全不同的。第一种的情况是 IP 加上一个 status,而对于第二种情况来说说,它是 IP 加上一个浮点数。在这种情况下,我们使用 Dissect 是完全无能为力了。
我们可以使用 Grok 来完美地匹配这两种情况:
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"grok": {
"field": "message",
"patterns": [
"%{IP:client} %{NUMBER:duration:float}",
"%{IP:client} %{WORD:status}"
]
}
}
]
},
"docs": [
{
"_source": {
"message": "55.3.244.1 OK"
}
},
{
"_source": {
"message": "55.3.244.1 0.043"
}
}
]
}
在上面,我们在 Grok 的 pattern 里定义了如下的 patterns:
"patterns": [
"%{IP:client} %{NUMBER:duration:float}",
"%{IP:client} %{WORD:status}"
]
也就是说它可以同时匹配两个模式。其中的任何一个匹配,就可以完成文档的正确解析。运行上面的命令,我们可以看到如下的结果:
{
"docs" : [
{
"doc" : {
"_index" : "_index",
"_type" : "_doc",
"_id" : "_id",
"_source" : {
"client" : "55.3.244.1",
"message" : "55.3.244.1 OK",
"status" : "OK"
},
"_ingest" : {
"timestamp" : "2021-07-20T01:39:44.282416Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_doc",
"_id" : "_id",
"_source" : {
"duration" : 0.043,
"client" : "55.3.244.1",
"message" : "55.3.244.1 0.043"
},
"_ingest" : {
"timestamp" : "2021-07-20T01:39:44.282424Z"
}
}
}
]
}
从输出的结果中,我们可以清楚地看到结构化的输出。
我们甚至结合定制 pattern,让它生成更为复杂的匹配模式:
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"grok": {
"field": "message",
"patterns": [
"%{IP:client} %{VERSION:version} %{NUMBER:num}",
"%{IP:client} %{NUMBER:duration:float} %{NUMBER:num}",
"%{IP:client} %{WORD:status} %{NUMBER:num}"
],
"pattern_definitions": {
"VERSION": """\\d\\.\\d+\\.\\d"""
}
}
}
]
},
"docs": [
{
"_source": {
"message": "55.3.244.1 7.31.1 12"
}
},
{
"_source": {
"message": "55.3.244.1 OK 14"
}
},
{
"_source": {
"message": "55.3.244.1 0.043 15"
}
}
]
}
在上面,我们运用 custom pattterns 来定制一个 pattern。它被用来匹配 version。上面运行的结果是:
{
"docs" : [
{
"doc" : {
"_index" : "_index",
"_type" : "_doc",
"_id" : "_id",
"_source" : {
"num" : "12",
"client" : "55.3.244.1",
"message" : "55.3.244.1 7.31.1 12",
"version" : "7.31.1"
},
"_ingest" : {
"timestamp" : "2021-07-20T02:21:22.447666Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_doc",
"_id" : "_id",
"_source" : {
"num" : "14",
"client" : "55.3.244.1",
"message" : "55.3.244.1 OK 14",
"status" : "OK"
},
"_ingest" : {
"timestamp" : "2021-07-20T02:21:22.447673Z"
}
}
},
{
"doc" : {
"_index" : "_index",
"_type" : "_doc",
"_id" : "_id",
"_source" : {
"duration" : 0.043,
"num" : "15",
"client" : "55.3.244.1",
"message" : "55.3.244.1 0.043 15"
},
"_ingest" : {
"timestamp" : "2021-07-20T02:21:22.447676Z"
}
}
}
]
}
以上是关于Elasticsearch:Dissect 和 Grok 处理器之间的区别的主要内容,如果未能解决你的问题,请参考以下文章