Grok 过滤器插件

编辑
  • 插件版本:v4.4.3
  • 发布日期:2022-10-28
  • 更新日志

有关其他版本,请参阅版本化插件文档

获取帮助

编辑

有关插件的问题,请在Discuss论坛中开启一个主题。对于错误或功能请求,请在Github中开启一个 issue。有关 Elastic 支持的插件列表,请参考Elastic 支持矩阵

描述

编辑

解析任意文本并将其结构化。

Grok 是将非结构化日志数据解析为结构化和可查询数据的绝佳方法。

此工具非常适合 syslog 日志、apache 和其他 Web 服务器日志、mysql 日志,以及通常为人类而非计算机使用而编写的任何日志格式。

Logstash 默认附带大约 120 个模式。您可以在此处找到它们:https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns。您可以轻松添加自己的模式。(请参阅patterns_dir设置)

如果您需要帮助构建与您的日志匹配的模式,您会发现http://grokdebug.herokuapp.comhttp://grokconstructor.appspot.com/应用程序非常有用!

Grok 还是 Dissect?还是两者都用?

编辑

dissect 过滤器插件是另一种使用分隔符将非结构化事件数据提取到字段中的方法。

Dissect 与 Grok 的不同之处在于它不使用正则表达式,并且速度更快。当数据可靠地重复出现时,Dissect 非常有效。当文本结构逐行变化时,Grok 是更好的选择。

当行的某个部分可靠地重复出现,但整行不是时,您可以将 Dissect 和 Grok 用于混合用例。Dissect 过滤器可以解构行中重复的部分。Grok 过滤器可以使用更多的正则表达式可预测性来处理其余的字段值。

Grok 基础

编辑

Grok 通过将文本模式组合成与您的日志匹配的内容来工作。

grok 模式的语法是 %{SYNTAX:SEMANTIC}

SYNTAX 是将匹配您的文本的模式的名称。例如,3.44 将与 NUMBER 模式匹配,55.3.244.1 将与 IP 模式匹配。语法是您如何匹配。

SEMANTIC 是您为匹配的文本段提供的标识符。例如,3.44 可能是事件的持续时间,因此您可以简单地将其称为 duration。此外,字符串 55.3.244.1 可能标识发出请求的 client

对于上面的示例,您的 grok 过滤器将如下所示

%{NUMBER:duration} %{IP:client}

(可选)您可以在 grok 模式中添加数据类型转换。默认情况下,所有语义都保存为字符串。如果您希望转换语义的数据类型,例如将字符串更改为整数,则在其后附加目标数据类型。例如 %{NUMBER:num:int},它将 num 语义从字符串转换为整数。目前,唯一支持的转换是 intfloat

示例:有了语法和语义的概念,我们可以从像这样的虚构的 http 请求日志的示例日志中提取有用的字段

    55.3.244.1 GET /index.html 15824 0.043

此模式可以是

    %{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}

更实际的示例,让我们从文件中读取这些日志

    input {
      file {
        path => "/var/log/http.log"
      }
    }
    filter {
      grok {
        match => { "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}" }
      }
    }

在 grok 过滤器之后,事件中将包含一些额外的字段

  • client: 55.3.244.1
  • method: GET
  • request: /index.html
  • bytes: 15824
  • duration: 0.043

正则表达式

编辑

Grok 位于正则表达式之上,因此任何正则表达式在 grok 中也是有效的。正则表达式库是 Oniguruma,您可以在Oniguruma 站点上查看完整支持的正则表达式语法。

自定义模式

编辑

有时 logstash 没有您需要的模式。为此,您有几个选择。

首先,您可以使用 Oniguruma 语法的命名捕获,这将使您可以匹配一段文本并将其保存为字段

    (?<field_name>the pattern here)

例如,postfix 日志有一个 queue id,它是一个 10 或 11 个字符的十六进制值。我可以像这样轻松捕获它

    (?<queue_id>[0-9A-F]{10,11})

或者,您可以创建自定义模式文件。

  • 创建一个名为 patterns 的目录,并在其中创建一个名为 extra 的文件(文件名无关紧要,但为了方便自己,请有意义地命名它)
  • 在该文件中,将您需要的模式编写为模式名称、一个空格,然后编写该模式的正则表达式。

例如,像上面那样执行 postfix 队列 id 示例

    # contents of ./patterns/postfix:
    POSTFIX_QUEUEID [0-9A-F]{10,11}

然后使用此插件中的 patterns_dir 设置来告知 logstash 您的自定义模式目录在哪里。这是一个带有示例日志的完整示例

    Jan  1 06:25:43 mailserver14 postfix/cleanup[21403]: BEF25A72965: message-id=<[email protected]>
    filter {
      grok {
        patterns_dir => ["./patterns"]
        match => { "message" => "%{SYSLOGBASE} %{POSTFIX_QUEUEID:queue_id}: %{GREEDYDATA:syslog_message}" }
      }
    }

上面的内容将匹配并生成以下字段

  • timestamp: Jan 1 06:25:43
  • logsource: mailserver14
  • program: postfix/cleanup
  • pid: 21403
  • queue_id: BEF25A72965
  • syslog_message: message-id=<[email protected]>

timestamplogsourceprogrampid 字段来自 SYSLOGBASE 模式,该模式本身由其他模式定义。

另一种选择是使用 pattern_definitions 在过滤器中内联定义模式。这主要是为了方便,并允许用户定义一个仅在该过滤器中使用的模式。在 pattern_definitions 中新定义的模式将无法在该特定 grok 过滤器之外使用。

迁移到 Elastic 通用架构 (ECS)

编辑

为了简化向Elastic 通用架构 (ECS)的迁移,过滤器插件除了现有模式外,还提供了一组新的符合 ECS 的模式。新的 ECS 模式定义捕获与架构兼容的事件字段名称。

ECS 模式集具有旧版集中的所有模式定义,并且是直接替代品。使用ecs_compatibility设置切换模式。

新功能和增强功能将添加到符合 ECS 的文件中。旧版模式可能仍会收到向后兼容的错误修复。

Grok 过滤器配置选项

编辑

此插件支持以下配置选项以及稍后描述的通用选项

另请参阅通用选项,以获取所有过滤器插件支持的选项列表。

 

break_on_match

编辑

在第一次匹配时中断。grok 的第一次成功匹配将导致过滤器完成。如果您希望 grok 尝试所有模式(也许您正在解析不同的内容),则将此项设置为 false。

ecs_compatibility

编辑
  • 值类型为字符串
  • 支持的值为

    • disabled:插件将加载旧版(内置)模式定义
    • v1v8:插件提供的所有模式都将使用符合 ECS 的捕获
  • 默认值取决于运行的 Logstash 版本

    • 当 Logstash 提供 pipeline.ecs_compatibility 设置时,其值用作默认值
    • 否则,默认值为 disabled

控制此插件与Elastic 通用架构 (ECS)的兼容性。当匹配复合模式(例如 HTTPD_COMMONLOG)时,此设置的值会影响提取的事件字段名称。

keep_empty_captures

编辑

如果为 true,则将空捕获保留为事件字段。

match

编辑
  • 值类型为哈希
  • 默认值为 {}

一个哈希,定义了在哪里查找以及使用哪些模式的映射。

例如,以下内容将匹配 message 字段中的现有值以获得给定的模式,如果找到匹配项,则将字段 duration 添加到事件中,并带有捕获的值

    filter {
      grok {
        match => {
          "message" => "Duration: %{NUMBER:duration}"
        }
      }
    }

如果您需要对单个字段匹配多个模式,则该值可以是模式数组

    filter {
      grok {
        match => {
          "message" => [
            "Duration: %{NUMBER:duration}",
            "Speed: %{NUMBER:speed}"
          ]
        }
      }
    }

若要对多个字段执行匹配,只需在 match 哈希中使用多个条目

    filter {
      grok {
        match => {
          "speed" => "Speed: %{NUMBER:speed}"
          "duration" => "Duration: %{NUMBER:duration}"
        }
      }
    }

但是,如果一个模式依赖于先前模式创建的字段,请将其分隔为两个单独的 grok 过滤器

    filter {
      grok {
        match => {
          "message" => "Hi, the rest of the message is: %{GREEDYDATA:rest}"
        }
      }
      grok {
        match => {
          "rest" => "a number %{NUMBER:number}, and a word %{WORD:word}"
        }
      }
    }

named_captures_only

编辑

如果为 true,则仅存储来自 grok 的命名捕获。

overwrite

编辑
  • 值类型为数组
  • 默认值为 []

要覆盖的字段。

这允许您覆盖已存在的字段中的值。

例如,如果您的 message 字段中有一行 syslog 行,您可以覆盖 message 字段,其中包含匹配项的一部分,如下所示

    filter {
      grok {
        match => { "message" => "%{SYSLOGBASE} %{DATA:message}" }
        overwrite => [ "message" ]
      }
    }

在这种情况下,像 May 29 16:37:11 sadness logger: hello world 这样的行将被解析,并且 hello world 将覆盖原始消息。

如果您在 overwrite 中使用字段引用,则必须在模式中使用字段引用。示例

    filter {
      grok {
        match => { "somefield" => "%{NUMBER} %{GREEDYDATA:[nested][field][test]}" }
        overwrite => [ "[nested][field][test]" ]
      }
    }

pattern_definitions

编辑
  • 值类型为哈希
  • 默认值为 {}

一个模式名称和模式元组的哈希,定义了当前过滤器使用的自定义模式。与现有名称匹配的模式将覆盖预先存在的定义。可以将其视为仅对此 grok 定义可用的内联模式

patterns_dir

编辑
  • 值类型为数组
  • 默认值为 []

Logstash 默认自带许多模式,因此除非您要添加额外的模式,否则您不必自己定义。您可以使用此设置指向多个模式目录。请注意,Grok 将读取目录中所有匹配 patterns_files_glob 的文件,并将其视为模式文件(包括任何波浪号备份文件)。

    patterns_dir => ["/opt/logstash/patterns", "/opt/logstash/extra_patterns"]

模式文件是纯文本格式,如下所示:

    NAME PATTERN

例如:

    NUMBER \d+

模式会在管道创建时加载。

patterns_files_glob

编辑

Glob 模式,用于选择由 patterns_dir 指定目录中的模式文件

tag_on_failure

编辑
  • 值类型为数组
  • 默认值为 ["_grokparsefailure"]

当没有成功匹配时,将值附加到 tags 字段

tag_on_timeout

编辑
  • 值类型为字符串
  • 默认值为 "_groktimeout"

如果 grok 正则表达式超时,则应用的标签。

target

编辑
  • 值类型为字符串
  • 此设置没有默认值

定义放置匹配项的目标命名空间。

timeout_millis

编辑
  • 值类型为 number
  • 默认值为 30000

在此时间后尝试终止正则表达式。如果应用了多个模式,则此设置适用于每个模式。这永远不会提前超时,但可能需要更长的时间才能超时。实际超时是基于 250 毫秒量化的近似值。设置为 0 可禁用超时

timeout_scope

编辑
  • 值类型为字符串
  • 默认值为 "pattern"
  • 支持的值为 "pattern""event"

当向 match 提供多个模式时,超时通常应用于每个模式,从而导致尝试每个模式时产生开销;当 grok 过滤器配置为 timeout_scope => event 时,插件改为在事件的所有尝试匹配中强制执行单个超时,因此它可以以显著更少的开销实现对失控匹配器的类似保护。

通常最好将超时范围限定为整个事件。

通用选项

编辑

所有过滤器插件都支持这些配置选项

add_field

编辑
  • 值类型为 hash
  • 默认值为 {}

如果此过滤器成功,则向此事件添加任何任意字段。字段名称可以是动态的,并且可以使用 %{field} 包括事件的部分内容。

示例

    filter {
      grok {
        add_field => { "foo_%{somefield}" => "Hello world, from %{host}" }
      }
    }
    # You can also add multiple fields at once:
    filter {
      grok {
        add_field => {
          "foo_%{somefield}" => "Hello world, from %{host}"
          "new_field" => "new_static_value"
        }
      }
    }

如果事件具有字段 "somefield" == "hello",则此过滤器在成功时将添加字段 foo_hello(如果存在),其值如上所示,并且 %{host} 部分被事件中的该值替换。第二个示例还将添加一个硬编码字段。

add_tag

编辑
  • 值类型为 array
  • 默认值为 []

如果此过滤器成功,则向事件添加任意标签。标签可以是动态的,并且可以使用 %{field} 语法包括事件的部分内容。

示例

    filter {
      grok {
        add_tag => [ "foo_%{somefield}" ]
      }
    }
    # You can also add multiple tags at once:
    filter {
      grok {
        add_tag => [ "foo_%{somefield}", "taggedy_tag"]
      }
    }

如果事件具有字段 "somefield" == "hello",则此过滤器在成功时将添加标签 foo_hello(第二个示例当然会添加 taggedy_tag 标签)。

enable_metric

编辑
  • 值类型为 boolean
  • 默认值为 true

禁用或启用此特定插件实例的指标日志记录。默认情况下,我们会记录所有可以记录的指标,但是您可以禁用特定插件的指标收集。

  • 值类型为 string
  • 此设置没有默认值。

向插件配置添加唯一的 ID。如果未指定 ID,则 Logstash 将生成一个。强烈建议在您的配置中设置此 ID。当您有两个或多个相同类型的插件时,这尤其有用,例如,如果您有两个 grok 过滤器。在这种情况下添加命名 ID 将有助于在使用监控 API 时监控 Logstash。

    filter {
      grok {
        id => "ABC"
      }
    }

id 字段中的变量替换仅支持环境变量,不支持使用来自密钥存储的值。

periodic_flush

编辑
  • 值类型为 boolean
  • 默认值为 false

定期调用过滤器刷新方法。可选。

remove_field

编辑
  • 值类型为 array
  • 默认值为 []

如果此过滤器成功,则从此事件中删除任意字段。字段名称可以是动态的,并且可以使用 %{field} 包括事件的部分内容。示例

    filter {
      grok {
        remove_field => [ "foo_%{somefield}" ]
      }
    }
    # You can also remove multiple fields at once:
    filter {
      grok {
        remove_field => [ "foo_%{somefield}", "my_extraneous_field" ]
      }
    }

如果事件具有字段 "somefield" == "hello",则此过滤器在成功时将删除名称为 foo_hello 的字段(如果存在)。第二个示例将删除一个额外的非动态字段。

remove_tag

编辑
  • 值类型为 array
  • 默认值为 []

如果此过滤器成功,则从此事件中删除任意标签。标签可以是动态的,并且可以使用 %{field} 语法包括事件的部分内容。

示例

    filter {
      grok {
        remove_tag => [ "foo_%{somefield}" ]
      }
    }
    # You can also remove multiple tags at once:
    filter {
      grok {
        remove_tag => [ "foo_%{somefield}", "sad_unwanted_tag"]
      }
    }

如果事件具有字段 "somefield" == "hello",则此过滤器在成功时将删除标签 foo_hello(如果存在)。第二个示例也将删除一个令人不快的、不需要的标签。