まちいろエンジニアブログ

南池袋のWebサービス開発会社、株式会社まちいろのエンジニアブログです。

Amazon Kinesis Firehose + Elasticsearch + fluentd でログ収集を試してみる

AWS Summit でのアナウンス通り、本日から Amazon Kinesis Firehose が東京リージョンで利用可能となりました。

Amazon Kinesis Firehose is now available in Asia Pacific (Tokyo), EU (Frankfurt), and US East (Ohio) regions

さっそく Firehose を使いながら、Elasticsearch を組み合わせたログ収集構成を試してみたいと思います。

前提

Firehose ストリームの作成

まずは Amazon Kinesis のページから、[Firehose コンソールに移動] ボタンをクリック。

f:id:mkudo-machiiro:20170825173728p:plain

続けて [Create Delivery Stream] ボタンをクリック。

f:id:mkudo-machiiro:20170825173744p:plain

[Delivery stream name] に好きな名前を入力、[Choose source] は Direct PUT or other sources を選択します。

f:id:mkudo-machiiro:20170825173757p:plain

Firehose では Lambda でストリームに流れレコードを加工したりできます。今回は Lambda を使わないので Disabled を選択します。

f:id:mkudo-machiiro:20170825173819p:plain

[Destination] は Amazon Elasticsearch Service を選択します。すると、ES のドメインやインデックスに関する設定が出てきますので、各項目入力していきます。

なお、[Index rotation] の設定に応じて、インデックス名のサフィックスが自動的に付与されます。 例えば [Index rotation] に Every day を選択すると、実際に作成されるインデックス名は インデックス名-YYYY-MM-DD という形式となります。

f:id:mkudo-machiiro:20170825173849p:plain

[S3 Backup] で All records を選択することで、全てのログが S3 にバックアップされます。 続けて転送先となる S3 バケット名、プレフィックスを指定していきます。

S3 に転送される際、{プレフィックス名}YYYY/MM/DD/HH という形式でフォルダが自動的に作成されます。そのため、プレフィックス名でフォルダを切りたい場合は末尾にスラッシュ (/) を入れておくと良いです。

f:id:mkudo-machiiro:20170825174233p:plain

次に転送時のバッファリングの設定を行います。通常はデフォルトのままで問題ないですが、必要に応じてチューニングしましょう。

最後に IAM ロールを作成または選択して完了です。

f:id:mkudo-machiiro:20170825173939p:plain

fluentd で Firehose に転送する

ログの転送に fluentd を使います。まずは td-agent と firehose 用のプラグインをインストールします。

fluent-plugin-kinesis-firehose というプラグインもありますが、現在は非推奨のようなのでご注意ください。

$ curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh
$ td-agent-gem install fluent-plugin-kinesis
$ chkconfig td-agent on

次に td-agent の設定を行います。

<source>
  @type tail
  path /path/to/path/access.log
  pos_file /tmp/access.log.pos
  format json
  time_format %Y-%m-%dT%H:%M:%S%z
  time_key time
</source>

<match **>
  @type kinesis_firehose

  region ap-northeast-1
  delivery_stream_name firehose_stream_name
  flush_interval 1s
  include_time_key true
</match>

最後に td-agent を起動して完了です。設定に問題がなければ、S3 にファイルが転送され、ES にドキュメントが追加されていきます。

$ service td-agent start

Firehose コンソールからもグラフで確認できます。

f:id:mkudo-machiiro:20170825174628p:plain

S3 に転送されるファイルについて

Firehose から S3 への転送量削減のため、転送時に gzip 等に圧縮させる事が可能ですが、このファイルを S3 からダウンロードすると中身が展開された状態で落ちてきます。ダウンロードファイル名は *.gz のままなので、なぜか解凍できないと変なところでハマりました。。

Ruby/Padrino/MySQL 5.7 プロジェクトをCircleCI 2.0 に移行してみた

こんにちは、まちいろの工藤です。

まちいろでは CI に CircleCI を利用していますが、先日ついに CircleCI の 2.0 が正式リリースされましたね。 まだ 2.0 に対応していなかったので、既存のプロジェクトを 2.0 に対応させてみました。

circleci.com

対象プロジェクトの技術スタック

対象プロジェクトは Ruby/Padrino で書かれた至って普通の Web アプリケーションって感じです。

移行手順

CircleCI 2.0 への移行は、2.0 用の設定ファイルを push するだけです。

2.0 から、設定ファイルが circle.yml から .circleci/config.yml に変更されています。 Circle CI のサイトから既存のリポジトリを選択すると config.yml の雛形が出てくるので、そちらを参考にすると良いかと思います。

以下、最終的にできあがった config.yml です。

version: 2

jobs:
  build:
    working_directory: ~/repo
    docker:
      - image: circleci/ruby:2.4.1-node-browsers
        environment:
          DB_HOST: 127.0.0.1
      - image: mysql:5.7
        command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_bin --innodb-large-prefix=true --innodb-file-format=Barracuda
        environment:
          MYSQL_USER: foo
          MYSQL_PASSWORD: foo
          MYSQL_DATABASE: foo
          MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
          MYSQL_ROOT_HOST: '%'
    steps:
      - checkout

      - run:
          name: install dockerize
          command: wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && tar -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
          environment:
            DOCKERIZE_VERSION: v0.5.0

      - run:
          name: Wait for db
          command: ./dockerize -wait tcp://localhost:3306 -timeout 1m

      # Download and cache dependencies
      - restore_cache:
          keys:
          - foo-vendor-bundle-{{ checksum "Gemfile.lock" }}
          # fallback to using the latest cache if no exact match is found
          - foo-vendor-bundle-

      - run:
          name: bundle install
          command: bundle install --jobs=4 --path vendor/bundle

      - save_cache:
          key: foo-vendor-bundle-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle

      # Database setup
      - run:
          name: init db
          command: RACK_ENV=test DB_YAML=tools/circleci/database.yml bundle exec rake db:initdb

      # run tests!
      - run:
          name: rspec
          command: RACK_ENV=test DB_YAML=tools/circleci/database.yml bundle exec rake spec

移行時のポイント

  • MySQL コンテナの環境変数 MYSQL_ROOT_HOST を指定して、テストを実行するコンテナから疎通可能とする
  • dockerize を利用して、MySQL が起動した後にテストが実行されるようにする
  • restore_cache/save_cache を利用して、bundle install の結果をキャッシュして高速化
  • Padrino の場合、DB 設定を config/database.rb に記述するため、DB_YAML に database.yml のパスを渡したらそちらの設定を適用するようコードを修正

移行した結果

CircleCI 2.0 に移行したら、テストの実行時間が半分以下まで減りました :)

コード解析・フォーマットツールを導入しよう

こんにちは、まちいろの工藤です。

まちいろでは言語毎にコード解析・フォーマットツールを導入しています。 弊社メンバーがよく使っているエディタ「Atom」のプラグインと合わせて、いくつか紹介したいと思います。

Ruby

Ruby には RuboCop という Ruby コード静的解析ツールがあります。 コーディングルールは .rubocop.yml に記述していきます。

github.com

RuboCop には、実行時にコーディング規約に準拠する形にコードを修正する autocorrect 機能があります。 例えば文字列は基本シングルクォーテーションで囲む、という規約だった場合、 ダブルクォーテーションで囲まれている部分を自動でシングルクォーテーションに修正します。

autocorrect を有効にするには、実行時に -a オプションを付与します。

$ rubocop -a

...

nn files inspected, nn offenses detected, nn offenses corrected

Atom から実行するには、linter-rubocop プラグインを導入します。 また、rubocop-auto-correct プラグインを導入すると、ファイル保存時に autocorrect を行うことができて便利です。 Golang の gofmt を使っている感覚でコーディングできます。

JavaScript

JavaScript でのコード解析は ESLint が有名です。 コーディングルールは .eslintrc に記述していきます。

eslint.org

ESLint にも autofix という自動修正のオプションがあります。 Atom では、linter-eslint プラグインを導入すると、コード解析だけでなくファイル保存時のフォーマットも行うことができます。

また、最近 (?) Prettier というコードフォーマッタが話題です。 既に Star の数が ESLint を超えてますね。。

github.com

こちらは Golang における gofmt 的な役割で、コードフォーマットに特化しています。 既に ESLint を導入している場合は、https://github.com/prettier/prettier-eslint を利用することで、.eslintrc の設定内容を元にフォーマットすることができます。

Atomprettier-atom プラグインを導入すると、ファイル保存時にフォーマットを実行することが可能です。

CSS

CSS では stylefmt (以前は cssfmt という名称だったようです) というコードフォーマッタがあります。 Stylelint との連携も可能なようですが、まちいろでは stylefmt のデフォルトルールで利用しています。

https://github.com/morishitter/stylefmt

Atomatom-stylefmt プラグインを導入すると、ファイル保存時にフォーマットを実行することが可能です。 ただし最新バージョンでは、language-postcss プラグインを導入しているとうまく動きませんでした。

最後に

いかがでしたでしょうか。

コードレビューを実施している現場は多いと思いますが、レビューの際にインデントや括弧の位置など、本質的ではないところを指摘するのは無駄なので、こういったツールを導入して自然にルールに準拠できるようにしていくと良いと思います。