Grok 处理器

编辑

从文档中的单个文本字段中提取结构化字段。您可以选择从中提取匹配字段的字段,以及您期望匹配的 grok 模式。grok 模式类似于正则表达式,它支持可以重用的别名表达式。

此处理器附带许多可重用模式

如果您需要帮助构建匹配日志的模式,您会发现 Grok 调试器 工具非常有用!Grok 构造器 也是一个有用的工具。

在管道中使用 Grok 处理器

编辑

表 23. Grok 选项

名称 必需 默认值 描述

field

-

用于 grok 表达式解析的字段

patterns

-

有序的 grok 表达式列表,用于匹配和提取命名捕获。返回列表中第一个匹配的表达式。

pattern_definitions

-

一个模式名称和模式元组的映射,定义当前处理器使用的自定义模式。与现有名称匹配的模式将覆盖预先存在的定义。

ecs_compatibility

disabled

必须为 disabledv1。如果为 v1,则处理器使用带有Elastic Common Schema (ECS) 字段名称的模式。

trace_match

false

如果为 true,则 _ingest._grok_match_index 将插入到您的匹配文档的元数据中,其中包含 patterns 中匹配的模式的索引。

ignore_missing

false

如果 truefield 不存在或为 null,则处理器会静默退出而不修改文档

description

-

处理器的描述。用于描述处理器的目的或其配置。

if

-

有条件地执行处理器。请参阅 有条件地运行处理器

ignore_failure

false

忽略处理器的失败。请参阅 处理管道失败

on_failure

-

处理处理器的失败。请参阅 处理管道失败

tag

-

处理器的标识符。用于调试和指标。

以下示例演示如何使用提供的模式从文档中的字符串字段中提取并命名结构化字段。

resp = client.ingest.simulate(
    pipeline={
        "description": "...",
        "processors": [
            {
                "grok": {
                    "field": "message",
                    "patterns": [
                        "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes:int} %{NUMBER:duration:double}"
                    ]
                }
            }
        ]
    },
    docs=[
        {
            "_source": {
                "message": "55.3.244.1 GET /index.html 15824 0.043"
            }
        }
    ],
)
print(resp)
response = client.ingest.simulate(
  body: {
    pipeline: {
      description: '...',
      processors: [
        {
          grok: {
            field: 'message',
            patterns: [
              '%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes:int} %{NUMBER:duration:double}'
            ]
          }
        }
      ]
    },
    docs: [
      {
        _source: {
          message: '55.3.244.1 GET /index.html 15824 0.043'
        }
      }
    ]
  }
)
puts response
const response = await client.ingest.simulate({
  pipeline: {
    description: "...",
    processors: [
      {
        grok: {
          field: "message",
          patterns: [
            "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes:int} %{NUMBER:duration:double}",
          ],
        },
      },
    ],
  },
  docs: [
    {
      _source: {
        message: "55.3.244.1 GET /index.html 15824 0.043",
      },
    },
  ],
});
console.log(response);
POST _ingest/pipeline/_simulate
{
  "pipeline": {
    "description" : "...",
    "processors": [
      {
        "grok": {
          "field": "message",
          "patterns": ["%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes:int} %{NUMBER:duration:double}"]
        }
      }
    ]
  },
  "docs":[
    {
      "_source": {
        "message": "55.3.244.1 GET /index.html 15824 0.043"
      }
    }
  ]
}

此管道会将这些命名捕获作为文档中的新字段插入,如下所示

{
  "docs": [
    {
      "doc": {
        "_index": "_index",
        "_id": "_id",
        "_version": "-3",
        "_source" : {
          "duration" : 0.043,
          "request" : "/index.html",
          "method" : "GET",
          "bytes" : 15824,
          "client" : "55.3.244.1",
          "message" : "55.3.244.1 GET /index.html 15824 0.043"
        },
        "_ingest": {
          "timestamp": "2016-11-08T19:43:03.850+0000"
        }
      }
    }
  ]
}

自定义模式

编辑

Grok 处理器预先打包了一组基本模式。这些模式可能并不总是包含您正在寻找的内容。模式具有非常基本的格式。每个条目都有一个名称和模式本身。

您可以在 pattern_definitions 选项下向处理器定义添加自己的模式。以下示例是一个指定自定义模式定义的管道

{
  "description" : "...",
  "processors": [
    {
      "grok": {
        "field": "message",
        "patterns": ["my %{FAVORITE_DOG:dog} is colored %{RGB:color}"],
        "pattern_definitions" : {
          "FAVORITE_DOG" : "beagle",
          "RGB" : "RED|GREEN|BLUE"
        }
      }
    }
  ]
}

提供多个匹配模式

编辑

有时,一个模式不足以捕获字段的潜在结构。假设我们想要匹配所有包含您最喜欢的猫或狗品种的消息。实现此目的的一种方法是提供两个不同的可以匹配的模式,而不是一个真正复杂的表达式来捕获相同的 or 行为。

以下示例是针对 simulate API 执行的此类配置

resp = client.ingest.simulate(
    pipeline={
        "description": "parse multiple patterns",
        "processors": [
            {
                "grok": {
                    "field": "message",
                    "patterns": [
                        "%{FAVORITE_DOG:pet}",
                        "%{FAVORITE_CAT:pet}"
                    ],
                    "pattern_definitions": {
                        "FAVORITE_DOG": "beagle",
                        "FAVORITE_CAT": "burmese"
                    }
                }
            }
        ]
    },
    docs=[
        {
            "_source": {
                "message": "I love burmese cats!"
            }
        }
    ],
)
print(resp)
response = client.ingest.simulate(
  body: {
    pipeline: {
      description: 'parse multiple patterns',
      processors: [
        {
          grok: {
            field: 'message',
            patterns: [
              '%{FAVORITE_DOG:pet}',
              '%{FAVORITE_CAT:pet}'
            ],
            pattern_definitions: {
              "FAVORITE_DOG": 'beagle',
              "FAVORITE_CAT": 'burmese'
            }
          }
        }
      ]
    },
    docs: [
      {
        _source: {
          message: 'I love burmese cats!'
        }
      }
    ]
  }
)
puts response
const response = await client.ingest.simulate({
  pipeline: {
    description: "parse multiple patterns",
    processors: [
      {
        grok: {
          field: "message",
          patterns: ["%{FAVORITE_DOG:pet}", "%{FAVORITE_CAT:pet}"],
          pattern_definitions: {
            FAVORITE_DOG: "beagle",
            FAVORITE_CAT: "burmese",
          },
        },
      },
    ],
  },
  docs: [
    {
      _source: {
        message: "I love burmese cats!",
      },
    },
  ],
});
console.log(response);
POST _ingest/pipeline/_simulate
{
  "pipeline": {
  "description" : "parse multiple patterns",
  "processors": [
    {
      "grok": {
        "field": "message",
        "patterns": ["%{FAVORITE_DOG:pet}", "%{FAVORITE_CAT:pet}"],
        "pattern_definitions" : {
          "FAVORITE_DOG" : "beagle",
          "FAVORITE_CAT" : "burmese"
        }
      }
    }
  ]
},
"docs":[
  {
    "_source": {
      "message": "I love burmese cats!"
    }
  }
  ]
}

响应

{
  "docs": [
    {
      "doc": {
        "_index": "_index",
        "_id": "_id",
        "_version": "-3",
        "_source": {
          "message": "I love burmese cats!",
          "pet": "burmese"
        },
        "_ingest": {
          "timestamp": "2016-11-08T19:43:03.850+0000"
        }
      }
    }
  ]
}

两种模式都会将字段 pet 设置为适当的匹配项,但是如果我们想要跟踪哪些模式匹配并填充了我们的字段呢?我们可以使用 trace_match 参数来实现这一点。以下是同一管道的输出,但配置了 "trace_match": true

{
  "docs": [
    {
      "doc": {
        "_index": "_index",
        "_id": "_id",
        "_version": "-3",
        "_source": {
          "message": "I love burmese cats!",
          "pet": "burmese"
        },
        "_ingest": {
          "_grok_match_index": "1",
          "timestamp": "2016-11-08T19:43:03.850+0000"
        }
      }
    }
  ]
}

在上面的响应中,您可以看到匹配的模式的索引为 "1"。也就是说,它是 patterns 中第二个(索引从零开始)匹配的模式。

此跟踪元数据可以调试匹配了哪些模式。此信息存储在 ingest 元数据中,不会被索引。

从 REST 端点检索模式

编辑

Grok 处理器附带自己的 REST 端点,用于检索处理器中包含的模式。

resp = client.ingest.processor_grok()
print(resp)
response = client.ingest.processor_grok
puts response
const response = await client.ingest.processorGrok();
console.log(response);
GET _ingest/processor/grok

上述请求将返回一个响应正文,其中包含内置模式字典的键值表示形式。

{
  "patterns" : {
    "BACULA_CAPACITY" : "%{INT}{1,3}(,%{INT}{3})*",
    "PATH" : "(?:%{UNIXPATH}|%{WINPATH})",
    ...
}

默认情况下,API 返回旧版 Grok 模式列表。这些旧版模式早于Elastic Common Schema (ECS),并且不使用 ECS 字段名称。要返回提取 ECS 字段名称的模式,请在可选的 ecs_compatibility 查询参数中指定 v1

resp = client.ingest.processor_grok(
    ecs_compatibility="v1",
)
print(resp)
response = client.ingest.processor_grok(
  ecs_compatibility: 'v1'
)
puts response
const response = await client.ingest.processorGrok({
  ecs_compatibility: "v1",
});
console.log(response);
GET _ingest/processor/grok?ecs_compatibility=v1

默认情况下,API 按照从磁盘读取的顺序返回模式。此排序顺序保留了相关模式的分组。例如,所有与解析 Linux 系统日志行相关的模式都保持分组在一起。

您可以使用可选的布尔值 s 查询参数来按键名对返回的模式进行排序。

resp = client.ingest.processor_grok(
    s=True,
)
print(resp)
response = client.ingest.processor_grok(
  s: true
)
puts response
const response = await client.ingest.processorGrok({
  s: "true",
});
console.log(response);
GET _ingest/processor/grok?s

API 返回以下响应。

{
  "patterns" : {
    "BACULA_CAPACITY" : "%{INT}{1,3}(,%{INT}{3})*",
    "BACULA_DEVICE" : "%{USER}",
    "BACULA_DEVICEPATH" : "%{UNIXPATH}",
    ...
}

当内置模式在不同版本之间发生更改时,这可能很有用。

Grok 看门狗

编辑

执行时间过长的 Grok 表达式会被中断,然后 grok 处理器会因异常而失败。grok 处理器有一个看门狗线程,用于确定 grok 表达式的计算何时花费的时间过长,并通过以下设置控制

表 24. Grok 看门狗设置

名称 默认值 描述

ingest.grok.watchdog.interval

1s

检查是否存在执行时间超过最大允许执行时间的 grok 计算的频率。

ingest.grok.watchdog.max_execution_time

1s

grok 表达式计算的最大允许执行时间。

Grok 调试

编辑

建议使用 Grok 调试器 来调试 grok 模式。从那里,您可以在 UI 中针对示例数据测试一个或多个模式。在底层,它使用与 ingest 节点处理器相同的引擎。

此外,建议为 Grok 启用调试日志记录,以便可以在 Elasticsearch 服务器日志中看到任何其他消息。

PUT _cluster/settings
{
  "persistent": {
    "logger.org.elasticsearch.ingest.common.GrokProcessor": "debug"
  }
}