SpringBoot のログを elasticserch に送信して kibana で見る為の fluentd (td-agent) の設定

# 本題
## 概要
SpringBoot のログを Elasticsearch に送って Kibana で見たかったが、SpringBoot のログを Elasticsearch に送るための方法がすぐにはわからなかった。fluentd を使って転送できたのでその方法を記す。

- 確認した構成
    - Elastic Stack サーバ
	    - OS: CentOS7 / Elasticsearch: Version 5.0.1 / Kinbana Version: Version 5.0.1
    - SpringBoot サーバ
	    - OS: CentOS7 / SpringBoot: Version1.4.2 / td-agent 0.12.29

## 対象とするログ
```spring.log
（略）
2016-12-09 21:27:13.240  INFO 13404 --- [pool-1-thread-1] com.example.Task                         : 1039443329 is 1039443329
2016-12-09 21:27:13.741 ERROR 13404 --- [pool-1-thread-1] o.s.s.s.TaskUtils$LoggingErrorHandler    : Unexpected error occurred in scheduled task.

java.lang.RuntimeException: FizzBuzz
    at com.example.Task.fizzBuzz(Task.java:21) ~[main/:na]
    at com.example.Task.doTask(Task.java:16) ~[main/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
（略）
```

- 特徴
    - スタックトレースなど複数行にまたがるログがある。

## fluentd の設定
```/etc/td-agent/td-agent.conf
<source>
  type tail
  path /spring/logs/spring.log
  pos_file /var/log/td-agent/spring.log.pos
  tag spring.logtest
  refresh_interval 5s
  format multiline
  format_firstline /\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}\.\d{3}.*---/
  format1 /^(?<time>\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}\.\d{3})\s+(?<level>[^\s]+)\s+(?<process>[^\s]+)\s+---\s+\[(?<thread>[^\s]+)\]\s+(?<class>[^\s]+)\s+:\s+(?<message>.*)/
</source>
<match spring.**>
    type Elasticsearch
    type_name spring_logtest
    host 192.168.33.9
    port 9200

    logstash_format true
    logstash_prefix spring_logtest
    logstash_dateformat %Y%m%d
    include_tag_key true
    tag_key @log_name
    flush_interval 5s
</match>
```

- （入力）tail プラグイン [詳細はこちらで確認してください](http://docs.fluentd.org/articles/in_tail)
    - format multiline 機能を使って複数行のログを１つの情報として扱えるようになる。
        - 完璧な正規表現ではないので誤検知もあり得る
    - format_firstline で１つのログの先頭行を判定するための正規表現
    - format1 でログの各項目に意味づけする   (<フィールド名>データ抽出の正規表現)
- Elasticsearchプラグイン [詳細はこちらで確認してください](https://github.com/uken/fluent-plugin-elasticsearch)
    - host / port : Elasticsearch サーバの host と port

## 結果
+ Elasticsearch と Kibana を設定するとこんな感じで見ることができる
![kibana03resultAll.png](https://qiita-image-store.s3.amazonaws.com/0/71973/a4f4807e-4e11-c09a-a515-08a43ce28abd.png)

## 感想
これが推奨される方法なのだろうか？ SpringBoot も Elasticsearch も Kibana も簡単なんだけど、SpringBoot のログを Elasticsearch に転送するという部分だけこんなにゴリゴリ正規表現書かなくちゃいけないのはスマートではないような気がするので。良い方法あったら教えてください。


# おまけ：確認をした構成を作るまで
## Elastic Stack サーバ のセットアップ
この記事がわかりやすい
[Elastic Stack 5.0.0 GAリリース！ 早速インストール！！ #Elasticsearch"](http://acro-engineer.hatenablog.com/entry/2016/10/27/165342)

- 記事は Amazon Linux を想定していますが CentOSも同じコマンド行けました。
- 本稿に関係あるのは、「ElasticsearchとKibanaのインストール」までで良いです。
- 「Beatsのインストール」までやっても損はないと思う
- 「Logstashのインストール」は本稿の構成の場合は不要

## Spring Boot アプリケーションの準備
- アプリを作るところは省略
- ログをファイル出力するためには application.yml に 以下のように書く

```application.yml
# 以下の設定だと <実行ディレクトリ>/logs/spring.log ができる
logging.file: logs/spring.log
```

## fluentd(td-agent) の準備 ＠ SpringBoot サーバ
- 基本的に [公式](http://docs.fluentd.org/articles/install-by-rpm)の通りインストール。
- fluent-plugin-elasticsearch を使用する
- 以上をコマンドにすると以下。

```
sudo wget -r --no-parent --no-directories -A 'epel-release-*.rpm' http://dl.fedoraproject.org/pub/epel/7/x86_64/e/
curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh
sudo td-agent-gem install fluent-plugin-Elasticsearch
```

- fluentd(td-agent) 再起動
	- 上記の設定ができたらconfファイルを書き換えたので fluentd 再起動する。
```
sudo /etc/init.d/td-agent restart
```
- fluentd(td-agent) の動作確認
Springアプリケーションを起動してログを出力させた後。
```/var/log/td-agent/td-agent.log``` をみて Elasticsearch につながったっぽいログが出たら成功。
![fluentdLog.png](https://qiita-image-store.s3.amazonaws.com/0/71973/5766f44f-edd2-ba31-8798-d5323dcc3537.png)

## Kibanaの設定
+ http://_Elastic stack host_:5601 で Kibana を開く
+ 左のメニュー ＞ Management ＞ Index Patterns ＞ Add New ＞ 「logstash_prefix」で設定した内容を設定
![kibana000indexPatterns.png](https://qiita-image-store.s3.amazonaws.com/0/71973/8c879ec8-31b4-063c-feba-06d1453ed715.png)

![kibana00AddIndex.png](https://qiita-image-store.s3.amazonaws.com/0/71973/1e863da2-8d4a-f075-a4a7-f8d1e3fc60a7.png)

![kibana01createIndex.png](https://qiita-image-store.s3.amazonaws.com/0/71973/d83930d9-9404-db5d-73ae-c2a6bcccd23c.png)

+ さっきの正規表現で書いた項目が Fields に定義されている
![kibana02index.png](https://qiita-image-store.s3.amazonaws.com/0/71973/37f05cff-174d-6035-8c0f-77426bde3ac5.png)

+ Discover を見るとログが来ている
![kibana03resultAll.png](https://qiita-image-store.s3.amazonaws.com/0/71973/a4f4807e-4e11-c09a-a515-08a43ce28abd.png)

+ StackTrace も全部（複数行）来ている
![kibana04resultDetail.png](https://qiita-image-store.s3.amazonaws.com/0/71973/097e743e-420b-88b1-6fda-07a0b5022327.png)

+ Exception で検索すれば問題箇所にすぐにアクセスできる
![kibana05resultException.png](https://qiita-image-store.s3.amazonaws.com/0/71973/a911633f-5283-ef5a-3466-552640774c63.png)