使用 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.Request-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}=
因为这很容易导致不匹配。
我正在解析一组日志,其中一个字段给我带来了问题。 格式为
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.Request-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}=
因为这很容易导致不匹配。