如何用单个Jolt Spec统一处理两种输入格式的IP字段提取?
解决方案
当然可以!单个Jolt Spec完全能搞定这个需求,而且实现起来还挺简洁的~
完整Jolt Spec
[ { "operation": "shift", "spec": { "creationTime": "created_ts", "device": { "ip": "src_ip_addr", "ip6": "src_ip_addr" } } }, { "operation": "default", "spec": { "src_ip_addr": null } } ]
操作逻辑解释
咱们拆解下这个Spec的作用:
- Shift转换:
- 首先把顶层的
creationTime直接映射到目标字段created_ts,完成时间字段的重命名。 - 针对
device下的ip和ip6,让它们都指向同一个目标字段src_ip_addr。Jolt在Shift操作中,如果多个源字段映射到同一个目标,会自动保留最后一个存在的字段值——刚好匹配你“两个字段只会存在其一”的场景。
- 首先把顶层的
- Default兜底:
- 如果经过Shift后,
src_ip_addr字段不存在(也就是ip和ip6都没提供),就给它设置默认值null,确保输出结构始终符合要求。
- 如果经过Shift后,
测试场景验证
咱们用你给出的几种输入来验证效果:
场景1:包含device.ip的输入
输入:
{ "creationTime": 1503999158000, "device": { "ip": "155.157.36.226", "hostname": "server-123.example.int" } }输出:
{ "created_ts": 1503999158000, "src_ip_addr": "155.157.36.226" }
场景2:包含device.ip6的输入
输入:
{ "creationTime": 1503999158000, "device": { "ip6": "2001::face", "hostname": "server-123.example.int" } }输出:
{ "created_ts": 1503999158000, "src_ip_addr": "2001::face" }
场景3:无ip/ip6的输入
输入:
{ "creationTime": 1503999158000, "device": { "hostname": "server-123.example.int" } }输出:
{ "created_ts": 1503999158000, "src_ip_addr": null }
额外说明
如果后续遇到极端情况(比如ip和ip6同时存在),可以通过调整Shift中字段的顺序来设置优先级:把你想优先保留的字段写在后面,因为后面的映射会覆盖前面的。比如想优先用ip6,就把ip6的映射放在ip之后即可。
内容的提问来源于stack exchange,提问作者Arj
相关产品推荐
相关产品推荐

