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 匹配逻辑要点

  1. 最长前缀优先:如果有多个 trap_mapping 的 OID 命中,或者 varbind 命中,Categraf 会自动选择 OID 最长的那一条规则,确保匹配最精确。
  2. 层级边界对齐:为了防止误匹配(例如 OID 1.3.6 匹配到 1.3.60),插件会强制进行层级边界校验。
  3. 主 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 既能提供高度聚合的事件监控用于告警,又绝不丢失任何一个原始指标字段的数据!

更新时间 2025-11-12

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云