(読者がじゃぶじゃぶ可視化したくなるようなメトリクス心を煽りまくるリードテキスト。)
迫り来るクライシスに備えて
Recipeの第359回では水野さんが
ロードアベレージやメモリ・
さらに最近はクラウド上に何台ものインスタンスを立ち上げたり、
そんな方に向けて、
モニタリングフレームワーク「Sensu」
今回紹介する
- 設定ファイルはすべてJSONで小分けも可能
- 監視やメトリクス用のプラグインは好みの言語を利用できる
- NagiosのNRPEプラグインも流用できる
- APIやExternal Inputといった機能で外部からの操作が可能
- 監視結果をIRCやSlackといった外部のサービスへ整形して転送する機能
- SSLを用いたセキュアな通信
- スケールアウトや多重化が容易な自由度の高いコンポーネント構成
SensuそのものにはWebブラウザー向けのフロントエンドはありません。以前はSensu Dashboardと言うSinatraを使ったフロントエンドが存在していたのですが、
また収集したデータをグラフ化するには、
Sensuそのものが提供するのは、

Sensuのセットアップ
Sensuには最初からChefのクックブックやPuppetのモジュールが用意されているため、
ちなみにここではSensu ServerやAPI、
サーバーの下準備
まずはSensu Server側のセットアップ方法から説明しましょう。クライアントやサーバーとRabbitMQはSSLで通信します。そのためはじめに証明書を作っておきます。
$ cd /tmp $ wget http://sensuapp.org/docs/0.16/tools/ssl_certs.tar $ tar -xvf ssl_certs.tar $ cd ssl_certs $ ./ssl_certs.sh generate
serverディレクトリにRabbitMQサーバー用の証明書が、
次にRabbitMQとRedisをインストールします。
$ sudo apt install rabbitmq-server redis-server
さらに先程作成した証明書を使って、
$ sudo mkdir -p /etc/rabbitmq/ssl $ sudo cp sensu_ca/cacert.pem server/cert.pem server/key.pem /etc/rabbitmq/ssl
/etc/
[
{rabbit, [
{ssl_listeners, [5671]},
{ssl_options, [{cacertfile,"/etc/rabbitmq/ssl/cacert.pem"},
{certfile,"/etc/rabbitmq/ssl/cert.pem"},
{keyfile,"/etc/rabbitmq/ssl/key.pem"},
{verify,verify_peer},
{fail_if_no_peer_cert,true}]}
]}
].
ここにもあるようにRabbitMQのSSL接続時の待ち受けポート番号を5671に設定しています。このポートのみ、
RabbitMQを再起動したうえで、
$ sudo service rabbitmq-server restart $ sudo rabbitmqctl add_vhost /sensu $ sudo rabbitmqctl add_user sensu mypass $ sudo rabbitmqctl set_permissions -p /sensu sensu ".*" ".*" ".*"
Sensuのインストール
今回利用するsensuパッケージは、
Sensu本体は公式が提供しているリポジトリを利用します。
$ wget -q http://repos.sensuapp.org/apt/pubkey.gpg -O- | sudo apt-key add - $ echo "deb http://repos.sensuapp.org/apt sensu main" | sudo tee /etc/apt/sources.list.d/sensu.list $ sudo apt update $ sudo apt install sensu
sensuパッケージは必要なRubyやそのライブラリなどもセットで/opt/
$ sudo sed -i 's/^\(EMBEDDED_RUBY=\)false/\1true/' /etc/default/sensu
Sensu ServerもSensu ClientもRabbitMQから見ると
$ sudo mkdir -p /etc/sensu/ssl $ sudo cp client/cert.pem client/key.pem /etc/sensu/ssl/
/etc/
{
"rabbitmq": {
"ssl": {
"cert_chain_file": "/etc/sensu/ssl/cert.pem",
"private_key_file": "/etc/sensu/ssl/key.pem"
},
"host": "localhost",
"port": 5671,
"vhost": "/sensu",
"user": "sensu",
"password": "mypass"
}
}
hostとportはRabbitMQサーバーのアドレスとポート番号を指定します。RabbitMQとSensu Serverが同じホストであれば上記のようにlocalhostでつながりますし、
Sensu Serverのセットアップ
ここまででインストールしたSensuがRabbitMQとSSL経由で接続できる設定までは行えました。これはサーバーとクライアント双方に必要な作業です。次にサーバー固有の設定を行います。
まずSensu ServerがRedisに接続するための設定を行います。/etc/
{
"redis": {
"host": "localhost",
"port": 6379
}
}
次にAPIサーバーの設定です。/etc/
{
"api": {
"host": "localhost",
"port": 4567
}
}
これらは/etc/
最後にSensu ServerとSensu APIを起動します。
$ sudo service sensu-server start $ sudo service sensu-api start
/var/
$ sudo update-rc.d sensu-server defaults $ sudo update-rc.d sensu-api defaults
Sensu Clientのセットアップ
次にSensu Clientの設定です。Sensu ClientはRabbitMQと通信できれば問題ありません。よってSensuのインストールと以前に作った証明書のうちクライアント関連の証明書のコピー、
クライアント特有の設定として/etc/
{
"client": {
"name": "sensu-server",
"address": "localhost",
"subscriptions": [ "all" ]
}
}
nameはクライアントマシンを識別するための名前で、
Sensu Clientは起動すると上記設定ファイルの内容をRabbitMQで通知します。Sensu Serverはこの通知を受けてクライアントを登録し、
Sensu Serverは監視やメトリクスの収集を行う際の対象をsubscriptionsで指定されたグループで決定します。これについては後ほど説明します。
クライアントを起動してみましょう。
$ sudo service sensu-client start
ログは/var/
$ sudo update-rc.d sensu-client defaults
ClientはServerに登録されたら、
Uchiwaのインストール
冒頭でも説明したようにUchiwaは、
$ sudo apt install uchiwa
設定ファイルは/etc/
{
"sensu": [
{
"name": "Sensu",
"host": "127.0.0.1",
"ssl": false,
"port": 4567,
"user": "",
"pass": "",
"path": "",
"timeout": 5
}
],
"uchiwa": {
"host": "0.0.0.0",
"port": 3000,
"user": "admin",
"pass": "secret",
"interval": 5
}
}
なお、
$ sudo service uchiwa start
ログファイルは/var/
$ sudo update-rc.d sensu-client defaults
実際に


試しに別のマシンにSensu Clientをインストールし、
Sensuのモニタリングシステム
Sensuではクライアントごとに確認しなければならない単位項目を
では監視やメトリクスの収集を行う際の基本となるCheckを追加してみましょう。行わなければならない作業は次のとおりです。
- クライアントにCheckスクリプトをインストールする
- サーバーにCheckスクリプトを呼び出す設定
(Check) を追加する - クライアントを追加したCheckに登録する
Checkスクリプトとは実際にデータを収集したり、
Sensuではコミュニティで開発しているプラグインをGitHubで公開しています。そこで今回は
$ sudo wget -O /etc/sensu/plugins/check-file-exists.rb \ https://raw.github.com/sensu/sensu-community-plugins/master/plugins/files/check-file-exists.rb $ sudo chmod 755 /etc/sensu/plugins/check-file-exists.rb
このRubyスクリプトは指定したファイルが存在するときにオプションのステータスを返すシンプルなスクリプトです。APTシステムでアップグレードした時、
スクリプトそのものはクライアント側のローカルで次のようにテストできます。
$ /opt/sensu/embedded/bin/ruby /etc/sensu/plugins/check-file-exists.rb -c /var/run/reboot-required CheckFileExists OK: No test files exist
次にサーバー側で、
{
"checks": {
"check_reboot": {
"handlers": ["default"],
"command": "/etc/sensu/plugins/check-file-exists.rb -c /var/run/reboot-required ",
"interval": 10,
"subscribers": [ "reboot" ]
}
}
}
commandにクライアント側で実行して欲しいコマンドを記述します。intervalは実行間隔です。テスト目的で10秒間隔としていますが、
Sensu Serverの設定を変更したので再起動しておきましょう。ちなみにSensu Serverを再起動する場合は、
$ sudo service sensu-server restart $ sudo service sensu-api restart
再びクライアント側に戻り、
{
"client": {
"name": "sensu-server",
"address": "localhost",
"subscriptions": [ "all", "reboot" ]
}
}
最後にclient.
$ sudo service sensu-client restart
これで、


「Standalone Check」
InfluxDBとGrafanaでグラフ作成
冒頭で、
InfluxDBとGrafanaのインストール
「InfluxDB」
$ wget http://s3.amazonaws.com/influxdb/influxdb_latest_amd64.deb $ less influxdb_latest_amd64.deb $ sudo dpkg -i influxdb_latest_amd64.deb $ sudo service start influxdb $ curl -X POST 'http://localhost:8086/db?u=root&p=root' -d '{"name": "stats"}'
設定ファイルは/opt/
「Grafana」
$ sudo apt install nginx $ sudo rm /etc/nginx/sites-enabled/default $ sudo mkdir -p /var/www/html $ cat <<EOF | sudo tee /etc/nginx/sites-available/grafana server { listen 80 default_server; listen [::]:80 default_server ipv6only=on; root /var/www/html/; index index.html index.htm; server_name localhost; location /grafana { index index.html index.htm; } } EOF $ sudo ln -s /etc/nginx/sites-available/grafana /etc/nginx/sites-enabled/ $ sudo service nginx configtest $ sudo service nginx restart $ wget http://grafanarel.s3.amazonaws.com/grafana-1.9.1.tar.gz $ tar xvf grafana-1.9.1.tar.gz $ sudo mv grafana-1.9.1 /var/www/html/grafana $ sudo chown -R www-data: /var/www/html/grafana
また/var/
datasources: {
influxdb: {
type: 'influxdb',
url: "http://(InfluxDBのアドレス):8086/db/stats",
username: 'root',
password: 'root',
},
grafana: {
type: 'influxdb',
url: "http://(InfluxDBのアドレス):8086/db/grafana",
username: 'root',
password: 'root',
grafanaDB: true
},
},
なお、
Metricの追加
次はSensu側の設定です。まずはデータの収集から。Checkのタイプに
コミュニティで開発しているプラグインにvmstatの出力結果を取得するMetricスクリプトがありますのでそれを利用します。クライアント側で次のように実行します。
$ sudo wget -O /etc/sensu/plugins/vmstat-metrics.rb \ https://raw.github.com/sensu/sensu-community-plugins/master/plugins/system/vmstat-metrics.rb $ sudo chmod 755 /etc/sensu/plugins/vmstat-metrics.rb $ /opt/sensu/embedded/bin/ruby /etc/sensu/plugins/vmstat-metrics.rb sensu-client.vmstat.procs.waiting 0 1423466090 sensu-client.vmstat.procs.uninterruptible 0 1423466090 sensu-client.vmstat.memory.swap_used 0 1423466090 (以下略)
クライアントの設定ファイル/etc/
{
"client": {
"name": "sensu-server",
"address": "localhost",
"subscriptions": [ "all", "reboot", "vmstat" ]
}
}
最後にclient.
$ sudo service sensu-client restart
サーバー側に/etc/
{
"checks": {
"vmstat_metrics": {
"type": "metric",
"handlers": [ "influxdb" ],
"command": "/etc/sensu/plugins/vmstat-metrics.rb",
"interval": 60,
"subscribers": [ "vmstat" ]
}
}
}
ポイントはtypeがmetricになっていることと、
HandlerとMutator
HandlerはEvent Dataを受け取ったときに、
さらに他のプログラムにデータを渡す前に、
今回はMutatorは使わずHandlerだけ必要です。influxdb-metrics用のスクリプトをダウンロードします。
$ sudo wget -O /etc/sensu/handlers/influxdb-metrics.rb \ https://raw.github.com/sensu/sensu-community-plugins/master/handlers/metrics/influxdb-metrics.rb $ sudo chmod 755 /etc/sensu/handlers/influxdb-metrics.rb $ sudo /opt/sensu/embedded/bin/gem install influxdb $ sudo sed -i "s/each/each_line/" /etc/sensu/handlers/influxdb-metrics.rb
最後のsedは、
{
"handlers": {
"influxdb": {
"type": "pipe",
"command": "/etc/sensu/handlers/influxdb-metrics.rb"
}
},
"influxdb": {
"server": "localhost",
"port": "8086",
"username": "root",
"password": "root",
"database": "stats"
}
}
最後にサーバーを再起動します。
$ sudo service sensu-server restart $ sudo service sensu-api restart
これで定期的にvmstatの結果がInfluxDBに保存されます。実際にデータが保存されているかどうかは、
$ curl -G 'http://localhost:8086/db/stats/series?u=root&p=root' \ --data-urlencode "q=select value from vmstat_memory_free;"
うまく保存されてないようなら、
Grafanaの確認
最後にGrafanaのページをブラウザで表示してみましょう。最初は何も選択されていないため、
Dashboardにあるグラフの

Grafanaの操作についての詳しいことは公式のチュートリアルを参照してください。
Sensu of Wonder
いかがでしたでしょうか。導入までがすごく面倒で、
ただし今回はなるべく手作業でいろいろなものをインストールしています。これらの煩雑に見える部分も、
Sensuはあくまでフレームワークであり、
ぜひSensuを使って、