みなさん、お久しぶりです。
ELKスタック構築
前準備
ELKをインストールする為に、HomebrewとJAVA JDKが必要となります。インストールされていない方は先に入れておいてください。
Homebrew
自分の作業するパスの下に
$ mkdir homebrew && curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew
Java SDK
Oracleの**Java SE Downloads**に参考してください。
念のためJDK 8にしました。
ELK
ELKとは
ELKスタックとはElasticsearch社のElasticsearch(解析) + Logstash(収集) + Kibana(可視化)の3つの製品の総称です。
(実際に動く際に、LEKのフローで動いてますが)
Elasticsearch
Elasticsearch は Elastic 社が開発しているオープンソースの全文検索エンジンです。
大量のドキュメントから目的の単語を含むドキュメントを高速に抽出することができます。
Elasticsearch はリレーショナルデータベースではないため、SQL文 は使用できません。
代わりに RESTful インターフェースを使って操作します。
今回はElasticsearch 6.2.4を使用します。
インストール
$ brew install elasticsearch
ホストを設定する
まずは、elasticsearch.ymlを見つかります。
$ brew info elasticssearch
でこのような情報が出てくると思います。
...(Blah Blah Blah)...
Data:    /usr/local/var/lib/elasticsearch/elasticsearch_JP23417/
Logs:    /usr/local/var/log/elasticsearch/elasticsearch_JP23417.log
Plugins: /usr/local/var/elasticsearch/plugins/
Config:  /usr/local/etc/elasticsearch/
...(Blah Blah Blah)...
elasticsearch.ymlは、Configに書いてあるパスの下にあります。
それを開いて、network.hostを実際に使うIPアドレスに変更してください。今回はローカル環境に構築するので、コメントを外してこう設定しました。
network.host: localhost
動作確認
brew services elasticsearch startでElasticsearchを起動する。
Elasticsearchはデフォルトで9200番ポートで動いていますので、http://localhost:9200 にアクセスすると、このような情報が表示されます。
{
  "name" : "ry1EXQC",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "ZMYVLV-eR-G5hBrQ6QmSGA",
  "version" : {
    "number" : "6.2.4",
    "build_hash" : "ccec39f",
    "build_date" : "2018-04-12T20:37:28.497551Z",
    "build_snapshot" : false,
    "lucene_version" : "7.2.1",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}
Logstash
Logstashは、オープンソースのサーバーサイドデータ処理パイプラインです。膨大な数のソースから同時にデータを取り込み、変換して、お好みの格納庫(スタッシュ)に送信します。お勧めのスタッシュは、もちろんElasticsearchです。
今回はLogstash 6.2.4を使用します。
インストールと起動
$ brew install logstash
$ brew services start logstash
Logstashは実はコンフィグに連動して動いてます。各シーンに違うコンフィグを配置する必要があります。とりあえずこれでKibanaを動けるはずなので、詳しくはあとで説明します。
Kibana
KibanaはElasticsearchのデータを簡単に可視化するツールです。
今回はKibana 6.2.4を使用します。
インストール
$ brew install kibana
ポートとElasticsearchを設定する
まずは、kibana.ymlを見つかります。
$ brew info kibana
でこのような情報が出てくると思います。
...(Blah Blah Blah)...
Config: /usr/local/etc/kibana/
...(Blah Blah Blah)...
kibana.ymlは、Configに書いてあるパスの下にあります。
それを開いて、server.portとelasticsearch.urlを実際に使うものに変更してください。今回はデフォルトの設定のままでこう設定しました。
...(Blah Blah Blah)...
server.port: 5601 
...(Blah Blah Blah)...
elasticsearch.url: "http://localhost:9200”
...(Blah Blah Blah)...
確認
これできたら、http://localhost:5601/status から確認できるはずです。
このような画面出てきます。

JAVAによるログ出力(log4j2)
今回はTCPによって、ログをElasticsearchに送信するツールを作ります。
Mavenプロジェクトを作成
どっかのIDEでMavenプロジェクトを自動生成するのがあると思いますが、ぜひそれを使ってください。
だいたいこういう形で生成すれば問題ないです。ご参考まで。

今回のパッケージ名はlog4j2.localです(実はなんでもいいです)。
Mavenのライブラリ配置
つまりpom.xmlの中身ってことですね。
dependenciesタグに以下のように追加してください。
<dependencies>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>
</dependencies>
Log4j2の配置
つまりlog4j2.xmlの中身のことです。Log4j2はこれに従って、ログの送信先を決まります。
今回はもちろんLogstash経由でElasticsearchに送信しますが、Debugしやすさも考慮すると一応Consoleにも出力する形にしておきました。
<configuration status="OFF">
    <appenders>
        <Socket name="Logstash" host="localhost" port="9601" protocol="TCP">
            <PatternLayout pattern="%d|%t|%p|%c|%L|%m%n" />
        </Socket>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d|%t|%p|%c|%L|%m%n" />
        </Console>
    </appenders>
    <loggers>
        <root level="all">
            <AppenderRef ref="Logstash"/>
            <appender-ref ref="Console"/>
        </root>
    </loggers>
</configuration>
個性化したい方は**このページ**に参考してください。
Mainクラス
ログを出力する挙動です。
package log4j2.local;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
public class Main {
    private static Logger logger = LogManager.getLogger("test");
    public static void main(String[] args) {
        logger.error("エラーメッセージです");
    }
}
これを実行すると、Consoleにはこのようなログが出てきます。
(Logstashにはまだ繋いでないので、もちろんElasticsearchにも保存されません。)
2018-09-12 12:55:13,962|main|ERROR|test|13|エラーメッセージです
Logstashを配置
Logstashコンフィグ
好きなパスで大丈夫で、logstash-tcp.confを作りましょう。(tcp通信なのでこの名前にしただけです。)
Logstashはデフォルトで9600~9700のポート全部使えるので、今回は9601番ポートを使います。(必ずlog4j2.xmlの<Socket>タグと同じポートにしてください。)
input {
    tcp {
        host => "localhost"
        port => "9601"
        mode => "server"
        type => "eslocallogger"
    }
}
filter {
    mutate{
        split => ["message","|"]
        add_field =>   {
            "Datetime" => "%{[message][0]}"
        }
        add_field =>   {
            "Classname" => "%{[message][1]}"
        }
        add_field =>   {
            "Level" => "%{[message][2]}"
        }
        add_field =>   {
            "Logger" => "%{[message][3]}"
        }
        add_field =>   {
            "Message" => "%{[message][5]}"
        }
    }
}
output {
    stdout {
        codec => rubydebug
    }
    elasticsearch {
        hosts => "localhost:9200"
    }
}
ここではSchemaを分けるためにFilterを使いましたが、使わなくてもデフォルトのカラムは自動的にパースされます。
(ここでは、Logstashに入ってきたエラーメッセージを|で区きりします。)
Logstashをコンフィグに連結して再起動
$ brew services stop logstash
$ logstash -f ./logstash-tcp.conf --experimental-java-execution
--experimental-java-executionのフラグがあると、JAVAのエンジンで走ります。
詳しくは**Meet the New Logstash Java Execution Engine**からご覧ください。確かそうした方がスループットが大分上がります。
実行してみよう
Console
2018-09-12 18:05:39,737|main|ERROR|test|13|エラーメッセージです
Logstash Console
[2018-09-12T18:05:40,464][DEBUG][logstash.pipeline        ] Pushing flush onto pipeline {:pipeline_id=>"main", :thread=>"#<Thread:0x5caa3237 sleep>"}
{
         "Level" => "ERROR",
    "@timestamp" => 2018-09-12T09:05:39.847Z,
        "Logger" => "test",
          "port" => 60614,
       "message" => [
        [0] "2018-09-12 18:05:39,737",
        [1] "main",
        [2] "ERROR",
        [3] "test",
        [4] "13",
        [5] "エラーメッセージです"
    ],
          "type" => "eslocallogger",
       "Message" => "エラーメッセージです",
      "Datetime" => "2018-09-12 18:05:39,737",
          "host" => "localhost",
      "@version" => "1",
     "Classname" => "main"
}
Kibana
KibanaのManagement画面に行ってリロードすると、このような画面が出てくるはずです。

Next stepに行って、filterを@timestampにしてCreate index patternをクリックすると、インデックスの可視化を始めます。

Discover画面に入ったら、時間軸のデータを見れます。

詳しくは**Kibanaの使い方**に参考してください。
参考元
Installing the ELK Stack on Mac OS X
ElasticSearch+Logstash+Kibana+log4j2 官方6.1.1版安装配置简介
LogStash的Filter的使用
Elastic Stack