如何使用Fluentd插件解析含动态键的字段?
解析带动态键的SNMP日志JSON方案
需求
从包含动态键(如IF-MIB::ifDescr.16896000,数字部分可变)的SNMP日志JSON结构中,提取interface(对应IF-MIB::ifDescr.*键的值)和host字段。
输入示例
message= [ { "SNMPv2-MIB::sysUpTime.0":"338 days, 20:31:17.37", "SNMPv2-MIB::snmpTrapOID.0":"IF-MIB::linkDown", "IF-MIB::ifAdminStatus.16896000":"1", "IF-MIB::ifOperStatus.16896000":"2", "IF-MIB::ifDescr.16896000":"fc1/30", "host":"192.168.21.15" } ]
期望输出
output= [ { "interface":"fc1/30", "host":"192.168.21.15" } ]
曾尝试的无效配置
grep插件配置
@type grep <regexp> key message pattern ??? </regexp>
parser插件配置
@type parser key_name message emit_invalid_record_to_error false <parse> @type regexp expression /IF-MIB::ifDescr.*=>(?<interface>.*)/ </parse>
可行解析方案
由于日志中的键是动态可变的,直接用正则或基础插件难以处理,推荐先将message解析为JSON结构,再通过脚本过滤器提取目标字段:
步骤1:解析message为JSON结构
先用parser插件将字符串格式的message解析为JSON数组:
<filter **> @type parser key_name message emit_invalid_record_to_error false <parse> @type json </parse> </filter>
步骤2:用Ruby过滤器提取目标字段
通过Ruby脚本遍历解析后的JSON对象,匹配动态键并提取值:
<filter **> @type ruby code > if record['message'].is_a?(Array) output_items = [] record['message'].each do |snmp_item| # 匹配所有以IF-MIB::ifDescr.开头的键,取出对应值 interface_val = snmp_item.keys.select { |k| k.start_with?('IF-MIB::ifDescr.') }.map { |k| snmp_item[k] }.first # 组装目标字段 output_items << { 'interface' => interface_val, 'host' => snmp_item['host'] } end record['output'] = output_items # 可选:删除原始message字段 record.delete('message') end </filter>
方案说明
- 先将
message字段从字符串解析为可操作的JSON数组,避免直接正则匹配字符串带来的精度问题; - 通过Ruby脚本遍历每个SNMP记录对象,动态匹配
IF-MIB::ifDescr.前缀的键,确保无论数字后缀如何变化都能正确取值; - 直接提取
host字段,组装成期望的输出结构。
内容的提问来源于stack exchange,提问作者user24980214
相关产品推荐
相关产品推荐

