Elastic:在摄入时使用 grok 构建 Elasticsearch 数据以加快分析速度

除了作为搜索引擎之外,Elasticsearch 还是一个强大的分析引擎。 但是,为了充分利用 Elasticsearch 的近实时分析功能,在将数据吸收到 Elasticsearch 中时向数据添加结构通常很有用。 在 schema on write vs. schema on read 博客文章中 ,可以很好地解释其原因,而在本博客系列的其余部分中,当我谈论结构化数据时,我指的是 schema on write

由于结构化数据非常重要,因此在这个分为三部分的博客系列中,我们将探讨以下内容:

  • 如何通过使用带有 Grok Processor摄取节点向非结构化文档添加结构。
  • 如何构建新的希腊模式。 (快来了)
  • 如何调试 grok 模式中的错误。 这还将探讨其他主题,例如可公开获得的 grok 模式,以及对 Dissect Processor 的简要说明,可以作为 grok 的替代方案。 (快来了)

ECS 简介

作为附带说明,如果你要努力构造数据,则应考虑构造数据以使其符合 Elastic 通用模式(Elastic Common Schema - ECS)。 ECS 可帮助用户更轻松地可视化,搜索,深入和遍历其数据。 ECS 还简化了自动化分析方法的实施,包括基于机器学习的异常检测和警报。 ECS 可以用于各种用例,包括日志记录,安全分析和应用程序性能监视。

向非结构化数据添加结构的示例

看到发送到 Elasticsearch 的文档类似于以下内容并不少见:

{ 
    "message": "55.3.244.1 GET /index.html 15824 0.043 other stuff" 
} 

上述文档中的 message 字段包含非结构化数据。 它是一系列单词和数字,不适用于近实时分析。为了充分利用 Elasticsearch 强大的分析功能,我们应该解析消息字段以提取相关数据。 例如,我们可以从 message 中提取以下字段:

"host.ip": "55.3.244.1"  
"http.request.method": "GET" 
"url.original": "/index.html" 
"http.request.bytes": 15824 
"event.duration": 0.043 

添加这样的结构将使你能够释放 Elasticsearch 对数据的全部功能(和速度)。 让我们来看看如何使用 grok 来组织你的数据。

使用 grok 构建数据

Grok 是一种工具,可用于从文档中的给定文本字段中提取结构化数据。您定义一个字段以从中提取数据,以及匹配的 grok 模式。 Grok 建立于正则表达式的基础之上。但是,与正则表达式不同,grok 模式由可重用模式组成,这些模式本身可以由其他 grok 模式组成。

作为 Logstash 用户的提示,Elasticsearch 具有与 Logstash 一样的 grok 处理功能。在此博客中,我们将使用摄取节点 grok 处理器,而不是 Logstash grok 过滤器。在摄取节点 grok 模式和 Logstash grok 模式之间进行转换相对简单。

在详细介绍如何构建和调试自己的 grok 模式之前,让我们快速看一下 grok 模式是什么样子的,如何在摄取管道中使用它以及如何对其进行仿真。如果你还不完全了解 grok 表达式的细节,请不要担心,因为这些细节将在本博客的后面部分进行深入讨论。

在上一节中,我们提供了一个示例文档,如下所示:

{ 
    "message": "55.3.244.1 GET /index.html 15824 0.043 other stuff" 
}

可以使用以下 grok 表达式从此文档中的示例消息字段中提取所需的结构化数据:

%{IP:host.ip} %{WORD:http.request.method} %{URIPATHPARAM:url.original} %{NUMBER:http.request.bytes:int} %{NUMBER:event.duration:double} %{GREEDYDATA} 

然后,我们可以在摄取管道中使用此表达式。 这是一个名为 example_grok_pipeline 的管道示例,该管道在 grok 处理器中包含此 grok 模式:

PUT _ingest/pipeline/example_grok_pipeline 
{ 
  "description": "A simple example of using Grok", 
  "processors": [ 
    { 
      "grok": { 
        "field": "message", 
        "patterns": [ 
          "%{IP:host.ip} %{WORD:http.request.method} %{URIPATHPARAM:url.original} %{NUMBER:http.request.bytes:int} %{NUMBER:event.duration:double} %{GREEDYDATA}" 
        ] 
      } 
    } 
  ] 
} 

可以使用以下命令来模拟此管道:

POST _ingest/pipeline/example_grok_pipeline/_simulate
{
  "docs": [
    {
      "_source": {
        "message": "55.3.244.1 GET /index.html 15824 0.043 other stuff"
      }
    }
  ]
} 

响应的结构化文档如下所示:

{
  "docs" : [
    {
      "doc" : {
        "_index" : "_index",
        "_type" : "_doc",
        "_id" : "_id",
        "_source" : {
          "host" : {
            "ip" : "55.3.244.1"
          },
          "http" : {
            "request" : {
              "method" : "GET",
              "bytes" : 15824
            }
          },
          "message" : "55.3.244.1 GET /index.html 15824 0.043 other stuff",
          "event" : {
            "duration" : 0.043
          },
          "url" : {
            "original" : "/index.html"
          }
        },
        "_ingest" : {
          "timestamp" : "2020-08-06T01:20:13.318715Z"
        }
      }
    }
  ]
}

瞧!

该文档包含原始的非结构化消息字段,并且还包含从消息中提取的其他字段。 现在,我们有了一个包含结构化数据的文档!

Grok 你的摄取管道

在上面的示例中,我们模拟了包含 grok 模式的摄取管道的执行,但实际上并未在任何实际文档上运行它。 如摄取节点文档中所述,摄取管道被设计为在摄取时间处理文档。 执行摄取管道的一种方法是在使用 PUT 命令时包括管道名称,如下所示:

PUT example_index/_doc/1?pipeline=example_grok_pipeline 
{
  "message": "55.3.244.1 GET /index.html 15824 0.043 other stuff"
} 

通过执行以下操作可以查看已编写的文档:

GET example_index/_doc/1 

它将以以下方式响应:

{
  "_index" : "example_index",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "host" : {
      "ip" : "55.3.244.1"
    },
    "http" : {
      "request" : {
        "method" : "GET",
        "bytes" : 15824
      }
    },
    "message" : "55.3.244.1 GET /index.html 15824 0.043 other stuff",
    "event" : {
      "duration" : 0.043
    },
    "url" : {
      "original" : "/index.html"
    }
  }
}

另外(可能最好),可以通过将摄取管道默认添加到索引设置,将其应用于所有写入给定索引的文档:

PUT example_index/_settings 
{ 
  "index.default_pipeline": "example_grok_pipeline" 
} 

将管道添加到设置中之后,任何写入 example_index 的文档都将自动应用 example_grok_pipeline。

测试管道

我们可以通过将新文档写入 example_index 来验证管道是否按预期工作,如下所示:

PUT example_index/_doc/2 
{ 
  "message": "66.3.244.1 GET /index.html 500 0.120 new other stuff" 
}  

通过执行以下操作可以查看已编写的文档:

GET example_index/_doc/2 

如预期的那样,它将返回我们刚刚编写的文档。 本文档具有从 message 字段中提取的新字段:

{
  "_index" : "example_index",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 1,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "host" : {
      "ip" : "66.3.244.1"
    },
    "http" : {
      "request" : {
        "method" : "GET",
        "bytes" : 500
      }
    },
    "message" : "66.3.244.1 GET /index.html 500 0.120 new other stuff",
    "event" : {
      "duration" : 0.12
    },
    "url" : {
      "original" : "/index.html"
    }
  }
}

了解 Grok 模式

在上一节中,我们介绍了具有以下结构的示例文档:

{ 
    "message": "55.3.244.1 GET /index.html 15824 0.043 other stuff" 
} 

然后,我们使用以下 grok 模式从 message 字段中提取结构化数据:

"%{IP:host.ip} %{WORD:http.request.method} %{URIPATHPARAM:url.original} %{NUMBER:http.request.bytes:int} %{NUMBER:event.duration:double} %{GREEDYDATA}" 

Grok Processor 文档 中所述,grok 模式的语法有三种形式,即 %{SYNTAX:SEMANTIC},%{SYNTAX} 和 %{SYNTAX:SEMANTIC:TYPE},我们可以在上述 grok 中看到所有这些模式。

  • SYNTAX 是将与你的文本匹配的模式的名称。 内置 SYNTAX 模式可以在 GitHub 上看到。
  • SEMANTIC 是将存储与 SYNTAX 模式匹配的数据的字段的名称。
  • TYPE 是你希望转换命名字段的数据类型。

识别 IP 地址

我们的 grok 模式的第一部分如下:

%{IP:host.ip} 

该声明与 IP 地址(对应于 IP grok 模式)匹配,并将其存储在名为 host.ip 的字段中。 对于我们的示例数据,这将从消息字段中提取值 55.3.244.1,并将其存储在 host.ip 字段中。

如果需要有关 IP grok 模式的更多详细信息,可以查看 GitHub 上的 grok 模式,我们将看到以下定义:

IP (?:%{IPV6}|%{IPV4}) 

这意味着 IP 模式将与 IPV6 或 IPV4 grok 模式之一匹配。 要了解 IPV6 和 IPV4 模式是什么,我们可以再次查看 GitHub 上的 grok模式 以查看其定义,依此类推。

可以进行相同类型的分析来理解与 url.original,request.bytes 和 event.duration 字段匹配的模式,这对于学习 grok(提示...提示...)的任何人都是不错的做法。

使用 GREEDYDATA 识别其余部分

最后,grok 模式中的最后一条语句如下:

%{GREEDYDATA} 

此表达式没有 SEMANTIC 部分,这意味着匹配的数据不会存储到任何字段中。 另外,GREEDYDATA grok 模式将消耗尽可能多的文本,这意味着在我们的示例中,它将匹配 event.duration 字段之后的所有内容。 如本博客系列的后续部分所述,在调试复杂的grok 模式时,GREEDYDATA表达式将派上用场。

敬请关注

在本文中,我们使用 grok 模式和 grok 处理器探索了摄取管道中的结构化数据。 这(以及摄取节点文档)应该足以让您开始构建自己的数据。 因此,请在本地试用,或启动 Elastic Cloud的14天免费试用,并尝试我们的服务。

关于构建新的 grok 模式的博客即将发布,因此请重新登录并学习如何以所需的方式完全构建数据-无论用例如何。

猜你喜欢

转载自blog.csdn.net/UbuntuTouch/article/details/107830887