如何在自定义 grok 模式中引用正则表达式组?

How do I refer to a regex group inside a custom grok pattern?

我想在日志行中为特定 URI 参数添加字段

这是一个示例日志行:

2017-03-12 21:34:36 W3SVC1 webserver 1.1.1.1 GET /webpage.html param1=11111&param2=22222&param3=&param4=4444444 80 - 2.2.2.2 HTTP/1.1 Java/1.8.0_121 - - balh.com 200 0 0 311 244 247 - -

我想为 param1、param2、param3 和 param4 添加字段。

我正在使用这个 grok 过滤器:

  grok {
    match => [ "message", "(?<param1>param1=(.*?)&)"]
  }

因此此正则表达式使用捕获组来获取 "param1=" 和“&”之间的文本。但是 grok 忽略了捕获组并得到 "param1=11111&" I just want to capture the "111111"

我怎么说使用捕获组 1 或告诉 grok 使用我的正则表达式捕获组?

编辑 这几乎可以工作:

  grok {
    match => [ "message", "(?<param1>param1=(?<param1>.*?)&)"]
  }

所以我猜测我在这里做的是使用两个命名组但名称相同。问题是 "param1" 字段中每个组都有两个条目。一个用于 "param1=11111&",一个用于“11111”。我怎样才能得到第二组?

这个有效:

  grok {
    match => [ "message", "(?:param1=(?<param1>.*?)&)"]
  }

所以我猜测我在这里做的是使用一个非捕获组,其中嵌套了一个命名的捕获组。所以父组的匹配被丢弃,嵌套的命名匹配是唯一返回的东西。

这是在按照我的想法行事,还是这是错误的,运气不好,它按照我的意愿行事?

How can I say use capture group 1 or tell grok to use my regex capture group?

默认情况下,只有 命名的捕获组 被 grok 考虑,编号的捕获组不会触发字段创建。如果您想覆盖此行为,请将 named_captures_only 设置为 false:

named_captures_only
- Value type is boolean
- Default value is true
If true, only store named captures from grok.

但是,使用命名捕获组并没有错(我会使用否定字符 class [^&]* 而不是带有消耗 & 的惰性匹配点在它之后):

\bparam1=(?<param1>[^&]*)

[^&]* 匹配 & 以外的 0 个或多个字符,因此也将匹配空参数(您可能希望通过将 * 更改为 +, 或用 keep_empty_captures 参数控制) 和字符串末尾.