SNMP_Trap 插件
本文介绍监控数据采集器 Categraf 的 SNMP_Trap 接收插件与高级数据聚合配置
一、插件概述
1.1 插件功能介绍
snmp_trap 是 Categraf 提供的一个服务端插件,用于被动接收来自网络设备(交换机、路由器、防火墙、服务器等)发送的 SNMP Trap(SNMPv1, SNMPv2c, SNMPv3)通知。
与 snmp 轮询插件(Pull 模式)不同,snmp_trap 处于监听状态(Push 模式),当网络设备发生异常或状态变更(例如:端口宕掉、电源故障、BGP 邻居断开)时,设备会主动将告警事件发送到此插件配置的监听端口(默认 UDP 162)。
1.2 核心特性
- 全版本支持:支持 SNMPv1、v2c、v3。对于 v3,支持认证和加密(AuthPriv)。
- 指标聚合能力:支持将一个 Trap 中的多个离散变量(Varbinds)聚合成一个结构化的核心指标,并将部分变量转换为指标标签(Labels),极大地简化了 PromQL 告警规则的编写。
- 上下文继承(Dispersed Fallback):未被聚合规则消耗的变量会自动作为独立指标散落,且会自动继承已提取的公共上下文标签,确保不丢失任何现场数据。
- 最长前缀匹配:在处理复杂的 OID 匹配时,遵循“最长前缀优先”原则,并且强制进行层级边界对齐,防止
1.3.6.1...错误匹配到1.3.6.10...。
二、基本原理与默认指标生成
当 Categraf 收到一个 SNMP Trap 报文时,报文中会携带若干个变量绑定(Varbinds)。如果没有任何聚合配置,插件会为每一个 Varbind 独立生成一条指标,这被称为 散落指标(Dispersed Metrics)。
2.1 默认标签列表
无论是哪种配置,插件都会从 Trap PDU(协议数据单元)中提取以下默认元数据标签:
source:发送 Trap 的设备 IP 地址name:Trap 事件的名称(例如:link_down,如果没有加载 MIB,则显示为数字 OID)mib:事件所属的 MIB 库名称(例如:SNMPv2-MIB)oid:Trap 事件的完整 OID(对应 SNMPv2-MIB::snmpTrapOID.0)version:SNMP 版本(“1”、“2c” 或 “3”)context_name/engine_id:SNMPv3 特有标签
迁移与安全提示:在早期版本中,SNMP v1/v2c 的
community会作为标签保留。出于安全考虑(防止凭证泄露)以及避免标签高基数,该标签已在最新(开源版>=v0.5.9,企业版>=v0.5.24)版本中被彻底移除。如果您现有的告警面板依赖community标签,请尽快修改。
2.2 无聚合的默认行为
假设收到一个 linkDown Trap,里面携带了 3 个变量(接口索引、管理状态、操作状态),如果没有任何聚合规则,会生成类似如下的三条散落指标:
snmp_trap_ifIndex{source="127.0.0.1", version="2c", name="linkDown", ...} = 835
snmp_trap_ifAdminStatus{source="127.0.0.1", version="2c", name="linkDown", ...} = 1
snmp_trap_ifOperStatus{source="127.0.0.1", version="2c", name="linkDown", ...} = 2
问题:这三条指标相互独立,如果你想写一条告警规则:“当接口操作状态为2,且管理状态为1时告警”,在 PromQL 中将非常困难。这就是为什么需要引入 指标聚合。
三、全局指标聚合配置
指标聚合的核心目的,是将那些表述状态的字段变成 Label,从而把同一事件的数据捏合成一条有意义的核心指标。
3.1 fields_to_labels
白名单机制。定义哪些字段(MIB 翻译后的变量名)应该被当做 Label 处理,而不是生成独立的 Metric。
[[instances]]
service_address = "udp://0.0.0.0:162"
fields_to_labels = ["ifIndex", "ifAdminStatus", "ifOperStatus"]
3.2 varbind_mapping
对特定 OID 前缀的变量进行强制重命名,如果重命名后的名字命中了 fields_to_labels 白名单,同样会转为 Label。
[[instances]]
[instances.varbind_mapping]
# 将以该 OID 开头的变量重命名为 ifIndex
".1.3.6.1.2.1.2.2.1.1" = "ifIndex"
注意 (TOML 配置陷阱):因为
[instances.varbind_mapping]声明了一个子 Table,TOML 解析器会将它下方所有的键值对都归属于这个 Map。如果你同时配置了fields_to_labels,请务必确保fields_to_labels写在[instances.varbind_mapping]之前,否则会报incompatible types错误。
四、专属映射 (Trap Specific Mappings)
有时候全局配置不够灵活(不同 Trap 事件可能有同名变量但意义不同)。此时可以使用 trap_mapping,它允许你为特定的 Trap OID 定义专属的聚合规则。它在匹配的变量上优先级高于全局配置。
4.1 配置语法
[[instances]]
[[instances.trap_mapping]]
oid = ".1.3.6.1.6.3.1.1.5.3" # 目标 Trap 的 OID 前缀
name = "link_down" # 强制将核心指标名重写为 snmp_trap_link_down
value = ".1.3.6.1.2.1.1.3" # 指定某个变量的值作为该指标的主 Value (可选)
[[instances.trap_mapping.varbind]]
oid = ".1.3.6.1.2.1.2.2.1.1" # 采用最长前缀匹配
name = "ifIndex" # 直接将其转换为名为 ifIndex 的 Label
4.2 匹配逻辑要点
- 最长前缀优先:如果有多个
trap_mapping的 OID 命中,或者varbind命中,Categraf 会自动选择 OID 最长的那一条规则,确保匹配最精确。 - 层级边界对齐:为了防止误匹配(例如 OID
1.3.6匹配到1.3.60),插件会强制进行层级边界校验。 - 主 Value 回退:如果定义了
trap_mapping使得指标聚合生效,但没有匹配到value字段指定的主变量,该核心指标的值默认设置为1(非常适合配置> 0的存在性告警)。
五、经典场景教程
假设我们发送如下一个 SNMPv2c 的 Trap(包含了 sysUpTime, trapOID, 以及三个业务字段:接口索引835,管理状态1,操作状态2):
snmptrap -v 2c -c public 127.0.0.1:162 "" \
.1.3.6.1.6.3.1.1.5.3 \
.1.3.6.1.2.1.2.2.1.1.835 i 835 \
.1.3.6.1.2.1.2.2.1.7.835 i 1 \
.1.3.6.1.2.1.2.2.1.8.835 i 2
场景 A:纯聚合指标
我们希望把这 3 个业务字段全部塞进 Label,并把 sysUpTimeInstance 的值作为指标值。
[[instances]]
service_address = "udp://0.0.0.0:162"
fields_to_labels = ["ifAdminStatus", "ifOperStatus"]
[[instances.trap_mapping]]
oid = ".1.3.6.1.6.3.1.1.5.3"
name = "link_down"
value = ".1.3.6.1.2.1.1.3" # 将 sysUpTime 的值作为主值
[[instances.trap_mapping.varbind]]
oid = ".1.3.6.1.2.1.2.2.1.1"
name = "ifIndex"
输出结果: 变量被全部消耗,生成唯一一条高维度的核心指标:
snmp_trap_link_down{source="127.0.0.1",version="2c",oid=".1.3.6.1.6.3.1.1.5.3",name="link_down",mib="SNMPv2-MIB",ifIndex="835",ifAdminStatus="1",ifOperStatus="2"} = 123456
场景 B:上下文继承 (Dispersed Fallback)
如果我们在上文配置中注释掉 value = ".1.3.6.1.2.1.1.3",会发生什么?
此时,核心指标没有指定主值来源,默认被赋值为 1。而未被消耗的 sysUpTimeInstance 会回退成散落指标。
输出结果: 散落指标继承了核心指标收集到的所有业务 Label!
# 1. 核心事件指标(最适合配置 '> 0' 的实时告警)
snmp_trap_link_down{source="127.0.0.1",version="2c",oid=".1.3.6.1.6.3.1.1.5.3",name="link_down",mib="SNMPv2-MIB",ifIndex="835",ifAdminStatus="1",ifOperStatus="2"} = 1
# 2. 散落的回退指标(保留了全量上下文)
snmp_trap_sysUpTimeInstance{source="127.0.0.1",version="2c",oid=".1.3.6.1.6.3.1.1.5.3",name="link_down",mib="SNMPv2-MIB",ifIndex="835",ifAdminStatus="1",ifOperStatus="2"} = 123456
通过这种机制,snmp_trap 既能提供高度聚合的事件监控用于告警,又绝不丢失任何一个原始指标字段的数据!