使用 Grok 捕获逗号分隔的模式

Catching a comma separated pattern with Grok

我正在解析一组日志,其中一个字段给我带来了问题。 格式为

header(ip, date etc.) field1=data, field2=data, field3=data, field4=data 我有一个通用的解析器,读起来像

match => [ "message","%{DATA:..header..} %{DATA}=%{DATA:service},%{DATA}=%{DATA:roles}],%{DATA}=%{DATA:macaddress},%{DATA}=%{DATA:nasip}"]

有时 "roles" 字段的 "value" 部分看起来像 值,[管理员]。这由 %{DATA}=%{DATA:roles}] 中的 ] 处理, 但在其他情况下我得到

subvalue1, subvalue2, subvalue3, 

subvalue1, subvalue2, subvalue3, subvalue4, 

subvalue1, subvalue2, 

并且解析器只捕获 subval1。如您所见.. 子值的数量是可变的,当缺少 ] 时很难捕捉到它们。

下面是日志创建问题的示例:

local1--debug--10.47.130.2--2017-03-24--2017-03-24T11:29:51-‌​04:00--11:29:51,545 10.241.186.253 ZTP0 SESSION 20 1 0 Common.Username=LABF5CHK,Common.Service=F5_HealthCHK,Common.‌​Roles=Employee, [User Authenticated],Common.NAS-IP-Address=xxxxxxxxxxxx,Common.Req‌​uest-Timestamp=2017-‌​03-24 11:27:56-04

有解决办法吗?

对于可变长度的逗号分隔数据,我建议将整组值捕获为一个字段,然后使用 csv filter.

解析该字段

为了解析一组键=值对,我建议使用 kv filter

因此您的配置将像这样工作

filter {
  grok {
    match => [ "message","%{DATA:..header..} %{GREEDYDATA:kv_pairs}"]
  }
  kv {
    source => "kv_pairs"
    field_split => ","
  }
  csv {
    # assumes that the key was 'roles'
    source => "roles"
    target => "role_list"
  }
}

我不确定您的日志消息的确切格式,但是如果您的消息的格式不将子值 csv 列表与 k=v 对列表分开,则 kv 过滤器可能会搞砸像这样:

...,key=value,roles=subval1,subval2,subval3,key2=value2...

或者使用 [ 打开列表但不关闭它。

编辑: 看起来第一个破案实际上就是您所面临的。

如果角色部分总是在同一个地方,后面跟着同一个键,您可以使用

匹配它
...Common.‌​Roles=%{DATA:roles},Common.NAS-IP-Address=%{DATA:nasip}...

如果这些 kv 对始终处于同一排列中,则使用此模式应该可行。如果一个字段完全一致或可以通过比 .*? 更具体的正则表达式匹配,你应该使用它,所以使用实际的键 names/patterns 而不是 %{DATA}= 因为这很容易导致不匹配。