ネットワークメトリクスを視覚化してみた（collectd + Graphite + Grafana）

ルータのトラフィックなど、ネットワーク機器の**メトリクス**を収集・蓄積・描画して視覚化してみました。使用したツールは下記のとおりです。

- 収集：[collectd](https://collectd.org/)  - SNMPでルータからメトリクスを収集する
- 蓄積：[Graphite](http://graphite.readthedocs.io/en/latest/#) - 収集したメトリクスを保存する
- 描画：[Grafana](http://grafana.org/) - メトリクスを時系列で表示する

今回は、上記のツールを利用して、ルータのトラフィックを視覚化してみました。下記のようなグラフを描くことができます。
![Grafanaで描画.png](https://qiita-image-store.s3.amazonaws.com/0/12026/388822ae-5e36-2ce6-ef56-442237e847ab.png)
図. Grafana実行画面



はじめに
============================================================
今回はSNMPで取得できるネットワークメトリクス（トラフィックやパケット数など）をGraphite + Grafanaで視覚化してみました。SNMPの取得にはGraphiteに対応したcollectdを利用しました。

[NetOpsCoding#3](https://atnd.org/events/78025)で、日本マイクロソフトの北島さんの発表「[Monitoring Intelligence](http://www.slideshare.net/netopscoding/monitoring-intelligence)」でネットワークメトリクスのデモを見て、導入したいと思いこの記事を書きました。デモでは、オープンソースのGraphite + Grafanaを使ってコアネットワークの監視や状態確認の事例が紹介され、非常に使い勝手が良さそうだと感じました。

拙著の[GrafanaとInfluxDBでネットワークリソースの視覚化](http://qiita.com/kooshin/items/a770c6df33fe2ffb2d0b)で、Grafanaを利用していました。実際に利用してみて、ネットワークメトリクスの視覚化は、InfluxDBよりGraphiteが楽でした。InfluxDBとGraphiteを比較すると、Graphiteはシンプルなため、理解しやすいと思います。ただ、InfluxDBはSQLライクな言語でデータベースの操作ができるため、GraphiteよりInfluxDBの方がデータの柔軟性は高いと思います。また、GraphiteとGrafanaの親和性が高く、簡単に複数のルータやインタフェースを比較するグラフを作成できます。


仕組み
----------------------------------------
collectd + Graphite + Grafanaの組み合わせると下図の通りとなります。

- [collectd](https://collectd.org/) - メトリクス収集：SNMPでメトリクスを収集します
- [Graphite](http://graphite.readthedocs.io/en/latest/#) - メトリクス蓄積：メトリクスを蓄積します。
- [Grafana](http://grafana.org/) - メトリクス描画：Webブラウザでグラフを表示します。

![20160709_collectd+graphite+grafana.002.png](https://qiita-image-store.s3.amazonaws.com/0/12026/aac505ec-eb2f-eb60-da45-00ba6da499ac.png)
図. collectd + Graphite + Grafana連携の仕組み


メトリクス収集 - collectd
----------------------------------------
[collectd](https://collectd.org/)は、システムのパフォーマンスなどのメトリクスを定期的に収集するツールです。昔からあるツールで様々なプラグインがあり、入力と出力をcollectdが仲介します。今回は下記のプラグインを使います。

- snmp入力プラグイン
SNMPでネットワーク機器からメトリクスを収集するプラグイン

- write_graphite出力プラグイン
収集したデータをGraphiteに保存するプラグイン



メトリクス蓄積 - Graphite
----------------------------------------
[Graphite](http://graphite.readthedocs.io/en/latest/#)は、下記の2つの機能（蓄積と描画）があります。データの収集の機能はありません。

- 時系列の数値データを保存する機能
- ダイナミックにグラフ描画する機能

2006年から開発されているツールです。グラフ描画機能はGrafanaの方が優れいているため、Graphiteのグラフ描画機能は使いません。Graphiteは下記の3つのコンポーネントで成り立っています。

- carbon：ネットワーク経由でデータを受信するコンポーネント
PythonのライブラリTwistedを使ったイベントドリブン型のネットワークエンジン

- whisper：データを保存するコンポーネント
PythonのライブラリWhisperを使った時系列データに特化したデータベース。RRDと似ている。

- graphite webapp：グラフを描画するWebアプリ
PythonのWebフレームワークDjangoとグラフィックライブラリCairoを利用した管理アプリ


一番の特徴は、データの保存がライブラリなど必要でなく、TCPでデータを送信するだけで、データを保存できます。プログラミングの知識がなくても、下記のようにnetcatコマンドで、データを保存できます。

>
```
PORT=2003
SERVER=graphite.your.org
echo "local.random.diceroll 4 `date +%s`" | nc -c ${SERVER} ${PORT}
```
引用元：[Graphite - Feeding In Your Data - The plaintext protocol](http://graphite.readthedocs.io/en/latest/feeding-carbon.html#the-plaintext-protocol)



メトリクス描画 - Grafana
----------------------------------------
[Grafana](http://grafana.org/)は、下記の機能があります。かなり、かっこよくて、綺麗なダッシュボードやグラフをWeb画面から構築できます。

- ダッシュボードを作成・表示する機能
- 時系列のグラフを描画する機能

グラフ機能が優れており、様々な演算処理を組み合わせることで、下記のようなグラフを描画できます。

- データを積み重ねて、複数インタフェースのトラフィック総量を表示するスタック機能
- トラフィックの多いインタフェースの内、トップ10のみ表示する機能
- 1週間前や1ヶ月前など、過去のグラフと比較して描画する機能



インストール
============================================================
collectd + Graphite + Grafanaのインストール方法について説明します。今回はVirtualBox上に構築したLinuxのUbuntuにすべてのツールをインストールします。インストールにあたって、下記のサイトを参考にしています。

- [素のサーバーに Sensu + Graphite + Grafana を導入して Dashboard を作るまでのメモ](http://qiita.com/nobuhito/items/9c6e0ed67a5fbb7d27e9)
- [How To Install and Use Graphite on an Ubuntu 14.04 Server](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-graphite-on-an-ubuntu-14-04-server)



インストール環境
----------------------------------------
インストールしたソフトウェアのパッケージ名とバージョンは下記のとおりです。基本的にUbuntu16.04のパッケージからインストールします。Grafanaのみ、最新版を利用するため、Stableパッケージをダウンロードしてインストールします。その他はUbuntu16.04の標準パッケージが最新版でした。

- 基本
 - Linuxディストリビューション：Ubuntu 16.04 LTS
 - カーネル4.4.0-28-generic x86_64
- 収集 - collectd 標準パッケージ
 - collectd 5.5.1-1build2
- 蓄積 - Graphite 標準パッケージ
 - graphite-carbon 0.9.15-1
 - graphite-web 0.9.15+debian-1
 - python-whisper 0.9.15-1
 - apache 2.4.18-2ubuntu
 - libapache2-mod-wsgi 4.3.0-1.1build1
- 描画 - Grafana 個別パッケージ
 - grafana 3.0.4

インストールは、蓄積=>収集=>描画の順で実施します。

0. Ubuntuのインストール
0. Graphiteのインストール
0. collectdのインストール
0. Grafanaのインストール



Ubuntuのインストール
----------------------------------------
今回はUbuntu 16.04のサーバ版```ubuntu-16.04-server-amd64.iso```をインストールします。Ubuntuのインストール手順は省略します。
この記事では、``$``記号はBashシェルのプロンプトを示し、``#``はコメントを示します。

Ubuntu16.04のインストール後、パッケージを最新版にアップグレードし、再起動します。

```bash
# 1. APTリポジトリをアップデート
$ sudo apt update

# 2. インストール済みのパッケージをアップグレード
$ sudo apt upgrade

# 3. 再起動
$ sudo shutdown -r now
```

Graphiteのインストール
----------------------------------------
GraphiteをUbuntu 16.04の標準パッケージでインストールします。インストールするパッケージは次のとおりです。

- graphite-carbon：データ蓄積パッケージ
- graphite-web：グラフ描画パッケージ
    - apache2
    - libapache2-mod-wsgi

変更する設定ファイルは次のとおりです。

- graphite-carbonの設定ファイル
    - /etc/default/graphite-carbon：自動起動設定
    - /etc/carbon/carbon.conf：データベースの設定
    - /etc/carbon/storage-schemas.conf：データベースのポリシー定義
- graphite-webの設定ファイル
    - /etc/graphite/local_settings.py：GraphiteWebアプリの設定
    - /etc/apache2/sites-available/apache2-graphite.conf：Apache用の設定ファイル
        - 元ファイル：/usr/share/graphite-web/apache2-graphite.conf

必要なパッケージをAPTでインストールします。

```bash
$ sudo apt install graphite-carbon graphite-web graphite-web apache2 libapache2-mod-wsgi
```

graphite-carbonのインストール途中に下記の入力画面が表示された場合は、Noを選択してください。graphite-carbonをアンインストール（parge）した場合、データベースも一緒に消すかという質問です。今回は消さないため、Noを選択します。

```
    ┌────────────────────────────────────────┤ Configuring graphite-carbon ├─────────────────────────────────────────┐     
    │                                                                                                                │     
    │ The /var/lib/graphite/whisper directory contains the whisper database files.                                   │     
    │                                                                                                                │     
    │ You may want to keep these database files even if you completely remove graphite-carbon, in case you plan to   │     
    │ reinstall it later.                                                                                            │     
    │                                                                                                                │     
    │ Remove database files when purging graphite-carbon?                                                            │     
    │                                                                                                                │     
    │                                 <Yes>                                    **<No>**                              │     
    │                                                                                                                │     
    └────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘     
```


### graphite-carbonの設定

graphite-carbonの起動設定ファイルを変更します。設定ファイルは``/etc/default/graphite-carbon``です。

```bash
$ sudo mv /etc/default/graphite-carbon /etc/default/graphite-carbon.orig
$ cat << EOF | sudo tee /etc/default/graphite-carbon
CARBON_CACHE_ENABLED=true
EOF
```

graphite-carbonの設定ファイルを変更します。設定ファイルは``/etc/carbon/carbon.conf``です。設定の詳細は[Graphiteのドキュメント](http://graphite.readthedocs.io/en/latest/config-carbon.html#carbon-conf)を参照してください。修正箇所は次の1箇所です。

- ログローテーションの有効化：ENABLE_LOGROTATION = True

```bash
# 設定ファイルのバックアップ
$ sudo mv /etc/carbon/carbon.conf /etc/carbon/carbon.conf.orig
# 設定変更
$ cat << EOF | sudo tee /etc/carbon/carbon.conf
[cache]
STORAGE_DIR    = /var/lib/graphite/
LOCAL_DATA_DIR = /var/lib/graphite/whisper/
CONF_DIR       = /etc/carbon/
LOG_DIR        = /var/log/carbon/
PID_DIR        = /var/run/
ENABLE_LOGROTATION = True
USER = _graphite
MAX_CACHE_SIZE = inf
MAX_UPDATES_PER_SECOND = 500
MAX_CREATES_PER_MINUTE = 50
LINE_RECEIVER_INTERFACE = 0.0.0.0
LINE_RECEIVER_PORT = 2003
ENABLE_UDP_LISTENER = False
UDP_RECEIVER_INTERFACE = 0.0.0.0
UDP_RECEIVER_PORT = 2003
PICKLE_RECEIVER_INTERFACE = 0.0.0.0
PICKLE_RECEIVER_PORT = 2004
LOG_LISTENER_CONNECTIONS = True
USE_INSECURE_UNPICKLER = False
CACHE_QUERY_INTERFACE = 0.0.0.0
CACHE_QUERY_PORT = 7002
USE_FLOW_CONTROL = True
LOG_UPDATES = False
LOG_CACHE_HITS = False
LOG_CACHE_QUEUE_SORTS = True
CACHE_WRITE_STRATEGY = sorted
WHISPER_AUTOFLUSH = False
WHISPER_FALLOCATE_CREATE = True

[relay]
LINE_RECEIVER_INTERFACE = 0.0.0.0
LINE_RECEIVER_PORT = 2013
PICKLE_RECEIVER_INTERFACE = 0.0.0.0
PICKLE_RECEIVER_PORT = 2014
LOG_LISTENER_CONNECTIONS = True
RELAY_METHOD = rules
REPLICATION_FACTOR = 1
DESTINATIONS = 127.0.0.1:2004
MAX_DATAPOINTS_PER_MESSAGE = 500
MAX_QUEUE_SIZE = 10000
QUEUE_LOW_WATERMARK_PCT = 0.8
USE_FLOW_CONTROL = True

[aggregator]
LINE_RECEIVER_INTERFACE = 0.0.0.0
LINE_RECEIVER_PORT = 2023
PICKLE_RECEIVER_INTERFACE = 0.0.0.0
PICKLE_RECEIVER_PORT = 2024
LOG_LISTENER_CONNECTIONS = True
FORWARD_ALL = False
DESTINATIONS = 127.0.0.1:2004
REPLICATION_FACTOR = 1
MAX_QUEUE_SIZE = 10000
USE_FLOW_CONTROL = True
MAX_DATAPOINTS_PER_MESSAGE = 500
MAX_AGGREGATION_INTERVALS = 5
EOF
```

graphite-carbonのデータ保存ポリシーを変更します。設定ファイルは``/etc/carbon/storage-schemas.conf``です。設定の詳細は[Graphiteのドキュメント](http://graphite.readthedocs.io/en/latest/config-carbon.html#storage-schemas-conf)を参照してください。データの保存頻度と保存期間を定義します。1つのデータについて複数のポリシーを定義でき、直近90日は30秒間隔で保持し、1年間は300秒間隔の平均値で保存できます。複数ポリシーを定義することで、データ保存の総量を減らしたり、グラフの描画速度を早くできます。今回は下記を定義します。

- carbonポリシー
    - 「carbon.」から始まるパターンに適用
    - 60秒間隔で90日保存
- collectdポリシー
    - 「collectd.」から始まるパターンに適用
    - 30秒間隔で90日保存
    - 300秒間隔で365日保存
- デフォルトポリシー
    - 上記のパターンに一致しない場合に適用
    - 60秒間隔で1日保存

```bash
# 設定ファイルのバックアップ
$ sudo mv /etc/carbon/storage-schemas.conf /etc/carbon/storage-schemas.conf.orig
# 設定変更
$ cat << EOF | sudo tee /etc/carbon/storage-schemas.conf
[carbon]
pattern = ^carbon\.
retentions = 60:90d

[collectd]
pattern = ^collectd\.
retentions = 30:90d,300:365d

[default_1min_for_1day]
pattern = .*
retentions = 60s:1d
EOF
```

設定変更が完了したのでgraphite-carbonデーモンを再起動します。

```bash
# プロセスを再起動（graphite-carbon）
$ sudo systemctl restart carbon-cache.service

# エラーがないか確認
$ sudo systemctl status carbon-cache.service
```

systemctl statusコマンドでは、graphite-carbonが問題なく稼働している場合は、下記のメッセージが表示されます。

```bash
kooshin@xenial2:~$ sudo systemctl status carbon-cache.service 
● carbon-cache.service - Graphite Carbon Cache
   Loaded: loaded (/lib/systemd/system/carbon-cache.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2016-07-07 22:00:06 JST; 1s ago
  Process: 15077 ExecStart=/usr/bin/carbon-cache --config=/etc/carbon/carbon.conf --pidfile=/var/run/c
 Main PID: 15086 (carbon-cache)
    Tasks: 2
   Memory: 18.1M
      CPU: 226ms
   CGroup: /system.slice/carbon-cache.service
           └─15086 /usr/bin/python /usr/bin/carbon-cache --config=/etc/carbon/carbon.conf --pidfile=/v

Jul 07 22:00:06 xenial2 systemd[1]: Stopped Graphite Carbon Cache.
Jul 07 22:00:06 xenial2 systemd[1]: Starting Graphite Carbon Cache...
Jul 07 22:00:06 xenial2 systemd[1]: Started Graphite Carbon Cache.
```


### graphite-webの設定

graphite-webの設定ファイル``/etc/graphite/local_settings.py``を修正します。設定の詳細は[Graphiteのドキュメント](http://graphite.readthedocs.io/en/latest/config-local-settings.html)を参照してください。修正箇所は次の2箇所です。

- タイムゾーンを日本時間に変更
TIME_ZONE = 'Asia/Tokyo'

- WebフレームワークDjangoのシークレットキーの修正
ランダムな値に変更します。
SECRET_KEY = 'RANDAMU NA MOJIRETU WO SETTEI SIMASU'

```bash
# 設定ファイルのバックアップ
$ sudo cp /etc/graphite/local_settings.py /etc/graphite/local_settings.py.orig
# 設定ファイルを修正
$ cat << EOF | sudo tee /etc/graphite/local_settings.py
TIME_ZONE = 'Asia/Tokyo'
SECRET_KEY = 'RANDAMU NA MOJIRETU WO SETTEI SIMASU'
LOG_RENDERING_PERFORMANCE = True
LOG_CACHE_PERFORMANCE = True
LOG_METRIC_ACCESS = True
GRAPHITE_ROOT = '/usr/share/graphite-web'
CONF_DIR = '/etc/graphite'
STORAGE_DIR = '/var/lib/graphite/whisper'
CONTENT_DIR = '/usr/share/graphite-web/static'
WHISPER_DIR = '/var/lib/graphite/whisper'
LOG_DIR = '/var/log/graphite'
INDEX_FILE = '/var/lib/graphite/search_index'  # Search index file
DATABASES = {
    'default': {
        'NAME': '/var/lib/graphite/graphite.db',
        'ENGINE': 'django.db.backends.sqlite3',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': ''
    }
}
EOF
```

local_settings.pyを修正した場合、Webアプリのデータベースを同期します。同期は``graphite-manage syncdb``で実行します。初回実行時には管理用のスーパーユーザが未定義のため、併せてスーパーユーザを作成します。必ずスーパーユーザを作成してください。ここでは、adminをいう名前でスーパーユーザを作成します。

```bash
# Webアプリ用のデータベースを同期
$ sudo -u _graphite -g _graphite graphite-manage syncdb
# スーパーユーザの作成
You have installed Django's auth system, and don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use '_graphite'): admin ★アカウント名
Email address: ★メールアドレス
Password: ★パスワード
Password (again): ★パスワード
Superuser created successfully.
```

Apacheの設定をします。設定は変更せずに元ファイル/usr/share/graphite-web/apache2-graphite.confをそのまま利用します。

```bash
# デフォルトの000-defaultを無効化
$ sudo a2dissite 000-default
# 設定変更
$ cat << EOF | sudo tee /etc/apache2/sites-available/apache2-graphite.conf
<VirtualHost *:80>

        WSGIDaemonProcess _graphite processes=5 threads=5 display-name='%{GROUP}' inactivity-timeout=120 user=_graphite group=_graphite
        WSGIProcessGroup _graphite
        WSGIImportScript /usr/share/graphite-web/graphite.wsgi process-group=_graphite application-group=%{GLOBAL}
        WSGIScriptAlias / /usr/share/graphite-web/graphite.wsgi

        Alias /content/ /usr/share/graphite-web/static/
        <Location "/content/">
                SetHandler None
        </Location>

        ErrorLog ${APACHE_LOG_DIR}/graphite-web_error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/graphite-web_access.log combined

</VirtualHost>
EOF
# apache2-graphiteを有効化
$ sudo a2ensite apache2-graphite
```

設定変更が完了したのでapache2を再起動します。

```bash
# プロセスを再起動（apache2）
$ sudo systemctl restart apache2.service

# エラーがないか確認
$ sudo systemctl status apache2.service
```
systemctl statusコマンドで、apache2が問題なく稼働している場合は、下記のメッセージが表示されます。


```bash
kooshin@xenial2:~$ sudo systemctl status apache2.service
● apache2.service - LSB: Apache2 web server
   Loaded: loaded (/etc/init.d/apache2; bad; vendor preset: enabled)
  Drop-In: /lib/systemd/system/apache2.service.d
           └─apache2-systemd.conf
   Active: active (running) since Thu 2016-07-07 22:25:02 JST; 1 day 9h ago
     Docs: man:systemd-sysv-generator(8)
  Process: 25758 ExecReload=/etc/init.d/apache2 reload (code=exited, status=0/SUCCESS)
    Tasks: 95
   Memory: 133.9M
      CPU: 2min 29.577s
   CGroup: /system.slice/apache2.service
           ├─18802 /usr/sbin/apache2 -k start
           ├─25831 (wsgi:_graphite)  -k start
           ├─25832 (wsgi:_graphite)  -k start
           ├─25833 (wsgi:_graphite)  -k start
           ├─25834 (wsgi:_graphite)  -k start
           ├─25835 (wsgi:_graphite)  -k start
           ├─25836 /usr/sbin/apache2 -k start
           └─25837 /usr/sbin/apache2 -k start

Jul 07 22:25:01 xenial2 systemd[1]: Stopped LSB: Apache2 web server.
Jul 07 22:25:01 xenial2 systemd[1]: Starting LSB: Apache2 web server...
Jul 07 22:25:01 xenial2 apache2[18786]:  * Starting Apache httpd web server apache2
Jul 07 22:25:01 xenial2 apache2[18786]: AH00558: apache2: Could not reliably determine the serv...sage
Jul 07 22:25:02 xenial2 apache2[18786]:  *
Jul 07 22:25:02 xenial2 systemd[1]: Started LSB: Apache2 web server.
Jul 09 06:25:01 xenial2 systemd[1]: Reloading LSB: Apache2 web server.
Jul 09 06:25:01 xenial2 apache2[25758]:  * Reloading Apache httpd web server apache2
Jul 09 06:25:01 xenial2 apache2[25758]:  *
Jul 09 06:25:01 xenial2 systemd[1]: Reloaded LSB: Apache2 web server.
Hint: Some lines were ellipsized, use -l to show in full.
```

### Graphiteの動作確認
Graphiteの動作確認をします。Webブラウザから次のURLを指定して、Graphiteのトップ画面が表示されるか確認します。

```
http://インストール先ホストのIPアドレス/
同じマシンで実行している場合のURL
http://localhost/
別のマシン192.168.88.18で実行している場合のURL
http://192.168.88.18
```

![Graphite画面.png](https://qiita-image-store.s3.amazonaws.com/0/12026/03c44558-8c8c-dbaa-03e0-b79a79960714.png)
図. Graphiteのトップ画面


collectdのインストール
----------------------------------------
collectdをUbuntu 16.04の標準パッケージでインストールします。インストールするパッケージは次のとおりです。
collectdのsnmpプラグインを使う場合、SNMPのMIBが必要のため、``snmp``と``snmp-mibs-downloader``を併せてインストールします。

- snmp：SNMPパッケージ
    - snmp-mibs-downloader
- collectd：データ収集パッケージ

設定ファイルは次のとおりです

- snmpの設定ファイル
    - /etc/snmp/snmp.conf
- collectdの設定ファイル
    - /etc/collectd/collectd.conf

必要なパッケージをAPTでインストールします。SNMPのMIBもダウンロードされます。

```bash
$ sudo apt install collectd snmp snmp-mibs-downloader
```

### SNMPの設定
SNMPのMIBはライセンスの問題から、標準ではインストールされません。そのため、snmp-mibs-downloaderでMIBファイルをダウンロードします。また、snmpのデフォルトの設定ではMIBファイルの読み込みが無効されています。MIBファイルの読み込みを有効化するため、下記のsって居変更を実施します。

```bash
# SNMPの設定ファイルをバックアップ
$ sudo cp /etc/snmp/snmp.conf /etc/snmp/snmp.conf.orig

# MIBファイルを読み込むよう変更
#   mibs行をコメントアウト
$ cat << EOF | sudo tee /etc/snmp/snmp.conf
# As the snmp packages come without MIB files due to license reasons, loading
# of MIBs is disabled by default. If you added the MIBs you can reenable
# loading them by commenting out the following line.
#mibs :
EOF
```

### collectdの収集設定
SNMPの収集対象を設定します。今回は下記の通りSNMPの収集対象を設定します。設定の詳細は次のドキュメントを参照してください。

- (collectd-snmp(5))[https://collectd.org/documentation/manpages/collectd-snmp.5.shtml]

- SNMP収集対象
 - ifmib_if_octets64: ifHCInOctets, ifHCOutOctets（IN/OUTのバイト数）
 - ifmib_if_ucastpkts64: ifHCInUcastPkts, ifHCOutUcastPkts（IN/OUTのユニキャストパケット数）
- SNMP収集ホスト
 - ホスト名：c1812j
 - IPアドレス：192.168.88.101
 - SNMPバージョン：2
 - SNMPコミュニティ：public
 - 収集間隔：30秒

```bash
# 設定ファイルのバックアップ
$ sudo cp /etc/collectd/collectd.conf /etc/collectd/collectd.conf.orig
# 設定を変更
$ cat << EOF | sudo tee /etc/collectd/collectd.conf
LoadPlugin snmp
LoadPlugin write_graphite

<Plugin snmp>
  <Data "ifmib_if_octets64">
    Type "if_octets"
    Table true
    Instance "IF-MIB::ifName"
    Values "IF-MIB::ifHCInOctets" "IF-MIB::ifHCOutOctets"
  </Data>
  <Data "ifmib_if_ucastpkts64">
    Type "if_packets"
    Table true
    Instance "IF-MIB::ifName"
    Values "IF-MIB::ifHCInUcastPkts" "IF-MIB::ifHCOutUcastPkts"
  </Data>

  <Host "c1812j">
    Address "192.168.88.101"
    Version 2
    Community "public"
    Collect "ifmib_if_octets64" "ifmib_if_ucastpkts64"
    Interval 30
  </Host>
</Plugin>

<Plugin write_graphite>
  <Carbon>
    Host "localhost"
    Port "2003"
    Prefix "collectd."
    Postfix ""
    StoreRates true
    AlwaysAppendDS true
    EscapeCharacter "_" 
  </Carbon>
</Plugin>
EOF
```

設定変更をcollectdデーモンに反映させるため、デーモンを再起動します。

```bash
# collectdデーモンの再起動
$ sudo systemctl restart collectd.service

# collectdデーモンの起動ログ確認
$ sudo systemctl status collectd.service
```

再起動後、下記の通りエラーがなければ問題ありません。

```bash
kooshin@xenial2:~$ sudo systemctl status --no-pager collectd.service
● collectd.service - Statistics collection and monitoring daemon
   Loaded: loaded (/lib/systemd/system/collectd.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2016-07-09 09:25:34 JST; 9s ago
     Docs: man:collectd(1)
           man:collectd.conf(5)
           https://collectd.org
  Process: 15569 ExecStartPre=/usr/sbin/collectd -t (code=exited, status=0/SUCCESS)
 Main PID: 15572 (collectd)
    Tasks: 11
   Memory: 1.5M
      CPU: 81ms
   CGroup: /system.slice/collectd.service
           └─15572 /usr/sbin/collectd

Jul 09 09:25:34 xenial2 systemd[1]: Stopping Statistics collection and monitoring daemon...
Jul 09 09:25:34 xenial2 systemd[1]: Stopped Statistics collection and monitoring daemon.
Jul 09 09:25:34 xenial2 systemd[1]: Starting Statistics collection and monitoring daemon...
Jul 09 09:25:34 xenial2 collectd[15572]: supervised by systemd, will signal readyness
Jul 09 09:25:34 xenial2 systemd[1]: Started Statistics collection and monitoring daemon.
Jul 09 09:25:34 xenial2 collectd[15572]: Initialization complete, entering read-loop.
```

設定ファイルが間違っている場合、下記の通りエラーメッセージが表示されます。

```bash
Jul 09 09:28:52 xenial2 collectd[16205]: snmp plugin: DataSet `if_octet' not defined.
```


### collectdの動作確認
collectdでメトリクスが収集され、Graphiteに蓄積されているか、動作確認をします。Graphiteで下記の項目と表示されていればOKです。ルータのホスト名にif_octetsとif_packetsが定義され、グラフが描かれていればcollectdが正しく動作しているか確認できます。

```
Tree > Metrics > collectd > c1812j > snmp > if_octets-[インタフェース名]
Tree > Metrics > collectd > c1812j > snmp > if_packets-[インタフェース名]
```

![Graphite+collectd.png](https://qiita-image-store.s3.amazonaws.com/0/12026/0e675247-481a-cd96-2c61-e23f830fe0d7.png)
図. c1812jルータのトラフィックをGraphiteで表示した画面

Grafanaのインストール
----------------------------------------
Grafanaの[Installing on Debian / Ubuntu](http://docs.grafana.org/installation/debian/)の手順通りにインストールします。今回はUbuntuの標準パッケージではなく、debファイルを直接ダウンロードし、インストールします。

```bash
$ wget https://grafanarel.s3.amazonaws.com/builds/grafana_3.0.4-1464167696_amd64.deb
$ sudo dpkg -i grafana_3.0.4-1464167696_amd64.deb
$ sudo systemctl daemon-reload
$ sudo systemctl enable grafana-server.service
```

Grafanaは設定変更をしなくても使用できます。今回は設定変更せず、利用します。自動起動するよう設定し、デーモンを開始します。

```bash
# デーモンの起動
$ sudo systemctl start grafana-server.service
# 状態表示
$ sudo systemctl status grafana-server.service
```

systemctl statusコマンドの実行結果で、下記の通りエラーがなければOKです。

```bash
kooshin@xenial2:/etc/grafana$ sudo systemctl status --no-pager grafana-server.service 
● grafana-server.service - Starts and stops a single grafana instance on this system
   Loaded: loaded (/usr/lib/systemd/system/grafana-server.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2016-07-07 22:46:45 JST; 1 day 10h ago
     Docs: http://docs.grafana.org
 Main PID: 22426 (grafana-server)
    Tasks: 7
   Memory: 10.6M
      CPU: 11.373s
   CGroup: /system.slice/grafana-server.service
           └─22426 /usr/sbin/grafana-server --config=/etc/grafana/grafana.ini --pidfile= cfg:default.paths.logs=/var/log/grafana cfg:defau...

Jul 07 22:46:45 xenial2 grafana-server[22426]: 2016/07/07 22:46:45 [I] Migrator: exec migration id: create playlist item table v2
Jul 07 22:46:45 xenial2 grafana-server[22426]: 2016/07/07 22:46:45 [I] Migrator: exec migration id: drop preferences table v2
Jul 07 22:46:45 xenial2 grafana-server[22426]: 2016/07/07 22:46:45 [I] Migrator: exec migration id: drop preferences table v3
Jul 07 22:46:45 xenial2 grafana-server[22426]: 2016/07/07 22:46:45 [I] Migrator: exec migration id: create preferences table v3
Jul 07 22:46:46 xenial2 grafana-server[22426]: 2016/07/07 22:46:46 [I] Created default admin user: admin
Jul 07 22:46:46 xenial2 grafana-server[22426]: 2016/07/07 22:46:46 [I] Plugins: Scan starting
Jul 07 22:46:46 xenial2 grafana-server[22426]: 2016/07/07 22:46:46 [W] Plugins: Plugin dir /var/lib/grafana/plugins does not exist
Jul 07 22:46:46 xenial2 grafana-server[22426]: 2016/07/07 22:46:46 [I] Plugins: Plugin dir /var/lib/grafana/plugins created
Jul 07 22:46:46 xenial2 grafana-server[22426]: 2016/07/07 22:46:46 [I] Listen: http://0.0.0.0:3000
Jul 07 22:47:17 xenial2 grafana-server[22426]: 2016/07/07 22:47:17 [I] Completed 192.168.88.40 - "GET / HTTP/1.1" 302 Found 29 bytes in 627us
Hint: Some lines were ellipsized, use -l to show in full.
```

### Grafanaの動作確認
WebブラウザからGrafanaのトップ画面が表示できればOKです。標準ではTCPの3000ポートで待ち受けしています。

```
http://インストール先ホストのIPアドレス:3000/
同じマシンで実行している場合のURL
http://localhost:3000/
別のマシン192.168.88.18で実行している場合のURL
http://192.168.88.18:3000/
```

![Grafanaのトップ画面.png](https://qiita-image-store.s3.amazonaws.com/0/12026/54650e74-a489-fffc-297f-d50e2c0bde2a.png)
図. Grafanaのトップ画面（ログイン画面）


### Grafanaの設定
ルータのトラフィックのグラフを作成します。collectdで収集したc1812jルータのトラフィックをGraphiteから読み出して、トラフィックのグラフを作成します。詳細は下記のGrafanaのドキュメントを参照してください。

- [Getting started](http://docs.grafana.org/guides/gettingstarted/)
- [Data Sources - Graphite](http://docs.grafana.org/datasources/graphite/)
- [Reference - Dashlist Panel](http://docs.grafana.org/reference/dashlist/)
- [Reference - Graph Panel](http://docs.grafana.org/reference/graph/)
- [Reference - Singlestat Panel](http://docs.grafana.org/reference/singlestat/)
- [Reference - Table Panel](http://docs.grafana.org/reference/table_panel/)

#### ログイン
トップ画面（ログイン画面）で、下記のユーザ名とパスワードでログインします。

- User: admin
- Password: admin

#### データソースの設定
Graphiteに保存したデータを使うよう、データソースを設定します。

ログイン後、左上部のGrafanaアイコンからメニューから、データソース設定画面を表示します。

![範囲を選択_056.png](https://qiita-image-store.s3.amazonaws.com/0/12026/a756187d-25ee-47b1-67ce-302c640d85c3.png)
図. Grafanaアイコン

```
Grafanaアイコン > Data Sources
「+Add data source」ボタン
```

データソースを下記のとおり設定します。Graphiteはプロキシでローカルホストに接続します。

```
Config
  Name：Graphite
  Default：チェック
  Type：Graphite

Http settings
  Url：http://localhost
  Access：Proxy

Addボタン
```

データソースが正しく動作しているか、Save&Testボタンで確認します。テスト接続後、Data source is workingと表示されればOKです。

```
Save＆Testボタン

Success
Data source is working
```

#### グラフの作成

```
Grafanaアイコン => Dashboards => +New
左の緑のアイコン => Add Panel => Graph
```

グラフは下記のとおり設定しています。General、Metrics、Axes、Legend、Displayタブで設定します。

Generalタブで、グラフの名前やサイズを指定します。

![Grafana - c1812j - Google Chrome_047.png](https://qiita-image-store.s3.amazonaws.com/0/12026/788feaf5-e6ca-06ec-7acd-19a0b6845009.png)
図. Graph - Generalタブ

Metricsタブで、グラフで描画するデータを設定します。今回はインタフェースFa0, Fa1, Fa2のトラフィックを描画します。Graphiteのメトリクスは次のとおりです

```
collectd.c1812j.snmp.if_octets-Fa0.*
collectd.c1812j.snmp.if_octets-Fa1.*
collectd.c1812j.snmp.if_octets-Fa2.*
```
末尾で*を指定することで、rxとtx両方が表示対象になります。また、Graphiteに保存されたデータはバイト数（オクテット数）のため、ビットに変換するため、scale関数で8倍します。


![Grafana - c1812j - Google Chrome_046.png](https://qiita-image-store.s3.amazonaws.com/0/12026/24f37094-e567-9b2f-4a80-7a435d045569.png)
図. Graph - Metricsタブ


Axesタブで、X軸とY軸を設定します。Left YのUnit（単位）をbits/secを選択し、Right Yは不要のため、showのチェックを外します。

![Grafana - c1812j - Google Chrome_049.png](https://qiita-image-store.s3.amazonaws.com/0/12026/f41a4bbb-c79f-e23a-d16a-67d8d6ea5934.png)
図. Graph - Axesタブ


Legendタブで、グラフの凡例を設定します。テーブル形式でメトリクスを表示し、最小値（Min）、最大値（Max）、平均値（Avg）、現在値（Current）を表示します。

![Grafana - c1812j - Google Chrome_050.png](https://qiita-image-store.s3.amazonaws.com/0/12026/7e94e226-dd33-ae63-e989-24004c1d9133.png)
図. Graph - Legendタブ


Displayタブで、描画する線の太さなどを設定します。積み重ねて表示する場合は、Stackをチェックします。

![Grafana - c1812j - Google Chrome_051.png](https://qiita-image-store.s3.amazonaws.com/0/12026/a375b1d0-e344-5c6e-283f-1feda3f1c03a.png)
図. Graph - Displayタブ


#### ダッシュボードの定義
グラフの作成が完了したあとは、上部の右に「Back to dashboard」でダッシュボード画面に戻ります。ここで、ダッシュボードの定義をします。

ダッシュボードは下記の設定アイコンからできます。
![範囲を選択_057.png](https://qiita-image-store.s3.amazonaws.com/0/12026/9571d258-b1da-b613-2496-1d43adddfd64.png)

```
設定アイコン > Settings

Details
  Title: c1812j
  Editable: チェック
```

![Grafana - c1812j - Google Chrome_058.png](https://qiita-image-store.s3.amazonaws.com/0/12026/afc38bab-f5a5-dc91-949b-bd9ea5e28fe4.png)
図. ダッシュボードの設定

#### 設定の保存
グラフとダッシュボードの設定が完了したあとに、保存します。保存は、下記の保存アイコンでできます。
![範囲を選択_059.png](https://qiita-image-store.s3.amazonaws.com/0/12026/aed1db00-7750-42ef-2dd5-104401992c5c.png)
グラフを変更した場合は、必ず保存してください。保存しない場合は、ブラウザを閉じるとすべての変更内容が失われます。
すべての設定が完了すると、下記のグラフのダッシュボードができます。また、+ADD ROWボタンで、グラフを追加することが可能です。

![Grafana - c1812j - Google Chrome_060.png](https://qiita-image-store.s3.amazonaws.com/0/12026/18521eb7-9c24-fbbb-5b4a-78a12bd45a59.png)
図. Grafanaのダッシュボード画面


Grafanaダッシュボード
============================================================
トラフィックとパケット数を追加すると下記のようなダッシュボードができます。

![Grafana - c1812j - Google Chrome_061.png](https://qiita-image-store.s3.amazonaws.com/0/12026/c1f1ed42-3c13-3ba6-3ec9-f296cf16a08e.png)
図. Grafanaダッシュボード - c1812jルータ

設定変更することで、積み重ねて表示するスタック表示もできます。アップリンクが複数ある場合、重ねて表示することで総量を把握することができます。

![Grafana - c1812j - Google Chrome_062.png](https://qiita-image-store.s3.amazonaws.com/0/12026/1803d2a3-cd67-1eff-cfa2-3387bfc273f8.png)
図. Grafanaダッシュボード - c1812jルータ（スタック表示）

おわりに
============================================================
今回はGraphite+Grafanaを試用するためにcollectdを使ってSNMPでメトリクスを収集しました。今後はSNMP以外で収集したメトリクスをGraphiteに保存して、実環境で使っていきたいと思います。

より活用したい場合は、下記のドキュメントを参照してください。

- [Grafana Documentation](http://docs.grafana.org/guides/basic_concepts/)
- [Graphite Documentation](http://graphite.readthedocs.io/en/latest/#)