SNMP 采集排障要有顺序。很多问题看起来都是“Dashboard 没数据”,但根因可能完全不同:设备 UDP 161 不通、community 错误、SNMPv3 认证失败、ACL 没放通、OID 不存在、MIB 名称无法解析、表格某个 tag 字段失败、filters 把所有行过滤掉、Categraf test 有数据但 remote write 没写入,或者 Dashboard 变量标签和实际指标不一致。
这篇文章给出一条可执行的排查路径。原则是:先证明 SNMP 协议可用,再证明 Categraf 能采到,再证明后端能查到,最后再看 Dashboard 和告警。
核心要点
- SNMP 问题先用
snmpwalk验证,不要直接在 Categraf 配置里猜。 snmp_up = 0只说明 Categraf 的 SNMP 探测失败;要继续区分网络、ACL、community、SNMPv3 和设备 SNMP 进程问题。snmp_icmp_up = 0不等于 SNMP 不通,设备可能禁 ping。- 表格没数据时,先去掉
filters,再确认 tag 字段、filter 字段和普通数值字段是否都能 walk。 partial能保留普通数值字段的部分成功结果,但不会牺牲标签和行身份正确性。--test只能证明采集侧输出,不证明 remote write 成功。- Dashboard 无数据时,先裸查真实指标,例如
snmp_interface_ifHCInOctets,再看变量和标签。
1. 先把问题分层
SNMP 链路可以拆成五层:
设备 SNMP 服务
-> 网络和 ACL
-> Categraf snmp 插件
-> remote write 后端
-> Dashboard 和告警
排障时不要跳层。比如 Dashboard 空白,不要一上来改 Dashboard;先查后端有没有裸指标。如果后端没有,再查 Categraf test。如果 test 也没有,再查 snmpwalk。
建议按下面顺序:
ping或网络探测;snmpwalk验证sysName.0;snmpwalk验证目标 OID;./categraf --test --inputs snmp;- 后端裸查
snmp_up和目标指标; - Dashboard 变量和 PromQL;
- 告警规则。
2. 验证网络和 UDP 161
SNMP 常用 UDP 161。先确认从 Categraf 所在机器到设备管理地址可达。
ping -c 4 10.10.10.11
如果设备禁 ping,这一步失败不代表 SNMP 一定失败。继续用 SNMP 命令验证。
如果有网络探测工具,可以检查 UDP 161,但 UDP 没有 TCP 那种可靠连接语义。最终仍要以 snmpwalk 为准。
常见网络问题:
- Categraf 不在设备 SNMP ACL 白名单;
- 采集源经过 NAT,设备看到的源地址不是你以为的地址;
- 管理网和业务网不通;
- 跨防火墙没有放通 UDP 161;
- 设备 SNMP 服务只监听管理 VRF。
3. 用 snmpwalk 验证最小 OID
SNMPv2c 先查 sysName.0:
snmpwalk -v2c -c '<COMMUNITY>' 10.10.10.11 1.3.6.1.2.1.1.5.0
再查 sysUpTime.0:
snmpwalk -v2c -c '<COMMUNITY>' 10.10.10.11 1.3.6.1.2.1.1.3.0
如果这两条都失败,Categraf 也大概率失败。先排:
- community 是否正确;
- 设备是否开启 SNMP;
- 设备 SNMP ACL 是否包含采集机;
- UDP 161 是否被防火墙拦截;
- 是否要使用 SNMPv3 而不是 v2c。
如果基础 OID 成功,再验证接口表:
snmpwalk -v2c -c '<COMMUNITY>' 10.10.10.11 1.3.6.1.2.1.31.1.1.1.1
snmpwalk -v2c -c '<COMMUNITY>' 10.10.10.11 1.3.6.1.2.1.31.1.1.1.6
第一条是 ifName,第二条是 ifHCInOctets。
4. SNMPv3 认证失败怎么查
SNMPv3 失败时,先用命令确认参数:
snmpwalk -v3 \
-l authPriv \
-u '<USER>' \
-a SHA \
-A '<AUTH_PASSWORD>' \
-x AES \
-X '<PRIV_PASSWORD>' \
10.10.10.11 \
1.3.6.1.2.1.1.5.0
对应 Categraf:
version = 3
sec_name = "<USER>"
sec_level = "authPriv"
auth_protocol = "SHA"
auth_password = "<AUTH_PASSWORD>"
priv_protocol = "AES"
priv_password = "<PRIV_PASSWORD>"
常见错误:
sec_level写成authPriv,设备侧是authNoPriv;auth_protocol不一致;priv_protocol不一致;- 密码复制时多了空格或特殊字符转义错误;
- 设备要求 context,配置里
context_name为空; - SNMPv3 用户只允许访问部分 view,目标 OID 不在权限范围内。
如果 sysName.0 能查,但接口表或私有 OID 查不到,重点看 SNMP view 权限,而不是网络。
5. MIB 名称无法解析怎么办
如果配置里写的是:
oid = "IF-MIB::ifHCInOctets"
Categraf 运行环境需要能解析 MIB。容器、最小化系统或缺少 net-snmp MIB 的机器上,可能会解析失败。
排查命令:
snmptranslate -On IF-MIB::ifHCInOctets
如果失败,可以:
- 安装对应 MIB;
- 配置
path = ["/usr/share/snmp/mibs"]; - 使用
translator = "gosmi"并加载 MIB; - 直接改用数字 OID。
生产配置建议优先使用数字 OID:
oid = "1.3.6.1.2.1.31.1.1.1.6" # IF-MIB::ifHCInOctets
这样更容易跨系统、容器和发布环境复用。
6. Categraf test 没有指标
先执行:
./categraf --test --inputs snmp
如果提示没有实例,检查:
- 配置目录是否正确;
conf/input.snmp/snmp.toml是否存在;[[instances]]是否取消注释;agents是否为空;- TOML 语法是否正确。
如果有 snmp_up = 0,说明插件运行了,但 SNMP 探测失败。回到 snmpwalk 验证。
如果有 snmp_up = 1,但没有表格指标,继续查:
- 表格 OID 是否存在;
- 字段 OID 是否存在;
filters是否过滤掉所有行;is_tag字段是否失败;inherit_tags依赖是否失败;- 是否使用了当前 Categraf 版本不支持的配置项。
7. filters 把所有行过滤掉
这是 SNMP 接口监控里最常见的问题之一。
先注释 filters:
#[[instances.table]]
# filters = [...]
# filters_expression = "..."
# filters_mode = "strict"
再运行:
./categraf --test --inputs snmp 2>&1 \
| rg 'snmp_interface_if(HCInOctets|OperStatus|InErrors)'
如果注释 filters 后有数据,说明采集没问题,是过滤条件不匹配。
排查正则时,要看设备真实接口命名。不同厂商可能是:
GigabitEthernet1/0/1
Ten-GigabitEthernet1/0/49
HundredGigE1/0/1
ge-0/0/0
xe-0/0/0
Eth-Trunk1
Vlanif100
不要直接照搬别人的 ifDescr 正则。
8. 表格字段失败怎么定位
表格里某个字段失败时,先单独 walk 这个字段。
例如怀疑 ifAlias:
snmpwalk -v2c -c '<COMMUNITY>' 10.10.10.11 1.3.6.1.2.1.31.1.1.1.18
怀疑 ifHCOutOctets:
snmpwalk -v2c -c '<COMMUNITY>' 10.10.10.11 1.3.6.1.2.1.31.1.1.1.10
如果字段不存在,可以选择:
- 删除该字段;
- 换成设备支持的 OID;
- 对低优先级字段使用
partial; - 对不同型号拆分配置模板。
不要为了一个设备不支持的字段,让同一组设备整张表都失败。
9. partial 结果怎么理解
新版 SNMP 插件支持:
default_table_error_policy = "partial"
dependency_cache_ttl = "10m"
如果看到 partial 相关指标增长:
increase(snmp_partial_table_total[10m])
increase(snmp_field_error_total[10m])
increase(snmp_dependency_cache_total[10m])
increase(snmp_dependency_skipped_rows_total[10m])
说明采集过程中发生过部分失败、字段错误、依赖缓存事件或行跳过。
这不一定代表业务故障,但代表采集质量需要关注。常见原因:
- 某个字段在部分设备上不存在;
- 某个 OID 偶发超时;
- 过滤字段读取失败;
- 标签字段读取失败;
- MIB 转换或值转换失败;
- 设备 SNMP 进程不稳定。
partial 的预期行为是保留普通数值字段的成功结果,但如果标签或过滤依赖未知,仍然会跳过行。看到跳过行时,优先查 tag 和 filter 字段。
10. snmp_up、icmp_up、health_state 的区别
SNMP 插件可能输出:
snmp_up
snmp_icmp_up
snmp_health_state
三者含义不同。
snmp_up:Categraf 能否通过 SNMP 读取设备基础 OID。
snmp_icmp_up:Categraf 能否 ICMP ping 通设备。
snmp_health_state:插件内部按采集失败、恢复探测等状态维护的 agent 健康状态。
典型场景:
| 现象 | 可能原因 |
|---|---|
snmp_up = 0,icmp_up = 1 |
SNMP ACL、community、SNMPv3、UDP 161 问题 |
snmp_up = 1,icmp_up = 0 |
设备禁 ping,但 SNMP 可用 |
health_state = 0 |
设备连续失败或恢复探测尚未成功 |
| 三者都异常 | 网络、设备宕机、管理地址不可达 |
告警时不要把三者混成一个含义。
11. test 有数据但后端查不到
--test 只验证采集输出,不验证 writer。正式模式后端查不到,要检查 remote write 链路。
先查 Categraf 日志:
journalctl -u categraf -n 200 --no-pager
再查配置:
sed -n '1,160p' conf/config.toml
重点看:
[[writers]].url是否正确;- 网络是否能访问后端;
- 后端是否返回 4xx 或 5xx;
- Categraf 发送队列是否堆积;
- 时间是否偏差太大;
- 后端租户、数据源、认证是否正确。
后端裸查:
snmp_up
snmp_interface_ifHCInOctets
snmp_health_state
如果裸指标没有,先修写入链路;不要先改 Dashboard。
12. Dashboard 没数据
Dashboard 没数据时,按下面顺序查。
第一,后端裸查指标:
snmp_up
snmp_interface_ifHCInOctets
snmp_interface_ifOperStatus
第二,确认标签:
snmp_interface_ifHCInOctets{ident="10.10.10.11"}
看指标上是否有 ident、source、ifName、ifAlias。
第三,检查 Dashboard 变量:
- 数据源是否正确;
- 变量查询使用的是
ident还是agent_host; - 变量值是否和实际标签一致;
- PromQL 指标名前缀是否正确;
- 时间范围是否覆盖采集时间。
第四,检查指标名。本文配置下接口流量是:
snmp_interface_ifHCInOctets
snmp_interface_ifHCOutOctets
如果 Dashboard 里写的是:
interface_ifInOctets
那就和实际输出不一致,需要修 Dashboard 或配置。
13. 告警没触发
告警没触发通常有几类原因。
第一,表达式本身查不到数据:
snmp_interface_ifAdminStatus == 1
and on (ident, index)
snmp_interface_ifOperStatus != 1
如果配置没有 index_as_tag = true,这里的 index 标签不存在,表达式就匹配不上。可以改用 ifIndex:
snmp_interface_ifAdminStatus == 1
and on (ident, ifIndex)
snmp_interface_ifOperStatus != 1
前提是 ifIndex 是 tag。
第二,标签名和告警模板不一致。比如配置用 agent_host,告警写 ident。
第三,告警持续时间太长,故障恢复太快,没有满足触发条件。
第四,设备本身没有采到目标指标。先裸查,再看告警。
14. 常见日志和处理方向
connection timeout
优先查网络、ACL、timeout、retries、设备 SNMP 进程负载。
no such object / no such instance
目标 OID 在该设备上不存在,或 SNMP view 没权限。用 snmpwalk 单独验证。
unknown security level / unknown username / wrong digest / decryption
SNMPv3 参数错误或设备侧用户配置不匹配。回到 snmpwalk -v3 验证。
translating error
MIB 名称无法解析。改用数字 OID,或修 MIB 路径和 translator。
result=partial
表格部分采集。查看字段错误、依赖缓存和跳过行统计,定位具体字段。
15. 一套完整排障命令
可以按下面顺序执行:
# 1. 基础 SNMP 连通性
snmpwalk -v2c -c '<COMMUNITY>' 10.10.10.11 1.3.6.1.2.1.1.5.0
# 2. 目标表验证
snmpwalk -v2c -c '<COMMUNITY>' 10.10.10.11 1.3.6.1.2.1.31.1.1.1.1
snmpwalk -v2c -c '<COMMUNITY>' 10.10.10.11 1.3.6.1.2.1.31.1.1.1.6
# 3. Categraf 测试模式
./categraf --test --inputs snmp
# 4. 过滤关键输出
./categraf --test --inputs snmp 2>&1 \
| rg 'snmp_(up|icmp_up|health_state|interface_ifHC|interface_ifOperStatus)'
# 5. 正式服务日志
journalctl -u categraf -n 200 --no-pager
后端查询:
snmp_up
snmp_health_state
snmp_interface_ifHCInOctets
increase(snmp_field_error_total[10m])
increase(snmp_partial_table_total[10m])
这套命令能覆盖大多数 SNMP 采集失败、部分采集和 Dashboard 无数据问题。
16. 生产建议
SNMP 排障最重要的是保留证据。每次新增设备或 OID,建议记录:
- 设备型号和系统版本;
- SNMP 版本和安全级别;
- 验证过的
snmpwalk命令; - 关键 OID 和返回样例;
- Categraf 配置片段;
- 后端裸指标截图或查询结果;
- Dashboard 变量和告警表达式。
这样后续遇到同型号设备时,不需要重新摸索。
对于社区文章、内部模板和生产配置,建议统一采用“数字 OID + 注释 MIB 名称”的写法,降低环境依赖。
最后,不要把 SNMP 排障归结为“Categraf 没采到”。SNMP 链路横跨设备、网络、权限、MIB、采集器、写入链路和 Dashboard。按层排查,才能快速定位真正的问题。