Dissect 和 Grok 处理器之间的区别

原创
07/21 10:30
阅读数 22

导语



针对很多情况我们可以直接使用 Dissect 处理器来对非结构化化的日志进行结构化。在我之前的文章 “Elasticsearch:深入理解 Dissect ingest processor” 有做笔记深入的讲解。在很多的情况下,我们也可以使用 Grok  处理器来进行结构化。那么这两者之间有什么区别呢?在实际的使用中,我们到底首先哪一个呢?


一般来说,我们需要首先 Dissect 处理器,这是因为它的速度比 Grok 要快很多。Grok 是基于正则匹配,执行速度比 Dissect 要慢很多。当然 Grok 也有自己的独到之处。它可以同时使用多个 patterns 来对日志来进行匹配。这个是 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"        }      }    }  ]}


正文完



 作者:刘晓国

本文编辑:喝咖啡的猫



嗨,互动起来吧!

喜欢这篇文章么?

欢迎留下你想说的,留言 100% 精选哦!

Elastic 社区公众号长期征稿,如果您有 Elastic  技术的相关文章,也欢迎投稿至本公众号,一起进步! 投稿请添加微信:medcl123



招聘信息

Job board


社区招聘栏目是一个新的尝试,帮助社区的小伙伴找到心仪的职位,也帮助企业找到所需的人才,为伯乐和千里马牵线搭桥。有招聘需求的企业和正在求职的社区小伙伴,可以联系微信 medcl123 提交招聘需求和发布个人简历信息。


Elastic中文社区公众号 (elastic-cn)

为您汇集 Elastic 社区的最新动态、精选干货文章、精华讨论、文档资料、翻译与版本发布等。

喜欢本篇内容就请给我们点个[在看]吧




本文分享自微信公众号 - Elastic中文社区(elastic-cn)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部