hidemium's blog

日々学んだことをアウトプットする。

SensuからElasticsearchにメトリクスを転送する

前回、Elasticsearchのインストールができたため、今回はinokappa/sensu-handler-metrics-elasticsearchを用いて、SensuからElasticsearchにDockerコンテナのメトリクスを転送できるか試してみました。*1
なお、Sensuのメトリクスの可視化にはGraphiteがよく使われていますが、FluentdではElasticsearchが使われており、サーチエンジンを使い分けるのは大変そうだったので、Elasticsearchにしてみました。

構成

Ubuntu 12.04: Sensu Server、Sensu Client
Ubuntu 12.04: Elasticsearch
※上記はDocker 1.0.0上で動作しています。

Sensu Serverの設定

Sensu Server側でElasticsearchと連携するための設定を行います。
config.jsonに以下の設定を追加します。

$ vi /etc/sensu/config.json
{
  "rabbitmq": {
    "port": 5672,
    "host": "localhost",
    "user": "admin",
    "password": "admin",
    "vhost": "/"
  },
  "redis": {
    "host": "localhost",
    "port": 6379
  },
  "api": {
    "host": "localhost",
    "port": 4567
  },
  "dashboard": {
    "host": "localhost",
    "port": 8080,
    "user": "admin",
    "password": "admin"
  },
  "handlers": {
    "default": {
      "type": "pipe",
      "command": "true"
+   },
+   "elasticsearch-metrics": {
+     "type": "pipe",
+     "command": "/etc/sensu/handlers/metrics/elasticsearch-metrics.rb"
    }
  }
}

今回はvmstatの情報を転送するため、vmstatの監視設定を追加します。
typeは「metric」、handlersは「elasticsearch-metrics」とします。

$ vi /etc/sensu/conf.d/metrics/metric_vmstat.json
{
  "checks": {
    "vmstat_metrics": {
      "type": "metric",
      "handlers": ["elasticsearch-metrics"],
      "command": "/etc/sensu/plugins/system/vmstat-metrics.rb",
      "subscribers": [
        "default","sensu"
      ],
      "interval": 60
    }
  }
}

SensuのメトリクスをElasticsearchに転送するスクリプトを取得します。

$ cd /etc/sensu/handlers/metrics
$ wget https://raw.githubusercontent.com/inokappa/sensu-handler-metrics-elasticsearch/master/elasticsearch-metrics.rb
$ chmod 755 elasticsearch-metrics.rb

転送先のElasticsearchサーバを指定するファイルを取得します。
ファイルを取得後、ElasticsearchサーバのIPアドレスとポート番号を設定します。

$ cd /etc/sensu/conf.d
$ wget https://github.com/inokappa/sensu-handler-metrics-elasticsearch/blob/master/elasticsearch-metrics.json
$ vi elasticsearch-metrics.json
{
  "elasticsearch-metrics": {
    "host": "<IPアドレス>",
    "port": <ポート番号>,
    "index": "sensu-metrics",
    "type": "metrics"
  }
}

Elasticsearchは、データをインポートすると、ルールに従って自動的に各フィールドの型を識別し、マッピング(フィールドと型の組み合わせ)が自動で設定されます。
ただ、思ったとおりにマッピングが設定されない場合もあるため、Mapping Templateという機能を使い手動でマッピングを定義します。

$ curl -XPUT <ElasticsearchのIPアドレス>:<ポート番号>/_template/vmstat_metrics -d '
{
    "template" : "sensu-metrics*",
    "mappings" : {
      "vmstat_metrics" : {
        "numeric_detection" : true,
        "properties" : {
          "@timestamp" : { "type":"date", "format":"dateOptionalTime" },
          "client" : {type: "string"},
          "status": {type: "long"},
          "address": {type: "string"},
          "check_name": {type: "string"},
          "occurrences": {type: "long"},
          "value": {type: "long"},
          "command": {type: "string"},
          "key": {type: "string"}
          }
        }
      }
    }
  }
'

今回、手動マッピングでvalueフィールドをlong型で定義しているにも関わらず、valueフィールドに転送したデータの型により、valueフィールドがString型で定義される場合がありました。
この問題をつぶやいていたところ、以下のようなコメントを頂き、「numeric_detection」を使うことで問題を解決することができました。

最後に、Sensu Serverの再起動を行い、Elasticsearchとの連携設定を反映させます。
supervisorでSensu Serverのautorestartをオンにしているため、stopコマンドだけ実行しています。

$ service sensu-server stop

Elasticsearchの確認

マッピングが思ったようにできているか確認するため、「http://<サーバのIPアドレス>:9200/_plugin/head」にアクセスし、 Overviewタブ>インデックス(vmstat_metrics)>infoボタン>Index Metadataをクリックします。
valueフィールドのtypeを見るとlongになっていることが確認できます。

f:id:hidemium:20140716005458p:plain

「http://<サーバのIPアドレス>:<ポート番号>」からKibanaにアクセスし、トップページの「Sample Dashboard」をクリックすると、Sensuのメトリクスが転送されているのが確認できます。

f:id:hidemium:20140716005827p:plain

おわりに

SensuからElasticsearchにメトリクスを転送することができ、Dockerコンテナの監視の可視化に向けて一歩進んだかと思います。

今回の記事は、Sensuのスクリプトを作成された@inokaraさんのブログを参考にさせて頂きました。また、マッピングの問題では@johtaniさんにコメントを頂き助かりました。
@inokaraさん、@johtaniさんありがとうございした。

*1:Dockerコンテナ内からはコンテナごとのリソース情報は見えず、ホスト全体のリソース情報しか見えないので、今回はメトリクスの転送をすることを目的としています。