MongoDB + Elasticsearch + Kibana の構築メモ

# 概要
[kibana](https://www.elastic.co/jp/products/kibana)でビジュアライズしたかったので、構築手順のメモ

全体の流れを簡単に言うと、MongoDBにあるログを[Elasticsearch](https://www.elastic.co/jp/products/elasticsearch)に同期して、Kibanaでビジュアライズし、さらにkibanaの設定(Index PatternとかSaved Objectsとか)をexport/importする手段についてメモる。

## 環境
- Ubuntu 16.04 or CentOS 7 or macOS 10.13
- Elasticsearch 5.6.x
- kibana 5.6.x
- MongoDB 3.4.7 (適当に新しめのでいいと思う)
- Python 3.6.x

なお、後述する[elasticsearch-dump](https://github.com/taskrabbit/elasticsearch-dump)がElasticsearch 5にしか対応していない(2017/12/06現在)ため、わざと5にしている。

# elasticsearchとkibanaインストール
なおMongoDBは各自適当にインストールしてください。

後述するレプリカセットの設定は必須です。

## Ubuntuの場合
### elasticsearch

[ElasticsearchをUbuntu 14.04にインストールする](https://qiita.com/hana_moto/items/762aae6b8f2a93d176d2)

    wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
    sudo apt-get update && sudo apt-get install elasticsearch
    sudo /etc/init.d/elasticsearch start


### kibana

[Download Kibana](https://www.elastic.co/downloads/kibana)から適当に

## CentOSの場合

### elasticsearch

[Elasticsearch を yumでインストール (CentOS)
](http://qiita.com/inouet/items/6276c5a08c4fe5eecdb5)

[Install Elasticsearch with RPM](https://www.elastic.co/guide/en/elasticsearch/reference/current/rpm.html)


    rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
    sudo yum install elasticsearch
    sudo /etc/init.d/elasticsearch restart

### kibana
適当にDownloadしてもいいが、yumでも入れられる

[Install Kibana with RPM](https://www.elastic.co/guide/en/kibana/current/rpm.html)

    rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
    sudo yum install kibana
    sudo systemctl restart kibana.service

## macOSの場合

    brew install elasticsearch@5.6 kibana@5.6


# それぞれの設定

## elasticsearch.yml

[Elasticsearch導入前に気を付けておきたいこと！](http://qiita.com/uzresk/items/e0b10c14875b79c450f2)
[Elasticsearch+kibanaでConnection Failedが出た時の対処法](http://qiita.com/tarr1124/items/65b16df367de3aeb10b5)

基本的にはそのままで良さげだが、これらは要変更した方が良い？

    network.host: 0.0.0.0
    http.cors.allow-origin: "*"
    http.cors.enabled: true
    action.auto_create_index: true

### tips

#### `vm.max_map_count` が足りないとか言われたら

    sudo sysctl -w vm.max_map_count=262144

[Ubuntu LinuxにElasticsearch 5.0.0、Kibana 5.0.0をインストールするAdd Star](http://d.hatena.ne.jp/Kazuhira/20161029/1477751381)

#### ダウンロードしてきたやつから普通に起動するなら

[Choosing configuration file to start elastic cluster](https://stackoverflow.com/a/39018516)

    ./bin/elasticsearch -Epath.conf=/path/to/my/config/


## kibana.yml

後述のリバースプロキシでアクセスしたいなら、以下の変更

    server.basePath: "/kibana"

## mongod.conf
**myRS** は任意のレプリカセット名

mongodを `--replSet myRS` で起動するか、mongod.confで設定

    replication:
        replSetName: myRS

ポートはいい感じにしてください。

次に、mongoコマンドでどれかに接続して、

    config = {_id: 'myRS', members: [
        {_id: 0, host: 'localhost:27017'},
        {_id: 1, host: 'localhost:27018'},
        {_id: 2, host: 'localhost:27019', arbiterOnly:true}
        ]
    }
    rs.initiate(config)
    rs.status()

一時しのぎで適当にレプリカ作るなら

    mkdir rs1
    mongod --dbpath rs1 --port 27018 --replSet myRS --logpath rs1log --fork
    mkdir rs2
    mongod --dbpath rs2 --port 27019 --replSet myRS --logpath rs2log --fork

### 完全にレプリカセットの設定を削除して再設定したい時
dbpathのところで

    rm -f local.*
    rm -f mongod.lock

[MongoDBのレプリカセット作成 & 再構成](https://open-groove.net/mongodb/replica-set-recreate/)

### 再構築したい時

スレーブのデータを全部削除してレプリカセットな起動をすると再構築される

# kibanaを外からアクセス

## nginxでリバースプロキシ

[kibanaをnginxのリバースプロキシでアクセスする](http://qiita.com/fuku2014/items/cb81af84ebac489c9f5a)

proxy_passとrewriteだけで動いた

    location /kibana/ {
        proxy_pass http://localhost:5601;
        rewrite /kibana/(.*)$ /$1 break;
        auth_basic "welcome to Kibana";
        auth_basic_user_file "/usr/local/nginx/.htpasswd";
    }

後述のbasic認証のために一部追記している

## basic認証

x-packで認証かけられるが ***有料*** なので仕方なくbasic認証する。

先述したように `/usr/local/nginx/.htpasswd` にid:pwを書く

普通にhtpasswdコマンドでやってもいいが、http://www.luft.co.jp/cgi/htpasswd.php でもできた


# mongo-connector

MongoDBのデータをelasticsearchに同期する。

レプリカセットの構築は必須。

    pip install 'mongo-connector[elastic5]'
    pip install 'elastic2-doc-manager[elastic5]'

[MongoDBのデータをElasticsearchにリアルタイム同期](http://christina04.hatenablog.com/entry/2016/08/25/011929)

なんか途中で中断したとか、最初からしたいって時は`oplog.timestamp`を削除する。

例えばlinuxならこの辺にある

    sudo rm /var/log/mongo-connector/oplog.timestamp

要は`oplog.timestamp`でどこまで同期しているのかをmongo-connectorが見ている。

つまり、mongo-connectorが突然死んだとしても、再度起動すれば最新まで同期してくれる。

## 全データ消して最初からしたい時はmongodb_metaも消す必要がある？
kibanaのDev ToolsのConsoleなどで

    DELETE YOUR_NAME_SPACE
    DELETE mongodb_meta


## 同期済みだけどnamespaceを追加する

_idがprimary keyとなっているため、`oplog.timestamp`を削除して最初からやったとしても、重複してデータが入ることはないが、再挿入の処理が入るためコストはかかる。

## daemon化

https://github.com/mongodb-labs/mongo-connector/wiki/Installation にあるようにsetup.pyでする

```sh
sudo python setup.py install_service
sudo chmod +x /etc/init.d/mongo-connector
sudo /etc/init.d/mongo-connector start
```

この時、同ディレクトリのconfig.jsonが `/etc/mongo-connector.json` にコピーされるので以後はそちらを参照

この時、デーモンのスクリプトである `scripts/mongo-connector` において、`/usr/bin/python -m mongo_connector.connector` とあるが、環境に応じて`/usr/bin/python3` に変更する必要があるかもしれない。

## config.json

    mongo-connector --config-file=config.json

renameの部分を`hoge.wifi\_log`にすると、indexはhogeで貼られて、wifi\_logでは貼れないので注意。

つまりhogeが親になってしまうので。wifi\_logはwifi\_logだけでindexを貼りたい時は以下の例のようにして別々にする。

後からindexingはkibanaでまとめて参照することができるので、別々でも大丈夫

https://github.com/mongodb-labs/mongo-connector/wiki/Configuration-Options この辺を参考にしつつ、例えばlinuxなら、

```json
{
  "mainAddress": "localhost:27017",
  "oplogFile": "/var/log/mongo-connector/oplog.timestamp",
  "verbosity": 1,
  "logging": {
    "type": "file",
    "filename": "/var/log/mongo-connector/mongo-connector.log",
    "__rotationWhen": "D",
    "__rotationInterval": 1,
    "__rotationBackups": 10
  },
  "namespaces": {
    "hoge.wifi_log": {
      "rename": "hoge-wifi_log.hoge-wifi_log"
    }
  },
  "docManagers": [
    {
      "docManager": "elastic2_doc_manager",
      "targetURL": "localhost:9200"
    }
  ]
}
```
# バックアップとリストア

kibanaの設定を丸ごとバックアップとリストアしたいなら、[elasticsearch-dump](https://github.com/taskrabbit/elasticsearch-dump)を使う

バックアップは

    elasticdump --input="http://localhost:9200/.kibana" --output=kibana_config.json

リストアは

    elasticdump --input=kibana_config.json --output="http://localhost:9200/.kibana"

kibanaのManagementのSaved Objectsから設定全部exportできるような雰囲気はあるが、これではIndex Patternsなどはexportされない。

結局設定の実体はelasticsearchの.kibanaの下に居るので、elasticsearch-dumpで`localhost:9200/.kibana`をdumpする。リストアはその逆。

# tips

## elasticsearchのindexの状況とか見る
kibanaのDev ToolsのConsoleとかで

    GET _cat/indices

## kibanaでアンダーバー始まりのフィールド使えない

デフォルトだと、アンダーバーから始まるフィールドは、indexとして使えない。

なので、kibanaのManagement -> Advanced Settings -> metaFields にそのフィールド名を足すとtimeとして選択できるようになる。

## elasticsearchのGUIツール

結局使ってない

https://github.com/mobz/elasticsearch-head

    git clone git://github.com/mobz/elasticsearch-head.git
    cd elasticsearch-head
    npm install
    npm run start