2014年12月7日

elasticsearch+kibana3を使ってログを可視化してみた


以前、Raspberry Piに温度/気圧センサーを取り付けて、その結果をXivelyにロギングしていたのですが、今回たまたま見かけたお名前.comクラウドの一万円クーポンがあったので、(遅ればせながら)Ubuntu環境にelasticsearchとkibana3を導入して、温度/気圧センサーのログを可視化してみる事にしました。

#クーポンのおかげ?か、例のメールが届きました。
#担当者さんの心中をお察しします。。

お名前.comクラウド上に仮想サーバを作成

まずはお名前.comクラウドのコントロールパネルにログインして、サービスメニューの”サーバ追加”より仮想サーバを起動します。OSは前述の通りUbuntu 12.04を選択し、タイプはvCPUx1/メモリ1GBのO-101を選択しました。
仮想サーバが起動したら、SSH公開鍵を使ってログインし、apt-get updateやファイアウォールの設定などの下準備を行います。

Oracle JDK 7のインストール

elasticsearchを動作させるためにはJavaランタイム環境が必要になるのですが、いつものapt-getではインストールできないため、下記のコマンドを実行します。
(”ランタイム環境”のみあればいいはずなので、OpenJRE/OracleJREでもよさそうですが、今回は公式のJDKで試しています)
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get install oracle-java7-installer
(oracle-java8-installerで、最新のJava8がインストールできるようです)
インストールが終わった後に、"java -version"と入力してバージョン情報が表示されれば正しくインストールされているかと思います。

elasticsearchのインストール

Javaランタイム環境の準備ができたので、次はelasticsearchをインストールします。
$ sudo apt-get install elasticsearch
公式サイトではUbuntu向けにdebパッケージも提供されているため、そちらをダウンロードしてdpkg -iでインストールしてもOKです。
インストールが終了したら、curlコマンドで下記にアクセスして応答が返ってくる事を確認します。
$ curl -s "http://localhost:9200/"
{  "status" : 200,  "name" : "Thinker",  "cluster_name" : "elasticsearch",  "version" : {    "number" : "1.4.1",    "build_hash" : "89d3241d670db65f994242c8e8383b169779e2d4",    "build_timestamp" : "2014-11-26T15:49:29Z",    "build_snapshot" : false,    "lucene_version" : "4.10.2"  },  "tagline" : "You Know, for Search"}

Raspberry Piからelasticsearchにログを登録

elasticsearchにログを登録する場合は、logstashやfluentdを使うケースが多いみたいですが、今回は直接elasticsearchにログを登録する方法で試してみました。
こちらより、Raspberry Piに設置した温度/気圧センサー(BMP085)から値を取得するプログラムをダウンロードし、結果を出力する部分をJSON形式に改造します。
41a42
>#include <time.h>
236,238c237,248
<
< printf("Temperature\t%0.1f%cC\n", ((double)temperature)/10,0x00B0);
< printf("Pressure\t%0.2fhPa\n", ((double)pressure)/100);
---
>
> time_t timer;
> struct tm *date;
> char dt[255];
>
> timer = time(NULL);
> date = localtime(&timer);
> strftime(dt, 255, "%Y-%m-%dT%H:%M:%S", date);
>
> // printf("Temperature\t%0.1f%cC\n", ((double)temperature)/10,0x00B0);
> // printf("Pressure\t%0.2fhPa\n", ((double)pressure)/100);
> printf("{\"datetime\": \"%s\", \"temperature\": %0.1f, \"pressure\": %0.2f}\n", dt, ((double)temperature) / 10, ((double)pressure) / 100);
ソースの修正が終わったら、一緒にダウンロードしたsmbus.c, smbus.hとともにgccでコンパイルし、できたコマンドをrootで実行するようsetuidビットを設定します。
sudo gcc -Wall -o bmp085 ./testBMP085.c ./smbus.csudo chmod 4755 ./bmp085sudo mv ./bmp085 /usr/local/bin
これでBMP085から、現在時刻(datetime)と温度(temperrature)と気圧(pressure)がJSON形式で取得できるようになったので、以下のcurlコマンドをcronに登録してelasticsearchにログを登録します。

* * * * * /usr/bin/curl -s -X POST "http://[リモートIPアドレス]:9200/bmp085/stats" -d "$(/usr/local/bin/bmp085)" > /dev/null
URLパスの"bmp085"がインデックス名、"stats"がタイプ名になります。
なお、登録されるデータは、先ほどのコマンドで出力されるJSONデータ(日時フィールドの"datetime"、気温の"temparature"、気圧の"pressure")になります。
ログが正しく登録されているかは、下記コマンドで確認することができます。
$ curl -s -X GET http://[リモートIPアドレス]:9200/bmp085/stats/_search
{
  "took": 3, "timed_out": false,
  "_shards": {
    "total": 5, "successful": 5, "failed": 0
  },
  "hits": {
    "total": 1213, "max_score": 1,
    "hits": [
      {
        "_index": "bmp085",
        "_type": "stats",
        "_id": "AUogPm0qkUV2E2kcxVxl",
        "_score": 1,
        "_source": {
          "datetime": "2014-12-07T00:36:09",
          "temperature": 15.8,
          "pressure": 1009.74
        }
      },
... 

kibana3のインストール

elasticsearchのログを可視化するためのツールとして、今度はkibana3をインストールします。
公式サイトよりパッケージをダウンロードし、ApacheやnginxなどのWebサーバのドキュメントルートに配置します。
(今回はnginxを使ってみました)
$ sudo apt-get install nginx
$ cd /usr/share/nginx/www
$ sudo curl -O https://download.elasticsearch.org/kibana/kibana/kibana-3.1.2.zip
$ sudo unzip kibana-3.1.2.zip
$ sudo mv kibana-3.1.2 kibana
なお今回試していませんが、Apacheやnginxをインストールしなくても、elasticsearchのプラグインとしてkibana3をインストールすれば、elasticsearch自身がkibana3をホストしてくれるみたいです。

クロスドメイン通信許可の設定

早速、前述で設置したkibana3(http://[リモートIPアドレス]/kibana)にアクセスしてみると、下記エラー画面(Connection Failed)が表示されるはずです。
これは、elasticsearch+kibana3をローカル環境ではなくリモート環境に構築している関係かと思われますが、elasticsearch.ymlにクロスドメイン通信許可の設定を加えることでアクセスできるようになります。
$ sudo vim /etc/elasticsearch/elasticsearch.yml
  http.cors.allow-origin: "/.*/"
  http.cors.enabled: true$ sudo service elasticsearch restart

ダッシュボードの作成

elasticsearchにログが記録され、kibana3の表示が確認できたところで、いよいよログを可視化するためのダッシュボードを作成します。
前述の通り今回はlogstashやfluentdなどを使わずログの記録を行っているため、一番下の"Blank Dashboard"より作成を開始します。
すると、"QUERY"と"FILTERING"などが表示された空のダッシュボード画面が表示されますので、そこから右上の歯車アイコン(Configure dashboard)をクリックし、ダッシュボードの設定画面へ進みます。

まず最初のGeneralで、ダッシュボードのタイトルを入力します。
次のIndexでは、名前の通りelasticsearch上のインデックス名を入力します。
Rowsでは、まずAdd RowのTitleにタイプ名を入力します。入力が終わったら【Create Row】ボタンを押下します。
すると左側のRowsに追加されます。
最後に、TimepickerでTime Fieldにelasticsearchに登録されているデータの日時フィールド名を入力します。終わったら【Save】ボタンを押下して入力内容を保存します。 
作成中のダッシュボードに戻ると、"Add panel to empty row"と書かれた項目が追加されているので、文字リンクをクリックしてパネルの設定に進みます。
まず、パネルで表示するグラフのタイプを選択します。今回は時系列で温度と気圧を折れ線グラフで可視化するため、"histogram"を選択します。
次にグラフのタイトルを入力します。
チャートの値は平均(mean)とし、その値ソースとして気温フィールド名を入力します。
Time Optionsでは、同じく日時フィールド名を入力します。
最後にパネルのスタイル設定として、棒グラフ(Bars)のチェックを外して折れ線グラフ(Lines)にチェックを入れます。ここまでの入力内容に問題が無ければ【Save】ボタンを押下して入力内容を保存します。


おわりに

予想以上に設定作業が大変で、今回のような温度や気圧程度であれば、elasticsearch+kibana3ではなく、GrowthForecastFocuslightの方がお手軽な感じもしますが、フィルターなどを駆使して自分の分析したい切り口でダッシュボードを作っていく流れは、ツール開発者が作った出来合いの管理画面をただ見るだけとは一線を画す感じがしました。
現在ベータ版のkibana4では、上記の設定フロー周りが改善されているらしいので、今後はもっと使われるケースが多くなってくるのかもしれません。