通过 Categraf SNMP 插件采集监控数据

秦晓辉@快猫星云 2022年11月9日

SNMP-Categraf

简介

通过《SNMP(简单网络管理协议)简介》和《SNMP命令相关参数介绍》两个文章,我们大体可以了解SNMP的基础知识了。

基于SNMP协议采集监控数据,原理很简单,就是通过配置SNMP agent连接地址、认证信息、要采集的OID信息,让监控采集器连到SNMP agent上去,获取相关数据即可。这里唯一有一点需要跟大家交代的是,监控数据分两种类型,一种是 Scalar 类型,OID都是.0结尾的,另一种是 Table 类型,下文详述。

获取 Scalar 数据

Categraf 的 SNMP 插件的配置在 conf/input.snmp 目录,我这里给一个配置样例,就着这个例子来做解释。

interval = 60

[[instances]]
agents = ["udp://172.30.15.189:161"]

timeout = "5s"
version = 2
community = "public"
agent_host_tag = "ident"
retries = 1

[[instances.field]]
oid = "RFC1213-MIB::sysUpTime.0"
name = "uptime"

[[instances.field]]
oid = "RFC1213-MIB::sysName.0"
name = "source"
is_tag = true

[[instances.table]]
oid = "IF-MIB::ifTable"
name = "interface"
inherit_tags = ["source"]

[[instances.table.field]]
oid = "IF-MIB::ifDescr"
name = "ifDescr"
is_tag = true

这里我要采集的交换机 IP 是 172.30.15.189,snmpd 通常监听在 161 端口,所以 agents 中配置了这个交换机的地址,为啥配置项的名称叫 agents 而不是叫 targets、addresses 之类的呢?因为在 SNMP 网络中,响应 SNMP 查询的那个软件就称为 SNMP agent,发起 snmpget 查询的那个软件称为 SNMP manager,在前面的文章中有介绍。

agents 是个数组,这就意味着,可以监控很多台设备,当然,instances 这一大段都是数组结构,即可以有很多个 instances 配置段,这个是 toml 格式的配置,关于 toml 的相关知识就不展开了,跟本文主题无关。

agents 后面是超时和认证信息相关的配置,最核心的是 version 和 community,这里使用是 2 版本,community 中也给出了认证团体名。agent_host_tag 字段配置成了 ident,这表示:采集上报的时序数据中,会带上 ident=172.30.15.189 这个标签,标签值显然就是交换机的 IP,标签名就是agent_host_tag指定的名称。这个数据如果上报给 Nightingale,Nightingale针对ident标签有个特殊逻辑,会把ident的值解析出来,放到对象列表里,你就可以在对象列表的页面中看到这个设备了。不过呢,通常对象列表里放置的都是部署 Categraf 的机器,而这里是交换机,不是一类对象,也可以选择不把交换机放进来,看你们的管理习惯,不把交换机放到对象列表里也很简单,修改 agent_host_tag 的配置,不要叫 ident 了就可以了,比如叫 agent_host_tag = "switch_ip"

instances.field 有两个,一个是获取系统启动时间(OID是RFC1213-MIB::sysUpTime.0),一个是获取系统名称(OID是RFC1213-MIB::sysName.0),instances.field 配置的采集项,实际是通过 snmpget 的方式来发请求获取的。你可以使用如下命令做测试:

snmpget -v2c -c public 172.30.15.189 RFC1213-MIB::sysUpTime.0

因为 name = "uptime" 这个配置的原因,采集到数据metric会命名成 snmp_uptime,snmp是前缀,uptime就是name字段指定的。看起来挺顺畅。但是,为啥sysName的获取多了一个 is_tag = true 的配置呢?因为 sysName 是个字符串,不是要上报的监控数据,通过 snmpget 获取到 sysName 之后,会作为一个标签 source=$sysName 附到所有时序数据上。

获取 Table 类数据

[[instances.table]]
oid = "IF-MIB::ifTable"
name = "interface"
inherit_tags = ["source"]

[[instances.table.field]]
oid = "IF-MIB::ifDescr"
name = "ifDescr"
is_tag = true

这一段配置是采集 Table 类型的数据,这个 Table 的 OID 是 IF-MIB::ifTable,Table里有多列数据,也有多个索引,Categraf会自动获取Table中的所有索引字段做成时序数据的标签,会自动获取所有的数据列,作为指标上报。但是,有些列可能不是数值,比如 ifDescr 就是字符串,这个列无需作为指标上报,应该作为标签上报更合适,所以有个 is_tag=true 的配置。

inherit_tags 表示继承下来的标签,ifTable 收集到的数据就会自动附上 source 标签。

资料参考

更多 SNMP Table 类型的知识,可以参考这个博客:《2018-08-23-snmp笔记》,非常值得看!