Help us understand the problem. What is going on with this article?

Prometheus の SNMP Exporter で net-snmp からメトリクス収集するメモ

More than 3 years have passed since last update.

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つのメトリクス sysUpTimeifInOctets を設定しています。

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.2labels で指定された 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=loifDescr=eth0 というラベルが付きます。

結果、下記のようなメトリクスが得られます。

ifInOctets{ifIndex="1",ifDescr="lo"} 2878606
ifInOctets{ifIndex="2",ifDescr="eth0"} 847816235

metrics の type

metricstype には大抵の場合は countergauge を指定します。どちらを指定するかは snmptranslate -Tp <oid> でなんとなくわかると思います。Integer とかは gaugeCounter とかは 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 で指定した値に応じて文字列化が行われます。

未指定だと OctetString で16進文字列になるため、適切な型を指定する必要があります。大抵は DisplayString で良いです。

例えば SNMPv2-MIB::systemsysUpTimesysName で次のように設定すると。

  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

indexeslookupstype には下記の 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
ngyuki
テック系男子。 ただのやってみた系の記事ははてなブログに、それ以外の技術系のネタは Qiita に投稿します。
https://ngyuki.jp/
headjapan
中規模~大規模の安定した基幹システム・大規模サイトの分析・要件定義・設計・開発を得意とする、総合的な開発会社です。
http://www.headjapan.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away