如何构建Grok模式:以metric_path为动态字段名、metric_value_number为数值?
没问题,我来帮你搞定这个动态字段的Grok配置需求!先理清楚咱们要做的事:把日志里动态变化的metric_path值当成字段名,再把metric_value_number的数值赋值给这个新字段。下面一步步来:
首先先明确你的原始日志样例,方便后续参考:
metric_value_number:1 path:/opt/jmxd/ @timestamp:January 5th 2018, 12:16:16.652 @version:1 host:server1 metric_path:dumper.PlugableGroupConsumer-0.running_bool type:jmx _id:NLEJxmABgpl3QdqYJlaX _type:jmx _index:jmx-2018.01.05 _score:
第一步:用Grok提取核心临时字段
Grok本身没办法直接把动态值作为字段名,所以我们先把metric_value_number和metric_path这两个关键信息提取成临时字段,Grok模式可以这么写:
metric_value_number:%{NUMBER:temp_value} path:%{DATA:path} @timestamp:%{DATA:@timestamp} @version:%{NUMBER:@version} host:%{DATA:host} metric_path:%{DATA:temp_metric_name} type:%{DATA:type} _id:%{DATA:_id} _type:%{DATA:_type} _index:%{DATA:_index} _score:%{DATA:_score}
这里的temp_value(存储指标数值)和temp_metric_name(存储动态字段名)是临时过渡字段,后续用来生成目标字段。
第二步:用Ruby Filter动态创建目标字段
接下来需要借助Logstash的Ruby Filter(如果用Elastic Agent/Fleet的话,可以用Processor组件实现类似逻辑),把临时字段转换成我们想要的动态字段:
ruby { code => " # 取出临时字段的值 metric_name = event.get('temp_metric_name') metric_value = event.get('temp_value').to_f # 转成浮点数,需要整数的话换成to_i # 确保两个字段都存在时再创建新字段 if metric_name && metric_value event.set(metric_name, metric_value) # 可选:删除临时字段,保持数据整洁 event.remove('temp_metric_name') event.remove('temp_value') end " }
这段代码的逻辑很直白:
- 提取临时字段的内容
- 把指标数值转换成合适的数值类型(避免存成字符串)
- 创建一个以
temp_metric_name值为名称的新字段,把指标数值赋值给它 - 可选删除临时字段,减少冗余数据
最终效果
经过上面的配置处理后,你的数据里就会出现一个名为dumper.PlugableGroupConsumer-0.running_bool的字段,它的数值是1,完全匹配你的需求。
额外简化技巧
如果你的日志里所有内容都是key:value的格式,也可以先用kv filter批量提取所有字段,这样Grok模式可以省掉很多内容:
kv { field_split => " " value_split => ":" }
运行这个filter后,所有key:value对都会自动变成字段,之后再用上面的Ruby Filter处理metric_path和metric_value_number就行,配置会更简洁。
内容的提问来源于stack exchange,提问作者qubsup

