ELK Stack (Elasticsearch, Logstash, Kibana) で ELB のログを分析する

Posted on

最近、改めて Elasticsearch をちゃんと学び直しています。ちょうど個人事業の仕事で S3 に溜まった ELB のログを分析したいという要望があったので、ELK Stack を使って分析してみることにしました。

試した環境は次のとおりです。

  • Elasticsearch 6.2.4
  • Logstash 6.2.4
  • Kibana 6.2.4
  • Docker Engine 18.03.1-ce

Docker Compose で ELK Stack を立ち上げる

Elastic 社の各プロダクトは公式の Docker イメージが用意されています。今回はこの Docker イメージを使って macOS 上に環境を作りました。

このページに載っている Docker イメージには X-Pack がプリインストールされています。ローカルで使う分には必要ないので OSS のみで構成された Docker イメージを使います。 OSS 版の URL は次のようになります。

docker.elastic.co/elasticsearch/elasticsearch-oss:6.2.4
docker.elastic.co/logstash/logstash-oss:6.2.4
docker.elastic.co/kibana/kibana-oss:6.2.4

Elasticsearch, Logstash, Kibana を個別に立ち上げるのは面倒なので Docker Compose を使ってまとめて立ち上げます。

version: "3"
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.2.4
    container_name: elasticsearch
    environment:
      discovery.type: single-node
    ports:
      - "9200:9200"
      - "9300:9300"
    volumes:
      - es_data:/usr/share/elasticsearch/data

  logstash:
    image: docker.elastic.co/logstash/logstash-oss:6.2.4
    container_name: logstash
    volumes:
      - ./pipeline:/usr/share/logstash/pipeline
      - ./log:/var/log
    depends_on:
      - elasticsearch

  kibana:
    image: docker.elastic.co/kibana/kibana-oss:6.2.4
    container_name: kibana
    environment:
      ELASTICSEARCH_URL: http://elasticsearch:9200
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch

volumes:
  es_data:
    driver: local

Logstash の Docker コンテナには macOS 側のカレントパスをマウントして、設定ファイルとログファイルを参照できるようにしました。

Logstash で ELB のログを解析して書き込む

ELB のログは JSON 形式ではないためそのままでは Elasticsearch に書き込めませんが、Logstash を使えばログを解析して Elasticsearch に書き込むパイプラインが簡単に作れます。

./pipeline の下に elb-log.conf というファイル名でパイプラインの設定ファイルを作ります。

input {
    file {
        path => "/var/log/elb/*.log"
        start_position => "beginning"
    }
}

filter {
    grok {
        match => {
            "message" => "%{ELB_ACCESS_LOG}"
        }
    }
    date {
        match => [ "timestamp", "ISO8601" ]
    }
    mutate {
        remove_field => [ "message", "timestamp" ]
    }
}

output {
    elasticsearch {
        hosts => [ "http://elasticsearch:9200" ]
    }
}

Fluentd と同じような仕組みで input → filter → output という流れで処理を定義します。

input で /var/log/elb/*.log のファイルを指定しているので、マウントしてある macOS 側のパスに ./log/elb/*.log を置いてあげれば Logstash のコンテナからも参照できるようになります。

filter が ETL の処理です。 Logstash にはあらかじめ定義されたパターンが登録されているので、ELB のログは Grok filter%{ELB_ACCESS_LOG} と指定すればいい感じにパースしてくれます。

output は Docker Compose で立ち上げた Elasticsearch を指定します。

ELK Stack を起動する

ここまで準備できれば docker-compose up で起動するだけです。 Elasticsearch と Kibana が立ち上がり Logstash がログを待ち受けています。

あとは AWS CLI などで ./log/elb にログをダウンロードすれば逐次処理してくれます。ちなみに、Logstash はそこそこリソースを使うので、Docker に割り当てるリソースを増やしておいたほうがいいです。

また localhost:5601 にアクセスすれば Kibana で分析できます。

まとめ

Docker Compose で ELK Stack を立ち上げて ELB のログを分析する方法でした。

数百 MB 程度のログファイルならローカルの ELK Stack でも十分に処理できます。実データを使って Elasticsearch を勉強するにはちょうどいいのではないでしょうか。