ApacheのアクセスログをEmbulk+Elasticsearch+Kibanaで見る

[前回](http://qiita.com/segawa/items/3f0aee6aaef6529b3f2e)、 Embulk で MySQL にアクセスログを入れてみましたが、グラフで見れるようにしたいのでやろうやろうと思っていた ElasticSearch+Kibana を試してみます。

Java が必要になるので、インストールしておいてください。
環境は macOs Sierra です。

```console:Javaのバージョン
$ java -version
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
```

# Elasticsearch

[Elasticsearch](https://www.elastic.co/jp/products/elasticsearch)とは、Wikipediaより

>ElasticsearchはLucene基盤の分散処理マルチテナント対応検索エンジンである。オープンソースソフトウェアだが、現在はオランダ・アムステルダムに本社を置くElastic社が中心になって開発が進められている

Javaで記述された全文検索ソフトウェアの Apache Lucene（アパッチ ルシーン）をベースにしているそうです。

## 用語

Elasticseach の用語の理解。

|用語|説明|
|:-----|:-----|
|インデックス|RDMSでのテーブルにあたるもの|
|ドキュメント|RDMSでのレコードにあたるもの|
|ドキュメントタイプ|Elasticsearch では1つのインデックス内に異なる構造のドキュメントを格納できる。ドキュメントタイプはどの構造かを識別するもの|
|マッピング|インデックスの構造の定義|
|フィールド|RDMSでのカラムにあたるもの|


## インストール

Homebrewでインストール可能です。

```console:Elasticsearchのインストール
$ brew install elasticsearch
  :
Data:    /usr/local/var/elasticsearch/elasticsearch_yutasega/
Logs:    /usr/local/var/log/elasticsearch/elasticsearch_yutasega.log
Plugins: /usr/local/Cellar/elasticsearch/5.0.2/libexec/plugins/
Config:  /usr/local/etc/elasticsearch/
plugin script: /usr/local/Cellar/elasticsearch/5.0.2/libexec/bin/plugin

To have launchd start elasticsearch now and restart at login:
  brew services start elasticsearch
Or, if you don't want/need a background service you can just run:
  elasticsearch
  :
```

下記のコマンドを実行するとフォアグラウンドで実行されます。
標準出力にログが出るので、それを見ながらトラブルシューティングしました。

```console:Elasticsearchのインストール
$ elasticsearch
```

起動確認します。
最新の 5.0.2 がインストールされました。

```console:起動確認
$ curl -X GET http://localhost:9200/ 
{
  "name" : "ZYNFZGW",
  "cluster_name" : "elasticsearch_yutasega",
  "cluster_uuid" : "VEGuf46HTfOG0Sl2us8IQg",
  "version" : {
    "number" : "5.0.2",
    "build_hash" : "f6b4951",
    "build_date" : "2016-11-24T10:07:18.101Z",
    "build_snapshot" : false,
    "lucene_version" : "6.2.1"
  },
  "tagline" : "You Know, for Search"
}
```

# Kibana

[Kibana](https://www.elastic.co/jp/products/kibana) は Elasticsearch と同じく elastic社のプロダクトで、Elasticsearch のデータを可視化できます。


## インストール

Kibana のインストールには node.js が必要でした。

### node.js

```console:node.jsのインストール
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | bash
source ~/.bashrc
```


### kibana

[ここ](https://www.elastic.co/guide/en/kibana/5.0/targz.html)に記載されている方法に従ってインストールします。

```console:Kibanaのインストール
$ wget https://artifacts.elastic.co/downloads/kibana/kibana-5.0.2-darwin-x86_64.tar.gz
$ tar -xzf kibana-5.0.2-darwin-x86_64.tar.gz
$ cd kibana/
```

## 起動

Elasticsearch の起動を確認後、別ターミナルで以下を実行します。

```console:Kibanaの実行
$ ./bin/kibana
```

## 確認

ブラウザで下記にアクセスします。

http://localhost:5601/

これでインストールは完了です。

# Embulkの設定変更

## プラグインのインストール

Embulk に Elasticsearch 用のプラグイン（embulk-output-elasticsearch_ruby）を追加します。

```console:プラグインのインストール
$ embulk gem install embulk-output-elasticsearch_ruby
```

## 設定ファイルを変更

outの部分を MySQL のものから Elasticsearch のものに変更します。

```yaml:config.yml
in:
  type: file
  path_prefix: try1/access_log/sample.access_
  decoders:
  - {type: gzip}
  parser: 
    type: apache-custom-log
    format: "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
out:
  type: elasticsearch_ruby
  nodes:
    - {host: localhost, port: 9200}
  index: access_log
  index_type: site_a
```

access_log がインデックス名で、site_a がインデックスタイプにあたります。


# データの流し込み

## Elasticseachにマッピングを登録

マッピング（=インデックスの構造定義）を行います。

```json:mapping.json
{
  "mappings" : {
    "site_a" : {
      "properties" : {
        "remote-host" : { "type" : "string" },
        "remote-log-name" : { "type" : "string" },
        "request-user" : { "type" : "string" },
        "request-time" : { "type" : "date", "format" : "yyyy-MM-dd HH:mm:ss z" },
        "request-line" : { "type" : "string" },
        "response-status" : { "type" : "long" },
        "response-bytes" : { "type" : "long" },
        "request-header-Referer" : { "type" : "string" },
        "request-header-User-Agent" : { "type" : "string" }
      }
    }
  }
}
```

上記のようなマッピング情報をjsonで記述し、

```console:マッピングの登録
$ curl -XPUT 'localhost:9200/access_log' -d @mapping.json
{"acknowledged":true,"shards_acknowledged":true}
```

curlで設定します。 `access_log` はマッピングを登録するインデックス名です。
これで準備完了です。

## Embulkを実行

```ｃｏｎｓｏｌｅ:Embulkを実行
$ embulk run config.yml
```

これでデータの取り込みは完了です。

データが無事取り込まれているかは、以下の URL にアクセスすることで確認できます。

Elasticsearchのデータ確認
http://localhost:9200/access_log/_search?pretty

マッピングの確認は下記で
http://localhost:9200/access_log/_mapping?pretty


マッピングの定義が場違っていた場合は以下のコマンドで削除し再設定可能です。

```console:マッピングの再設定
$ curl -XDELETE 'localhost:9200/access_log'
$ curl -XPUT localhost:9200/access_log -d @mapping.json
```

# Kibanaでグラフを見る

## ManagementでIndexPatternの設定

1. 左カラムの Management > Index Ptterns を選択します
2. Index name or pattern にインデックス名 `access_log` を入力します
3. Time-field name に date 型項目の `request-time` を選択し create

<img width="1064" alt="スクリーンショット 2016-12-09 20.53.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/20940/62a2cd69-3343-0041-fe0c-4c61efbb7b92.png">

## Visualize

1. グラフの種類を選択（忘れてしまった。たしか一番下の棒グラフのやつ）
2. Visualize メニューを選択します
3. Y軸に Count、X軸に `request-time` を選択して、青い再生ボタンみたいなやつを押します。

<img width="1223" alt="スクリーンショット 2016-12-09 21.08.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/20940/f9393bd1-cecd-fee8-8e21-610d07d6650b.png">

Yes！





# ハマった点

- すべて最新版を選択したため、意外と情報が少なかった。

- Embulk が生成する日付に「2016-01-05 15:19:56 UTC」のように「UTC」が入っているのですが、マッピングの Date format でどう書けばいいかわからず一向に取り込めなかった（`z`だった）

- マッピング設定を変えて試していたところ Elasticseach で下記のエラーが出てデータが取り込めなくなった。

```
[2016-12-09T20:36:44,640][DEBUG][o.e.a.a.i.a.TransportIndicesAliasesAction] [ZYNFZGW] failed to perform aliases
org.elasticsearch.indices.InvalidAliasNameException: Invalid alias name [access_log], an index exists with the same name as the alias
```

エイリアスを全て削除したら解消した。
以下のURLにアクセスし、表示されたエイリアスを .kibana以外全て削除した。
http://localhost:9200/_aliases/

```json:エイリアスの一覧
{
  "test-access_log-2016.12.09.20.15.37": {
    "aliases": {}
  },
  "access_log-site_a-2016.12.09.20.36.38": {
    "aliases": {}
  },
  ".kibana": {
    "aliases": {}
  },
  "sample-access_log-2016.12.09.20.09.43": {
    "aliases": {}
  },
  "sample-access_log-2016.12.09.20.07.56": {
    "aliases": {}
  },
  "samplesite-access_log-2016.12.09.20.18.51": {
    "aliases": {}
  },
  "test-access_log-2016.12.09.20.11.41": {
    "aliases": {}
  },
  "access_log": {
    "aliases": {}
  }
}
```

```console:エイリアスの削除
$ curl -XDELETE 'localhost:9200/test-access_log-2016.12.09.20.15.37'
```

- 取り込んだデータが2016年1月のデータで、Kibana の日付フィルタのデフォルトが `Last 15 minutes` なのに気づかずデータが表示されないと小一時間悩みました。