prometheusのnode_exporterの監視項目と設定例

# はじめに

監視ツール`prometheus`のハードウェア＆OS監視用のエージェントである`node_exporter`についてのエントリです。

`node_exporter`は`prometheus`向けにHWやOSに関連した様々な情報を取得して、`http`で公開してくれる監視エージェントです。
しかし、対応している監視項目（`prometheus`用語でコレクタと言います）が多いので、ユースケースに合わせて監視するコレクタを調整する必要があります。

本エントリでは`node_exporter`が対応しているコレクタとオプションについて整理したまとめになります。
また、コンテナで`node_exporter`を起動するケースとホスト側で直接起動するケースにおいて、サンプルの設定を乗っけています。

Linux向けのまとめです。`node_exporter`が対応している他OS（`FreeBSD`など）に関連する箇所は削っています。
また、マニアックな機能や、明らか使わない機能に関しては雑なメモ程度しか書いていません、あしからず。

## 使用ソフトウェアとバージョン

- `node_exporter`:`v0.14.0`

## デフォルト有効化されるコレクタ

### arp

`/proc/net/arp`からARPに関する統計と取ってきてくれるらしいです、が`v0.14.0`ではまだ取り込まれていません。
4/14時点でREADMEに載ってたんですが4/12でマスタブランチに取り込まれた機能っぽいので次のバージョンor手前でビルドすれば使えるかと思います。
有効化する事で、arpテーブルの現在のエントリ数を見ることができるっぽいです。

### conntrack

`/proc/sys/net/netfilter`からconntrackに関する統計を取って来てくれます。
conntrackとはネットワークのコネクションを追跡する機能で、iptablesなんかで使われます。
有効化する事で、conntrackの現在のエントリー数や、最大数なんかを見ることができます。

### diskstats

`/proc/diskstats`からdisk I/Oに関連する統計を取ってきてくれます。
有効化することで、各ディスクにおける現在進行中のI/O数などを見ることができます。


#### 関連するオプション

##### `-collector.diskstats.ignored-devices string`

無視するディスクを正規表現で指定します。
デフォルトは`"^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$"`

### edac

名前から察するに、ECCエラー周りの統計を出力してくれるコレクタっぽいです。
`/sys/devices/system/edac/mc/mc[0-9]*`から情報取ってきてくれるみたいですが、私の環境では、edacのパスが存在していませんでした。
監視すれば、メモリ故障の予兆とかわかりそうですが、深追いしては無いので詳細は不明です。

### entropy

乱数生成の元となるエントロピーの状態を取って来てくれます。
監視してれば、エントロピーが足りなくて/dev/randamがブロックされて死亡みたいな状況を未然に防げるかもしれません。

### filefd

`/proc/sys/fs/file-nr`からファイルディスクリプタの統計を取ってきてくれます。
有効すれば、現在割り当てられている数と、割当可能な最大値を取ってこれます。

### filesystem

filesystemに関連する統計を取ってきてくれます。
有効化すれば、各ファイルシステムの使用状況や空き状況なんかが見えます。

#### 関するオプション

##### `-collector.filesystem.ignored-fs-types string`

無視するファイルシステムのタイプを正規表現で指定します。
デフォルトは`"^(sys|proc|auto)fs$"`

##### `-collector.filesystem.ignored-mount-points string`

無視するファイルシステムのマウントポイントを正規表現で指定します。
デフォルトは`"^/(sys|proc|dev)($|/)"`

### hwmon

`/sys/class/hwmon`からhwのセンサデータを取ってきてくれます。
有効化すれば、cpuの温度とかが見えます。
個人的には別にいらないかな。

### infiniband

みんな大好き`infiniband`の情報を取ってきてくれます。
`infiniband`使ってないので、細かくは見てません。

### loadavg

みんな大好きロードアベレージを/proc/loadavgから取ってきてくれます。
いつもの、`1m`,`5m`,`15m`のやつが見れます。

### mdadm

`/proc/mdstat`からmd（ソフトウェアRAID）に関する情報を取ってきてくれます。
各mdデバイスに対して、そのデバイスは何枚ディスクを含んでいて、今いくつactiveなのか、とかが見れます。


### meminfo

`/proc/meminfo`からメモリに関する情報を取ってきてくれます。
有効化すれば、メモリやSwapの使用状況などが見れます。

### netdev

`/proc/net/dev`からネットワークインターフェースに関する情報を取ってきてくれます。
各インターフェースの送受信データのバイト数、パケット数、dropやerrorとなったパケット数なんかが見れます。

#### 関連するオプション

##### ` -collector.netdev.ignored-devices string`

無視するネットワークデバイスを正規表現で指定します。
デフォルトは`"^$"`で、つまり何も無視しません。

### netstat

`/proc/net/netstat`からTCP/UDP/ICMPなどプロトコル毎の統計情報を取ってきてくれます。
`netstat -s`と同じ情報が取れるようです。
TCPの再送数とかコネクション数なんかが見れます。

### sockstat

`/proc/net/sockstat`からソケットの統計情報を取ってきてくれます。
TCPのソケットの各種状態の個数（alloc/timewaitなど)とかが取れます。
`/proc/net/sockstat`は解説してる文章があんまり無く、どこまで信用できる値なのかは謎です。

### stat

`/proc/stat`から主にCPU周りなどの統計情報を取得することができます。
コア別のCPU使用量とかを見ることができます。

### textfile

指定したディレクトリ内にcronバッチなどでデータを格納することで、任意の情報を取得することができます。
格納するデータは以下のフォーマットに従った形式で出力する必要があります。
https://prometheus.io/docs/instrumenting/exposition_formats/

#### 関連するオプション

##### `-collector.textfile.directory string`

textfileコレクタでデータを読み込みに行く先のパスです。

### time

サーバーのUnixTimeを見ることができます。

### uname

unameに関する情報を取得することができます。
OSやホスト名、ドメイン名、カーネルバージョンなんかをラベルで見ることができます。

### vmstat

`/proc/vmstat`から仮想メモリに関する情報を取得することができます。
仮想メモリと言うとSwapと混同されやすいですが、ページングに関連する情報が見れます。
dirtyなページとかwrite_back中のページとか見れます。

### wifi

wifiデバイスの情報を取ってきてくれるそうです。
監視したいサーバはwifi使わないので割愛します。

### zfs

みんな大好き`zfs`の情報を取ってきてくれるそうです。
`zfs`使ってないので、割愛します。

## デフォルト無効化されてるコレクタ

マニアックな項目が増えてくるので、雑加減があがります。

### bonding

`/sys/class/net`から現在のbondインターフェースの情報が見れます。
何個スレーブがあって、何個アクティブかあるとか見れます。

### buddyinfo

`/proc/buddyinfo`から物理メモリの断片化状況が見えるらしいです。
ほー。

### drbd

みんな大好き`drbd`の情報を取ってきてくれるそうです。
`drbd`使ってないので、割愛します。

### interrupts

`/proc/interrupts`からIRQ毎の割り込み数なんかが見れるそうです。
へー。

### ipvs

`/proc/net/ip_vs`などからipvsの情報などの情報を取ってきてくれます。
振り分け元IP、振り分け先IP、に応じたウェイト数とか現在のコネクション数とかが見えます。

### ksmd

`/sys/kernel/mm/ksm`からKernel Samepage Merging (KSM)の情報を取れるそうです。
KSMとはプロセスのコピーオンライトの逆版で、複数のプロセス間でメモリーを比較し、同一である場合はマージしてサイズを減らす機能らしいです。
KVMとか使ってると効果を発揮するそうな。
ほーん。

### logind

systemdに付随するlogindという機能から現在のttyセッション数なんかが取れるそうです。
はー。

### meminfo_numa

numaに関するメモリ情報がみれるそうです。
numaはいずれ見たいケースがあるかもしれませんが、現時点でほとんど理解していない＆複数socketのマシンがほとんどいないので、深追いはしてません。

### mountstats

`/proc/self/mountstats`からnfs-clientに関連する情報を取ってきてくれます。
各マウント先に対して、各種オペレーション（writeとかreadとか）別に、何byte送ったとか何秒かかったとか、細かい情報を見ることができます。

### nfs

`/proc/net/rpc/nfs`からnfs-clientに関連する情報を取ってきてくれます。
`nfsstat -c`と同じ意味の値がとれるそうです。
`mountstats`と比較して、こちらの取れる情報はサマライズされたものになります。

### runit

`runit`の情報を取ってきてくれるそうです。
`runit`使ってないので、割愛します。

### supervisord

`supervisord`の情報を取ってきてくれるそうです。
`supervisord`使ってないので、割愛します。

### systemd

`systemd`の情報を取って来てくれます。
各Unitが現在、activeなのか、failedなのか、inactiveなのか、など、Unitの状態を見ることができます。

#### 関連するオプション

##### `-collector.systemd.private`

dbusを介さずsystemdと直接接続するオプションらしいですが、使い方がよく解ってません。
デフォルトはfalseです。

##### `-collector.systemd.unit-blacklist string`

監視するsystemdのユニット名のブラックリストの正規表現です。
デフォルトは何も入っていません。

##### `-collector.systemd.unit-whitelist string`

監視するsystemdのユニット名のホワイトリストの正規表現です。
デフォルトは".+"、つまり全て取得します。
監視対象はホワイトリストにマッチすることと、ブラックリストにマッチしないこと、の両方を満たす必要があります。

### tcpstat

`/proc/net/tcp`などからtcpに関連する情報を取ってきてくれるみたいです。
パフォーマンスに関する問題があるらしく、使用しないほうが良さそうです。

## オプション

個別のコレクタに関するオプションでは無く、`node_exporter`全体に関連するオプションで、`node_exporter`の取得に影響するものを抜粋してます。

### `-collector.procfs string`

`node_exporter`がprocの情報を取得しに行く先のパスです。
デフォルトは`/proc`です。
コンテナ内で動かす場合に、ホストの`/proc`をマウントした先を指定する用途で使います。

### `-collector.sysfs string`

`node_exporter`がsysの情報を取得しに行く先のパスです。
デフォルトは`/sys`です。
コンテナ内で動かす場合に、ホストの`/sys`をマウントした先を指定する用途で使います。

### `-collectors.enabled string`

カンマ区切りで有効化するコレクタを指定します。
デフォルトは`conntrack,diskstats,entropy,edac,filefd,filesystem,hwmon,infiniband,loadavg,mdadm,meminfo,netdev,netstat,sockstat,stat,textfile,time,uname,vmstat,wifi,zfs`つまり、デフォルト有効化されるコレクタたちです。

## `node_exporter`の起動サンプル

ユースケース次第なので、人によって当然必要なものは異なると思いますが、私の環境では以下を有効化しようと考えてます。

- conntrack
- diskstats
- entropy
- filefd
- filesystem
- loadavg
- mdadm
- meminfo
- netdev
- netstat
- sockstat
- stat
- textfile
- time
- uname
- vmstat
- bonding
- mountstats
- systemd

明らか見ない項目は有効化しない方針の元、上記をひとまず有効化して、様子見しつつ結局見ない項目があった場合、都度削ってく形にしようと考えてます。
以下は上記のコレクタを有効化した際のサンプルです。
`Container Linux`(`CoreOS`)上で動かすケースを考えています。

## コンテナで`node_exporter`を起動する場合

都合によりCompose File形式で記載します。

```yaml:node_exporter
version: '2'
services:
  prometheus:
    image: quay.io/prometheus/node-exporter
    ports:
      - "9100:9100"
    volumes:
      - /proc:/host/proc
      - /sys:/host/sys
      - /:/rootfs
      - text-collector:/text-collector
      - /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
    network_mode: "host"
    command:
      - -collectors.enabled
      - "conntrack,diskstats,entropy,filefd,filesystem,loadavg,mdadm,meminfo,netdev,netstat,sockstat,stat,textfile,time,uname,vmstat,bonding,mountstats,systemd"
      - -collector.systemd.unit-whitelist
      - "^(systemd-journald.service|etcd2.service)$$"
      - -collector.procfs
      - /host/proc
      - -collector.sysfs
      - /host/sys
      - -collector.filesystem.ignored-mount-points
      - "^/(sys|proc|dev|etc|host|var|text-collector|rootfs/(var/lib/docker|media|boot|proc|sys|dev|run|tmp)|$$)"
      - -collector.netdev.ignored-devices
      - "^(br|veth|docker)"
      - -collector.textfile.directory
      - /text-collector
volumes:
  text-collector:

```

Compose Fileでは`$`は`$$`でエスケープする必要があるので要注意です。
ごちゃついてますが、中身の説明です。

### ボリュームのマウントについて

- ホストの/procや/sys配下の情報を取得する必要があるのでマウント
- filesystemの監視が必要なので、ホストのルートを/rootfsとしてマウント
- text-collectorの領域を名前付きボリュームとしてマウント
  - これだけだと意味ないので、なんらか欲しい情報を出力するコンテナを追加することを想定してます
- systemdの情報を取得するのにsystemdのsocketをマウント

### オプションについて

#### `collector.systemd.unit-whitelist`

全Unitを監視しても見ないので、明示的にコレが動いて無いと困る、といったユニットのみ監視する方針です。
監視すべきUnitは真面目に精査できてないので、一旦、適当に入れてます。

#### `collector.filesystem.ignored-mount-points`

`filesystem`監視は物理ディスクの残容量などを見ることを目的として有効化しています。
コンテナで`node_exporter`を動かすと、コンテナ側のファイルシステムなどの不要な情報を取得していまうので、それらを除外しています。
また、ホストの情報は`/rootfs`配下にマウントしているので、そこ経由で見ることができるのですが、ホストがtmp領域をマウントしてる箇所など、不要な情報も含められているので、合わせて除外しています。

#### `collector.netdev.ignored-devices`

`netdev`監視もホストの物理的なネットワークデバイスを監視することを目的として有効化しています。
なので、仮想インターフェースなどを除外しています。
コンテナ側のネットワーク監視は別途、cAdvisorなどでやればいいかと。
（docker v1.13以降はdocker自体がprometheusの監視エンドポイントを持ってるらしいです）

## systemdで起動する場合

systemdで起動する場合も、基本的な方針は一緒です。
コンテナで起動しない分、少しすっきりします。

```bash:node_exporter.service
[Unit]
Description=node_exporter service
After=network.target

[Service]
Type=simple

Environment=COLLECTORS=conntrack,diskstats,entropy,filefd,filesystem,loadavg,mdadm,meminfo,netdev,netstat,sockstat,stat,textfile,time,uname,vmstat,bonding,mountstats,systemd
Environment=SYSTEMD_WHITELIST=^(docker.service|systemd-journald.service|etcd2.service)$
Environment=FILESYSTEM_IGNORED=^/(run|boot|media|tmp|sys|dev|proc|var/lib/docker)
Environment=NETDEV_IGNORED=^(br|veth|docker)
Environment=TEXT_DIR=/run/node_exporter/text-collector

ExecStartPre=-/usr/bin/mkdir -p ${TEXT_DIR}
ExecStart=/opt/bin/node_exporter -collectors.enabled ${COLLECTORS} \
  -collector.systemd.unit-whitelist ${SYSTEMD_WHITELIST} \
  -collector.filesystem.ignored-mount-points ${FILESYSTEM_IGNORED} \
  -collector.netdev.ignored-devices ${NETDEV_IGNORED} \
  -collector.textfile.directory ${TEXT_DIR}

Restart=always
RestartSec=10s
```

環境変数は別ファイルに纏めたほうがいいかもしれません。
コンテナで起動していないので、sysytemdの監視対象にdockerを含めています。

## おわりに

このエントリでは`node_exporter`の各種オプションをまとめて、`docker-compose`と`systemd`のサンプルを記載しました。
項目多くて、ぱっと見意味不明になりがちですが、一度設定決めたら、流用するだけなので運用乗った後は楽かなと思います。

値をたくさん取っても、ちゃんと可視化しないと意味がないので、気が向けば`Grapana`で可視化する際のクエリのパターンとかも整理してみたいです。