tjinjin's blog

インフラ要素多めの個人メモ

アプリケーションのログをfluentdを使ってkinesisに入れてlogstashを使ってデータを取得してfileに書き込む~検証編

About

ログをこれまでfluentdのaggregatorからcloudwatch logsに投げるということをやっていたんですが、cloudwatch logsがつまる?のと、料金が高いなーと思っているのでkinesis中心のログ基盤できないかなーと試してみました。

やったこと

文字で書くとこんな感じです。

  • fluentd-catを使って簡易的なログをfluentdに投げます
  • fluentdがjsonを受け取ってそれをfluent-plugin-kinesisを使ってkinesisに投げます
  • logstashがkinesisからデータを取得して、それをファイルに書き込みます

全体の構造

.
├── Gemfile
├── Gemfile.lock
├── docker-compose.yml
├── fluentd-forwarder
│   ├── Dockerfile
│   └── forwarder.conf
├── kinesis.sh # kinesisの状態確認用の簡易スクリプト
├── log
│   └── aaa.log # 出力テスト用
├── logstash
│   ├── Dockerfile
│   └── pipeline
│       └── logstash.conf
└── memo.md

4 directories, 11 files

kinesisのstreamを作る

$ aws kinesis create-stream --stream-name log --shard-count 1

fluentdの設定を用意する

fluent-plugin-kinesisを導入したイメージを用意します。

github.com

# Dockerfile
FROM fluent/fluentd:v0.14.25

RUN gem install fluent-plugin-kinesis

ADD *.conf /fluentd/etc/
<source>
  @type forward
  port 24224
  bind 0.0.0.0
</source>

<match docker.**>
  @type kinesis_streams
  region ap-northeast-1

  stream_name log
</match>

kinesisにログが入るか動作確認をしておきます(ローカルにインストールしたfluentdを使って確認しています)

$ bundle exec fluentd -c fluentd-forwarder/forwarder.conf -vv
$ echo '{"message":"tjinjin-test"}' | fluent-cat docker.app.info

うまく行っているとkinesisからデータが取得できます。

shard=$(aws kinesis get-shard-iterator --shard-id shardId-000000000000 --shard-iterator-type TRIM_HORIZON --stream-name log --query 'ShardIterator')
aws kinesis get-records --shard-iterator $shard | jq -r '.Records[] | .Data' | base64 --decode

logstashの設定を用意する

そもそもlogstashとは何なのかというと、データの取り込み、変換、送信が一括でできるツールのようです(私も今回実際に試したのは初めてです)。いわゆるELKスタックのLですね。

www.elastic.co

kinesisからデータを取得するためのlogstash pluginがあるので用意します。

github.com

# Dockerfile
FROM docker.elastic.co/logstash/logstash-oss:6.1.2
RUN logstash-plugin install logstash-input-kinesis
ADD pipeline/ /usr/share/logstash/pipeline/

設定ファイルは下記のようにしました。

input {
  kinesis {
    kinesis_stream_name => "log"
    codec => json { }
    region => "ap-northeast-1"
  }
}

output {
  file {
    path => "/tmp/log/aaa.log" 
    codec => "json"
  }
}

これでlogstashコンテナの準備は完了です。

docker-compose.ymlを作る

version: '3'
services:
  fluentd-forwarder:
    build: ./fluentd-forwarder
    ports:
      - 24224:24224
    environment:
      - FLUENTD_CONF=forwarder.conf
      - AWS_ACCESS_KEY_ID=hogehoge
      - AWS_SECRET_ACCESS_KEY=hogehoge
  logstash:
    build: ./logstash
    environment:
      - AWS_ACCESS_KEY_ID=hogehoge
      - AWS_SECRET_ACCESS_KEY=hogehoge

検証のため雑に作っています。実際にECSで動かすとしたらInstanceProfile経由でcredential情報を取ることになりそう。

動かす

動かし方は簡単でdocker-compose upをすると各コンテナが起動するので、起動したらfluent-catを使ってログを流してみます!

$ echo '{"message":"tjinjin-test2"}' | fluent-cat docker.app.info
$ cat log/aaa.log
{"message":"tjinjin-test2","@version":"1","@timestamp":"2018-01-22T15:51:24.428Z"}

ということで一応一通りできました。

注意

logstash-input-kinesisはどうやらKCLを内部的に使っているようで、DynamoDBでstreamの管理をしているようです。KCL周りも抑えておかねば…!

まとめ

とりあえず動かして見た感じなので、それぞれのコンポーネントにおいて見極めてよさげだったら導入したいかなー?って感じです。logstashの設定を追加していけば投げ先は増やせるので便利そうかなと思っています!