net-snmp が動いているホストから Prometheus でメトリクス収集するために SNMP Exporter を設定していたのだけど、ググって出てくる情報だとバージョン違いでわりと動かないっぽい気がしたので、下記を見ながら設定したメモ。
概ね下記を参考に設定すれば OK です。
これは下記のツールで自動生成されたものです。
ざっくりした設定ファイルの説明
SNMP Exporter のバージョンは現時点で最新の v0.4.0 を使っています。
net-snmp の機器からメトリクスを取得する設定ファイルの例です(metrics
の箇所は後述します)。
# 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]
1つの 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 ...
version
は使用する SNMP プロトコルバージョンです。1 とか 2 とか 3 とか。version
と同じ階層で、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
で指定します。
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
この例では2つのメトリクス 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
のようなインデックスが付いて複数の I/F の値を返しますが、それらをメトリクスのラベルで区別して複数の値としてエクスポートします。
indexes
でサフィックスに付くインデックスの型と、メトリクスに付与するラベルを指定します。この例だとインデックスは .1
のように整数1個なので、Integer32
を1つだけ指定し、その値でメトリクスに ifIndex
というラベルを付けます。
lookups
はメトリクスに追加で付与するラベルです。ifIndex
だけだとインデックス番号しか無いので、デバイス名などのわかりやすいラベルを付けるために使います。
この例だと、OID 1.3.6.1.2.1.2.2.1.2
に labels
で指定された ifIndex
の値をサフィックスとして追加し、取得した値を 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.3.6.1.2.1.2.2.1.2
にサフィックス .1
と .2
を付与した OID を元に ifDescr=lo
と ifDescr=eth0
というラベルが付きます。
結果、下記のようなメトリクスが得られます。
ifInOctets{ifIndex="1",ifDescr="lo"} 2878606
ifInOctets{ifIndex="2",ifDescr="eth0"} 847816235
metrics の type
metrics
の type
には大抵の場合は counter
か gauge
を指定します。どちらを指定するかは snmptranslate -Tp <oid>
でなんとなくわかると思います。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)
type
がそれ以外や未指定の場合は文字列項目であるとみなされて、メトリクス名がそのままラベルになり、そのラベルの値に取得した値が設定されます(メトリクスの値は 1
で固定)。
このとき type
で指定した値に応じて文字列化が行われます。
- 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
indexes や lookups の type
indexes
や lookups
の type
には下記の switch
にあるものを指定します。
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