InfluxDBとGrafanaを使ってサーバーリソースの可視化をする

muninに辛くなってfabricでなんやかんやするアプリケーションを作ったりしていたがグラフ描画部分で辛くなり、色々と調べた結果InfluxDBとGrafanaの組み合わせが良さそうだったので、それでいい感じにリソース可視化してみたという内容。

## 概要

監視サーバーと監視されるサーバー群が存在していて、監視サーバーにInfluxDB、Grafana、Fabricをインストールする。
監視サーバーはFabricで各サーバーにssh接続しメトリックを取得する。取得したメトリックはInfluxDBに保存され、Grafanaで可視化される。という感じ。


## Versions

OSはCentOSでやったけどInfluxDBとGrafanaのインストールと起動が違うだけだと思われる。
InfluxDB = __0.8.8__(stable)
Grafana = __2.0.1__
Fabric = __1.10.1__
influxdb-python = __2.2.0__

## Install & Launch

公式のinstallationがちゃんとしているのでそこをそのまま実行。

### [InfluxDB](http://influxdb.com/docs/v0.8/introduction/installation.html)

デフォルトだと __8083__, __8086__, __8090__, __8099__番のポートを使うので、必要なら開けておく。
`ulimit -n 65536`でファイルディスクリプタ数の上限を上げる。

```bash
wget http://s3.amazonaws.com/influxdb/influxdb-latest-1.x86_64.rpm
sudo rpm -ivh influxdb-latest-1.x86_64.rpm
sudo service influxdb start
```

### [Grafana](http://docs.grafana.org/installation/)

デフォルトだと __3000__番のポートを使うので、必要なら開けておく。

```bash
wget install https://grafanarel.s3.amazonaws.com/builds/grafana-2.0.2-1.x86_64.rpm
sudo rpm -ivh grafana-2.0.2-1.x86_64.rpm
sudo service grafana-server start
```

### [Fabric](http://www.fabfile.org/installing.html)

各サーバーからメトリクスを取得するのに使用する。各サーバーから数値を取ってきてInfluxDBに保存できるのなら別にFabricじゃなくても可。今は[Diamond](https://github.com/python-diamond/Diamond)というツールが良さそうかなーと目星をつけている。
FabricのインストールはPythonのパッケージシステムから。(2.x系のPythonじゃないと動かない)

```bash
sudo pip install Fabric
```

### [influxdb-python](https://github.com/influxdb/influxdb-python)

これもpipでインストールする。Fabricを使用しないならいらない。

```bash
sudo pip install influxdb
```

## Setting

InfluxDB、Grafana共にwebインターフェースにアクセスできる。
ユーザーとかは各自色々やってください。

### InfluxDB

メトリクスを保存するためのDBを作成する。

`http://localhost:8083/`にアクセスするとログインを求められるので`user=root`, `password=root`でログインする。
![screenshot 2015-05-10 22.00.21.png](https://qiita-image-store.s3.amazonaws.com/0/22102/6fe23324-15cf-915a-a0f1-18f5d705c3c9.png "screenshot 2015-05-10 22.00.21.png")

ログインするとデータベース一覧が表示される。
各サーバーから取得した計測値を格納する`dimensions`というデータベースを新しく作成する。
![screenshot 2015-05-10 22.20.41.png](https://qiita-image-store.s3.amazonaws.com/0/22102/3c6f54c8-be0f-55de-ca7e-a752b14fc505.png "screenshot 2015-05-10 22.20.41.png")

### GraphanaとInfluxDBの接続

`http://localhost:3000/`にアクセスするとこちらもログインを求められる。デフォルトは`user=admin`, `password=admin`でログイン出来る。
![screenshot 2015-05-10 22.36.18.png](https://qiita-image-store.s3.amazonaws.com/0/22102/e455a36a-17f4-c94a-19f1-e4ebfe74cbcf.png "screenshot 2015-05-10 22.36.18.png")

空のダッシュボード。左上のGrafanaマークをクリックするとメニューが開くので、メニュー中のData Sourcesをクリックし、Grafanaのバックエンド設定画面を開く。
![screenshot 2015-05-10 22.27.55.png](https://qiita-image-store.s3.amazonaws.com/0/22102/5644a7b0-d9ee-6fa0-80a9-921a8e0f70cc.png "screenshot 2015-05-10 22.27.55.png")

Data Sourcesをクリック後、画面中央上のAdd newをクリックしInfluxDB 0.8.xをバックエンドに設定する。urlのポートはapiのポートなので、ブラウザの8083ではなく __8086__を指定する事に注意。Nameは適当でいい。 Databaseは先ほどInfluxDBで作成したdimensionsを設定する。最後にAddをクリックで完了。
![993856d7-2af3-aeff-d05c-f6ac3a2df1f0.png](https://qiita-image-store.s3.amazonaws.com/0/22102/2c049cb2-69ae-5934-a695-df117171f428.png "993856d7-2af3-aeff-d05c-f6ac3a2df1f0.png")


これでGrafanaとInfluxDBのつなぎ込みが完了した。

### Fabric

各サーバーからメトリクスを取得しInfluxDBに保存する。詳しい使い方は他のページで見る感じでお願いします。

```python:fabfile.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from fabric.api import env, run
from influxdb.influxdb08 import InfluxDBClient
import re

env.hosts = ["server01.hoge.jp"]
env.key_filename  = ["~/.ssh/server01_rsa"]
env.user = "myuser"
client = InfluxDBClient('localhost', 8086, 'root', 'root', 'dimensions')

def loadaverage():
    match = re.search(r"load averages?:\s+(\d+\.\d+),\s+(\d+\.\d+),\s+(\d+\.\d+)", run("uptime"))
    min1  = float(match.group(1))
    min5  = float(match.group(2))
    min15 = float(match.group(3))
    client.write_points([
        {
            "name": "loadaverage_1min",
            "columns": ["value"],
            "points": [[min1]]
        },
        {
            "name": "loadaverage_5min",
            "columns": ["value"],
            "points": [[min5]]
        },
        {
            "name": "loadaverage_15min",
            "columns": ["value"],
            "points": [[min15]]
        }
    ])

```
こんな感じのfabfileを用意し、crontabで毎分実行するようにする。
`*/1 * * * * fab loadaverage`

数分経ってからInfluxDBのdimensions DBのwebインターフェースから`list series`とクエリを投げて3つseriesが返ってきたらok。ちなみにseriesとはRDBにおけるtableみたいなもの。
![screenshot 2015-05-11 0.25.31.png](https://qiita-image-store.s3.amazonaws.com/0/22102/b900baca-8deb-ff13-92be-cbe832b5ec7a.png "screenshot 2015-05-11 0.25.31.png")

### Grafanaで可視化

ダッシュボードのメニューからNewを選択する。
![e455de07-5be3-037a-a27b-65307479189a.png](https://qiita-image-store.s3.amazonaws.com/0/22102/9461fd58-d0f2-d145-570c-1dfff049ef64.png "e455de07-5be3-037a-a27b-65307479189a.png")


新しいダッシュボードに飛ばされるので、緑色のところからメニューを開いて新規グラフを作成する。
![da410db2-31c3-86c4-2bd8-fd258e1d231c.png](https://qiita-image-store.s3.amazonaws.com/0/22102/1e078736-fdea-61ac-c7b3-4875d4df425e.png "da410db2-31c3-86c4-2bd8-fd258e1d231c.png")


グラフのタイトル(no title(click here)となっている所)をクリックしeditでグラフの設定画面を開く。
seriesに`loadaverage_1min`と入力するとグラフが出てくる(!)。group by timeを`1m`に設定。
後はAdd queryを押してクエリを追加し、同じように`loadaverage_5min`と`loadaverage_15min`の設定を追加する。
aliasとかグラフタイトルとかをいい感じに設定するとさらに良い。ちなみにseries名をドット区切りで付けていればaliasでドットで区切ったそれぞれのフィールドが\$0, \$1...に代入されるので変数が使える。
この辺、fork元のkibanaより設定がしやすいような気がする(設定もリアルタイムに反映されるし)。
![7c5f7bca-ddc8-9e8b-be39-7c82099bd106.png](https://qiita-image-store.s3.amazonaws.com/0/22102/edd8e588-3eb7-ebc5-3e28-ba34c804d94a.png "7c5f7bca-ddc8-9e8b-be39-7c82099bd106.png")

右上の時間表示からグラフに表示する最大時間とリアルタイム更新の時間を設定できる。最後に保存をクリックすればダッシュボードが完成する。

後は煮るなり焼くなりどうぞという感じ。
![screenshot 2015-05-12 0.05.50.png](https://qiita-image-store.s3.amazonaws.com/0/22102/14d03ccd-0667-9bdd-7573-18637275ab6a.png)


## まとめ

個人的に作ってて辛かったメトリクスデータの時系列管理とグラフ化がInfluxDBとGrafanaで非常に簡単に出来た。
InfluxDBの1.0リリースが楽しみだけど0.8と0.9で互換性があまりないっぽいのでつらそう。
Grafanaはkibanaのクローンということで見た目のかっこよさはそのままに、操作性がさらに良くダッシュボードが作れるようになってて最高。また、Kibanaで可視化したいだけなのにElasticsearch入れないといけないのが結構辛かったけれど、Grafanaはバックエンドの種類を選べるのが地味に嬉しい。
FabricもDiamondも競合するわけでは無いので、loadaverageとか一般的なメトリクスはDiamond、もっとアプリケーション寄りなメトリクスだったらFabricというように使い分けるのがよさそう。
ダッシュボードは今回書いたグラフ表示に加えて、Single statもあるので、現在の状態を表示するだけ、みたいな事も出来る。アノテーションを付けてグラフのここはこの状態だったみたいな事も出来るっぽい。