使用 Prometheus 的 SNMP Exporter 从 net-snmp 收集指标的备忘录
我在运行net-snmp的主机上设置了SNMP Exporter,以便在Prometheus中收集指标。然而,根据我在谷歌上找到的信息,由于版本不同,它似乎不太稳定。因此,我根据以下内容进行了设置的备忘录。
- https://github.com/prometheus/snmp_exporter/
大致按照以下进行设置即可。
- https://github.com/prometheus/snmp_exporter/blob/v0.4.0/snmp.yml
这是由下述工具自动生成的内容。
- https://github.com/prometheus/snmp_exporter/tree/v0.4.0/generator
概述设定文件的说明
我們目前使用的 SNMP Exporter 版本是最新的 v0.4.0。
以下是从net-snmp设备中获取度量值的配置文件示例(度量值的详细信息将在后面说明)。
# snmp.yml
default:
version: 2
auth:
community: hogehoge
walk:
- 1.3.6.1.4.1.2021.4 # UCD-SNMP-MIB::memory
- 1.3.6.1.4.1.2021.9 # UCD-SNMP-MIB::dskTable
- 1.3.6.1.4.1.2021.11 # UCD-SNMP-MIB::systemStats
metrics:
... snip ...
“default”是在Prometheus的配置文件中指定的module参数的值。例如,在prometheus.yml文件中可以指定如下内容。
# prometheus.yml
- job_name: snmp
... snip ...
params:
module: [default]
当需要通过一个SNMP Exporter来监控多种设备时,您可以按照以下方式定义多个模块。
# snmp.yml
linux:
version: 2
auth:
community: hogehoge
walk:
- 1.3.6.1.4.1.2021.4 # UCD-SNMP-MIB::memory
- 1.3.6.1.4.1.2021.9 # UCD-SNMP-MIB::dskTable
- 1.3.6.1.4.1.2021.11 # UCD-SNMP-MIB::systemStats
metrics:
... snip ...
network:
version: 2
auth:
community: hogehoge
walk:
- 1.3.6.1.2.1.2 # IF-MIB::interfaces
metrics:
... snip ...
版本是用于使用的SNMP协议版本。例如1、2或3。在与版本相同的层次上,还可以设置max_repititions、retries和timeout等参数。
使用auth来指定认证信息。如果协议版本为1或2,则只需要指定community,但如果为3,则需指定其他参数(security_level、username、password、auth_protocol、priv_protocol、priv_password)。
Walk函数在SNMP Exporter中指定了要获取的树状OID。它会获取所有与指定的OID相关的数据。似乎不需要前面的点号(在指定其他OID的地方也是一样)。
只通过walk指定不会将其作为Prometheus的度量指标导出。您需要通过snmpwalk获取的值来指定导出的度量指标类型。
这是有关指标(metrics)的一个例子。
# snmp.yml
default:
... snip ...
metrics:
- name: sysUpTime
oid: 1.3.6.1.2.1.1.3.0
type: gauge
- name: ifInOctets
oid: 1.3.6.1.2.1.2.2.1.10
type: counter
indexes:
- labelname: ifIndex
type: Integer32
lookups:
- labelname: ifDescr
labels: [ifIndex]
oid: 1.3.6.1.2.1.2.2.1.2
type: DisplayString
在这个例子中我设置了两个指标sysUpTime和ifInOctets。
sysUpTime 获取单个值的例子。OID 1.3.6.1.2.1.1.3.0 的值将作为名为 sysUpTime 的度量指标进行导出。由于简单,因此不需要进行解释。
ifInOctets 是从 SEQUENCE 中获取值的示例。1.3.6.1.2.1.2.2.1.10 返回具有后缀 .1 或 .2 等索引的多个接口的值,请将它们作为指标标签区分,并导出为多个值。
使用索引来指定附加在后缀上的索引类型和要标记的指标。在这个例子中,索引是一个整数,如 .1 ,所以只需指定一个 Integer32,并将其值作为标签附加在指标上,标签名称为 ifIndex。
lookups 是用于补充指标的标签。只有 ifIndex 无法提供足够的信息,因此需要使用可理解的标签,如设备名称。
在这个例子中,我们将标签中指定的 ifIndex 值作为后缀添加到 OID 1.3.6.1.2.1.2.2.1.2 中,并将获取的值解释为 DisplayString 类型的值,并将其设置为指标的 ifDescr 标签。
如果数据以类似以下的 OID 获取到的话,
.1.3.6.1.2.1.2.2.1.1.1 = INTEGER: 1
.1.3.6.1.2.1.2.2.1.1.2 = INTEGER: 2
.1.3.6.1.2.1.2.2.1.2.1 = STRING: lo
.1.3.6.1.2.1.2.2.1.2.2 = STRING: eth0
.1.3.6.1.2.1.2.2.1.10.1 = Counter32: 2878606
.1.3.6.1.2.1.2.2.1.10.2 = Counter32: 847816235
.1.3.6.1.2.1.2.2.1.10.1 和 .1.3.6.1.2.1.2.2.1.10.2 的值被导出为指标,分别附带标签 ifIndex=1 和 ifIndex=2。此外,根据添加了后缀 .1 和 .2 的 OID .1.3.6.1.2.1.2.2.1.2,分别附带标签 ifDescr=lo 和 ifDescr=eth0。
最终结果将获得以下度量指标。
ifInOctets{ifIndex="1",ifDescr="lo"} 2878606
ifInOctets{ifIndex="2",ifDescr="eth0"} 847816235
指标的类型
- https://github.com/prometheus/snmp_exporter/blob/v0.4.0/collector.go#L177-L180
通常情况下,指标的类型通常会指定为counter或gauge。您可以使用snmptranslate -Tp 命令来大致确定应指定哪一个。例如,如果是Integer类型的指标,使用gauge;如果是Counter类型的指标,则使用counter。
snmptranslate -Tp .1.3.6.1.4.1.2021.11
# +--systemStats(11)
# |
# +-- -R-- Integer32 ssIndex(1)
# +-- -R-- String ssErrorName(2)
# | Textual Convention: DisplayString
# | Size: 0..255
# +-- -R-- Integer32 ssSwapIn(3)
# +-- -R-- Integer32 ssSwapOut(4)
# +-- -R-- Integer32 ssIOSent(5)
# +-- -R-- Integer32 ssIOReceive(6)
# +-- -R-- Integer32 ssSysInterrupts(7)
# +-- -R-- Integer32 ssSysContext(8)
# +-- -R-- Integer32 ssCpuUser(9)
# +-- -R-- Integer32 ssCpuSystem(10)
# +-- -R-- Integer32 ssCpuIdle(11)
# +-- -R-- Counter ssCpuRawUser(50)
# +-- -R-- Counter ssCpuRawNice(51)
# +-- -R-- Counter ssCpuRawSystem(52)
# +-- -R-- Counter ssCpuRawIdle(53)
# +-- -R-- Counter ssCpuRawWait(54)
# +-- -R-- Counter ssCpuRawKernel(55)
# +-- -R-- Counter ssCpuRawInterrupt(56)
# +-- -R-- Counter ssIORawSent(57)
# +-- -R-- Counter ssIORawReceived(58)
# +-- -R-- Counter ssRawInterrupts(59)
# +-- -R-- Counter ssRawContexts(60)
# +-- -R-- Counter ssCpuRawSoftIRQ(61)
# +-- -R-- Counter ssRawSwapIn(62)
# +-- -R-- Counter ssRawSwapOut(63)
# +-- -R-- Counter ssCpuRawSteal(64)
# +-- -R-- Counter ssCpuRawGuest(65)
# +-- -R-- Counter ssCpuRawGuestNice(66)
如果类型不是其他或未指定,则将其视为字符串项目,并将指标名称直接作为标签,获取的值将设置为该标签的值(指标值固定为1)。
根据类型参数指定的值进行字符串化处理。
-
- https://github.com/prometheus/snmp_exporter/blob/v0.4.0/collector.go#L223
- https://github.com/prometheus/snmp_exporter/blob/v0.4.0/collector.go#L266
如果未指定,OctetString会转换为16进制字符串,因此需要指定适当的类型。通常情况下,使用DisplayString即可。
如果在SNMPv2-MIB::system的sysUpTime或sysName上进行如下设置。
metrics:
- name: sysUpTime
oid: 1.3.6.1.2.1.1.3.0
type: gauge
- name: sysName
oid: 1.3.6.1.2.1.1.5.0
type: DisplayString
可以得到以下的指标。
# HELP sysName
# TYPE sysName gauge
sysName{sysName="example.com"} 1
# HELP sysUpTime
# TYPE sysUpTime gauge
sysUpTime 8.28781844e+08
索引和查询的类型
在索引和查找中,我们指定了下面的开关的类型。
- https://github.com/prometheus/snmp_exporter/blob/v0.4.0/collector.go#L266
参考MIB的定义进行设置会更好。
通常情况下,indexes是Integer32(或者也可以是gauge)。在IP-MIB::ip或TCP-MIB::tcp表中可能会有例外情况,但我认为在Prometheus中不会收集此类数据。
在大多数情况下,lookups 是 DisplayString。如果标签的值是 IP 地址之类的,根据需要进行相应的更改。
SNMP.yml文件的示例
这是一个用于收集 net-snmp 指标的配置文件示例。由于是手写的,所以尽量使用别名和锚点来消除重复。
linux:
version: 2
auth:
community: hogehoge
walk:
- 1.3.6.1.2.1.1.1 # SNMPv2-MIB::sysDescr
- 1.3.6.1.2.1.1.3 # SNMPv2-MIB::sysUpTime
- 1.3.6.1.2.1.1.5 # SNMPv2-MIB::sysName
- 1.3.6.1.2.1.2 # IF-MIB::interfaces
- 1.3.6.1.2.1.6.5 # TCP-MIB::tcpActiveOpens
- 1.3.6.1.2.1.6.6 # TCP-MIB::tcpPassiveOpens
- 1.3.6.1.2.1.6.7 # TCP-MIB::tcpAttemptFails
- 1.3.6.1.2.1.6.8 # TCP-MIB::tcpEstabResets
- 1.3.6.1.2.1.6.9 # TCP-MIB::tcpCurrEstab
- 1.3.6.1.4.1.2021.4 # UCD-SNMP-MIB::memory
- 1.3.6.1.4.1.2021.9 # UCD-SNMP-MIB::dskTable
- 1.3.6.1.4.1.2021.10.1.5 # UCD-SNMP-MIB::laLoadInt
- 1.3.6.1.4.1.2021.11 # UCD-SNMP-MIB::systemStats
- 1.3.6.1.4.1.2021.13.15.1 # UCD-DISKIO-MIB::diskIOTable
metrics:
################################################################################
# SNMPv2-MIB::system
- { name: sysDescr, oid: 1.3.6.1.2.1.1.1.0, type: DisplayString }
- { name: sysUpTime, oid: 1.3.6.1.2.1.1.3.0, type: gauge }
- { name: sysName, oid: 1.3.6.1.2.1.1.5.0, type: DisplayString }
################################################################################
# IF-MIB::interfaces
- &interfaces
name: ifIndex
oid: 1.3.6.1.2.1.2.2.1.1
type: gauge
indexes:
- labelname: ifIndex
type: Integer32
lookups:
- labelname: ifDescr
labels: [ifIndex]
oid: 1.3.6.1.2.1.2.2.1.2
type: DisplayString
- labelname: ifAdminStatus
labels: [ifIndex]
oid: 1.3.6.1.2.1.2.2.1.7
type: Integer32
- <<: *interfaces
name: ifMtu
oid: 1.3.6.1.2.1.2.2.1.4
type: gauge
- <<: *interfaces
name: ifSpeed
oid: 1.3.6.1.2.1.2.2.1.5
type: gauge
- <<: *interfaces
name: ifOperStatus
oid: 1.3.6.1.2.1.2.2.1.8
type: gauge
- <<: *interfaces
name: ifInOctets
oid: 1.3.6.1.2.1.2.2.1.10
type: counter
- <<: *interfaces
name: ifInUcastPkts
oid: 1.3.6.1.2.1.2.2.1.11
type: counter
- <<: *interfaces
name: ifInNUcastPkts
oid: 1.3.6.1.2.1.2.2.1.12
type: counter
- <<: *interfaces
name: ifInDiscards
oid: 1.3.6.1.2.1.2.2.1.13
type: counter
- <<: *interfaces
name: ifInErrors
oid: 1.3.6.1.2.1.2.2.1.14
type: counter
- <<: *interfaces
name: ifInUnknownProtos
oid: 1.3.6.1.2.1.2.2.1.15
type: counter
- <<: *interfaces
name: ifOutOctets
oid: 1.3.6.1.2.1.2.2.1.16
type: counter
- <<: *interfaces
name: ifOutUcastPkts
oid: 1.3.6.1.2.1.2.2.1.17
type: counter
- <<: *interfaces
name: ifOutNUcastPkts
oid: 1.3.6.1.2.1.2.2.1.18
type: counter
- <<: *interfaces
name: ifOutDiscards
oid: 1.3.6.1.2.1.2.2.1.19
type: counter
- <<: *interfaces
name: ifOutErrors
oid: 1.3.6.1.2.1.2.2.1.20
type: counter
- <<: *interfaces
name: ifOutQLen
oid: 1.3.6.1.2.1.2.2.1.21
type: gauge
################################################################################
# TCP-MIB::tcp
- { name: tcpActiveOpens , oid: 1.3.6.1.2.1.6.5 , type: counter }
- { name: tcpPassiveOpens , oid: 1.3.6.1.2.1.6.6 , type: counter }
- { name: tcpAttemptFails , oid: 1.3.6.1.2.1.6.7 , type: counter }
- { name: tcpEstabResets , oid: 1.3.6.1.2.1.6.8 , type: counter }
- { name: tcpCurrEstab , oid: 1.3.6.1.2.1.6.9 , type: gauge }
################################################################################
# UCD-SNMP-MIB::memory
- { name: memTotalSwap , oid: 1.3.6.1.4.1.2021.4.3.0 , type: gauge }
- { name: memAvailSwap , oid: 1.3.6.1.4.1.2021.4.4.0 , type: gauge }
- { name: memTotalReal , oid: 1.3.6.1.4.1.2021.4.5.0 , type: gauge }
- { name: memAvailReal , oid: 1.3.6.1.4.1.2021.4.6.0 , type: gauge }
- { name: memTotalFree , oid: 1.3.6.1.4.1.2021.4.11.0 , type: gauge }
- { name: memMinimumSwap , oid: 1.3.6.1.4.1.2021.4.12.0 , type: gauge }
- { name: memBuffer , oid: 1.3.6.1.4.1.2021.4.14.0 , type: gauge }
- { name: memCached , oid: 1.3.6.1.4.1.2021.4.15.0 , type: gauge }
################################################################################
# UCD-SNMP-MIB::dskTable
- &dskTable
name: dskIndex
oid: 1.3.6.1.4.1.2021.9.1.1
type: gauge
indexes:
- labelname: dskIndex
type: Integer32
lookups:
- labelname: dskPath
labels: [dskIndex]
oid: 1.3.6.1.4.1.2021.9.1.2
type: DisplayString
- labelname: dskDevice
labels: [dskIndex]
oid: 1.3.6.1.4.1.2021.9.1.3
type: DisplayString
- <<: *dskTable
name: dskTotal
oid: 1.3.6.1.4.1.2021.9.1.6
type: gauge
- <<: *dskTable
name: dskTotal
oid: 1.3.6.1.4.1.2021.9.1.6
type: gauge
- <<: *dskTable
name: dskAvail
oid: 1.3.6.1.4.1.2021.9.1.7
type: gauge
- <<: *dskTable
name: dskUsed
oid: 1.3.6.1.4.1.2021.9.1.8
type: gauge
################################################################################
# UCD-SNMP-MIB::laLoadInt
- { name: laLoadInt1 , oid: 1.3.6.1.4.1.2021.10.1.5.1 , type: gauge }
- { name: laLoadInt5 , oid: 1.3.6.1.4.1.2021.10.1.5.2 , type: gauge }
- { name: laLoadInt15 , oid: 1.3.6.1.4.1.2021.10.1.5.3 , type: gauge }
################################################################################
# UCD-SNMP-MIB::systemStats
- { name: ssCpuRawUser , oid: 1.3.6.1.4.1.2021.11.50.0 , type: counter }
- { name: ssCpuRawNice , oid: 1.3.6.1.4.1.2021.11.51.0 , type: counter }
- { name: ssCpuRawSystem , oid: 1.3.6.1.4.1.2021.11.52.0 , type: counter }
- { name: ssCpuRawIdle , oid: 1.3.6.1.4.1.2021.11.53.0 , type: counter }
- { name: ssCpuRawWait , oid: 1.3.6.1.4.1.2021.11.54.0 , type: counter }
- { name: ssCpuRawKernel , oid: 1.3.6.1.4.1.2021.11.55.0 , type: counter }
- { name: ssCpuRawInterrupt , oid: 1.3.6.1.4.1.2021.11.56.0 , type: counter }
- { name: ssIORawSent , oid: 1.3.6.1.4.1.2021.11.57.0 , type: counter }
- { name: ssIORawReceived , oid: 1.3.6.1.4.1.2021.11.58.0 , type: counter }
- { name: ssRawInterrupts , oid: 1.3.6.1.4.1.2021.11.59.0 , type: counter }
- { name: ssRawContexts , oid: 1.3.6.1.4.1.2021.11.60.0 , type: counter }
- { name: ssCpuRawSoftIRQ , oid: 1.3.6.1.4.1.2021.11.61.0 , type: counter }
- { name: ssRawSwapIn , oid: 1.3.6.1.4.1.2021.11.62.0 , type: counter }
- { name: ssRawSwapOut , oid: 1.3.6.1.4.1.2021.11.63.0 , type: counter }
################################################################################
# UCD-DISKIO-MIB::diskIOTable
- &diskIOTable
name: diskIOIndex
oid: 1.3.6.1.4.1.2021.13.15.1.1.1
type: gauge
indexes:
- labelname: diskIOIndex
type: Integer32
lookups:
- labelname: diskIODevice
labels: [diskIOIndex]
oid: 1.3.6.1.4.1.2021.13.15.1.1.2
type: DisplayString
- <<: *diskIOTable
name: diskIONRead
oid: 1.3.6.1.4.1.2021.13.15.1.1.3
type: counter
- <<: *diskIOTable
name: diskIONWritten
oid: 1.3.6.1.4.1.2021.13.15.1.1.4
type: counter
- <<: *diskIOTable
name: diskIOReads
oid: 1.3.6.1.4.1.2021.13.15.1.1.5
type: counter
- <<: *diskIOTable
name: diskIOWrites
oid: 1.3.6.1.4.1.2021.13.15.1.1.6
type: counter