【问题标题】:Grok strange issueGrok奇怪的问题
【发布时间】:2020-04-18 09:01:28
【问题描述】:

我们在 Elasticsearch 中使用管道来模拟 grok 过滤器。 我们遇到以下奇怪的行为。

如果时间戳字段位于消息的开头,则 grok 过滤器不起作用。

## GROK NOT WORK
    POST /_ingest/pipeline/_simulate
    {
      "pipeline": {
        "processors": [
          {
            "grok": {
              "field": "message",
              "patterns": ["""%{TIMESTAMP_ISO8601:@timestamp} %{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} %{TIMESTAMP_ISO8601:@timestamp}"""]
            }
          }
        ]
      },
        "docs": [
        {
          "_source": {
            "message": "2019-09-29T00:39:02.91ZZ 55.3.244.1 GET /index.html 15824 0.043  "
          }
        }
      ]
    }

我们有以下错误:

{
  "docs" : [
    {
      "error" : {
        "root_cause" : [
          {
            "type" : "illegal_argument_exception",
            "reason" : "Provided Grok expressions do not match field value: [2019-09-29T00:39:02.91ZZ 55.3.244.1 GET /index.html 15824 0.043  ]"
          }
        ],
        "type" : "illegal_argument_exception",
        "reason" : "Provided Grok expressions do not match field value: [2019-09-29T00:39:02.91ZZ 55.3.244.1 GET /index.html 15824 0.043  ]"
      }
    }
  ]
}

在这种格式下,消息末尾的时间戳,grok 过滤器工作正常。

    ## GROK WORKS FINE
    POST /_ingest/pipeline/_simulate
    {
      "pipeline": {
        "processors": [
          {
            "grok": {
              "field": "message",
              "patterns": ["""%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} %{TIMESTAMP_ISO8601:@timestamp}"""]
            }
          }
        ]
      },
        "docs": [
        {
          "_source": {
            "message": "55.3.244.1 GET /index.html 15824 0.043 2019-09-29T00:39:02.91ZZ"
          }
        }
      ]
    }

提前致谢

【问题讨论】:

  • 我觉得很奇怪,您的时间戳末尾有两个 ZZ 字符...似乎与 ISO8601 不兼容

标签: elasticsearch grok


【解决方案1】:

从您的第一个示例中,我发现您的 GROK 表达式存在 2 个问题:

  1. 在 grok 表达式的末尾有第二个时间戳(可能是复制粘贴问题?)
  2. 第二个问题是时间戳末尾的时区ZZ。如果您想忽略它,您可以在时间戳之后添加 %{NOTSPACE} 以忽略这些额外的时区字符。

你可以试试下面的 grok:

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

这是在 GROK 调试器中测试的,对我有用。 我建议你与 GROK 调试器密切合作(在 Kibana->Dev Tools->Grok 调试器中)或者你可以找到一些在线的 grok 调试器。

最后,我建议你在使用像%{NUMBER:duration:float} 这样的“NUMBER”格式之后添加:int 或:float,以便能够在ES 中使用更大/更小的过滤器。

【讨论】:

    【解决方案2】:

    可以使用https://regex101.com/r/eRAJg3/1 匹配日期。 LMK 如果有帮助的话。

    然后您可以在 grok 表达式中使用 Oniguruma 语法:

    (?<ts>([\d]{4}-[\d]{2}-[\d]{2}T[\d]{2}:[\d]{2}:[\d]{2}\.[\d]{2}Z{2}))
    

    供参考:https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html#_custom_patterns

    正如 eladyanai 指出的那样,您还应该从第一个表达式中删除时间戳的第二个实例。

    为了完整起见,我将提供完整的表达式:

    (?<ts>([\d]{4}-[\d]{2}-[\d]{2}T[\d]{2}:[\d]{2}:[\d]{2}\.[\d]{2}Z{2})) %{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}%{SPACE}
    

    【讨论】:

      【解决方案3】:

      它们在时间之后是“ZZ”,与 ISO 不兼容。

      您可以添加 .* --> "0 个或多个任意字符"

      %{TIMESTAMP_ISO8601:@timestamp}.*

      和 * 在最后一个时间戳模式之后使其成为可选

      {
        "pipeline": {
          "processors": [
            {
              "grok": {
                "field": "message",
                "patterns": [
                  "%{TIMESTAMP_ISO8601:@timestamp}.* %{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} %{TIMESTAMP_ISO8601:@timestamp}*"
                ]
              }
            }
          ]
        },
        "docs": [
          {
            "_source": {
              "message": "2019-09-29T00:39:02.91ZZ 55.3.244.1 GET /index.html 15824 0.043  "
            }
          }
        ]
      

      结果:

      {
        "docs" : [
          {
            "doc" : {
              "_index" : "_index",
              "_type" : "_doc",
              "_id" : "_id",
              "_source" : {
                "duration" : "0.043",
                "request" : "/index.html",
                "@timestamp" : "2019-09-29T00:39:02.91Z",
                "method" : "GET",
                "bytes" : "15824",
                "client" : "55.3.244.1",
                "message" : "2019-09-29T00:39:02.91ZZ 55.3.244.1 GET /index.html 15824 0.043  "
              },
              "_ingest" : {
                "timestamp" : "2020-04-18T10:43:39.8725873Z"
              }
            }
          }
        ]
      }
      

      【讨论】:

      • 您建议的解决方案不起作用。您忽略了他在 GROK 模式末尾有第二个时间戳的事实,这导致它失败。在可以避免的情况下,将 GROK 表达式与正则表达式混合使用也是一种不好的做法。
      猜你喜欢
      • 2015-02-27
      • 2018-06-26
      • 2011-08-13
      • 2011-08-17
      • 2011-02-02
      • 2021-10-10
      • 2014-04-21
      • 2010-12-30
      • 2014-03-21
      相关资源
      最近更新 更多