AWS
fluentd
Elasticsearch
AmazonElasticsearchService

fluent-plugin-aws-elasticsearch-service 導入時にハマった箇所

More than 1 year has passed since last update.

fluent-plugin-aws-elasticsearch-service

https://github.com/atomita/fluent-plugin-aws-elasticsearch-service

元となっている fluent-plugin-elasticsearch は、Elasticsearch への転送はできるが、
Amazon ES の API 署名(※)ができず、アクセス制限に対応できない。

※ AWS API に HTTP アクセスする際に、リクエストににょろにょろと情報をつけることで IAM 権限を利用したアクセスをできるようにする手法
※ Amazon ES のアクセス制限は IP, AWS Account でかけられるが、アクセスできるエンドポイントが URI だけなので EC2 に IAM Role をつけるだけではアクセスできない

インストール

fluent-gem でインストールするだけ

bash
$ /path/to/fluent-gem install fluent-plugin-aws-elasticsearch-service

ちなみに、fluent-gem/path/to/td-agent-root/embedded/bin/ のあたりにあるかと思います。

設定のハマりポイント

Amazon ES の URL を指定するとき最後のスラッシュをつけてはいけない

ここで指摘されていますね

td-agent.conf.sample
   <store>
      type aws-elasticsearch-service
      type_name your_type_name
      logstash_format true
      include_tag_key true
      tag_key @tag_key_name
      flush_interval 10s

      <endpoint>
        ↓ダメなやつ
        url https://search-your-endpoint.ap-northeast-1.es.amazonaws.com/
        ↓ OK なやつ
        url https://search-your-endpoint.ap-northeast-1.es.amazonaws.com

        region ap-northeast-1
      </endpoint>
    </store>
</endpoint>

それぐらいプラグイン側で対処してほしい

Kibana を使おうと思うとIndex のフォーマットが logstash-YYYY.MM.DD に固定される

Amazon ES を使う最たる理由は自分で何もしなくても Kibana が使えることだと思いますが、
Kibana を使うためには fluentd からの送信時に Logstash format で送る必要があります。
そのため、設定ファイルは以下のようになります。

td-agent.conf.sample
    <store>
      type aws-elasticsearch-service
      type_name staging_nginx_access
      logstash_format true ← Logstash format にする必要がある
      include_tag_key true
      tag_key @staging ← tag_key で区別する運用とした
      flush_interval 10s

      <endpoint>
        url https://search-your-endpoint.ap-northeast-1.es.amazonaws.com
        region ap-northeast-1
      </endpoint>
    </store>

この場合元になっている fluent-plugin-elasticsearch の仕様上 index_name のオプションが無効になります(バグじゃないのこれ)
https://github.com/uken/fluent-plugin-elasticsearch/blob/master/lib/fluent/plugin/out_elasticsearch.rb#L152-L170

→ページ下部に解決方法追記しました

直接上記処理を書き換えてしまえばできないこともありませんがそういうことをすると途端にバージョンアップが辛くなるのでやめました。

結局、tag_key を付加することで必要な分類分けを行う運用にしました。
Index を環境名と EC2 のインスタンス ID で分ける方針で運用したかったのですが、この対応でも検索できないことは無いので。
(Index にインスタンス ID が入っていると、複数台の分散処理を行っているときに特定のインスタンスのログだけを負えて便利だなと)

代わりに、Index に日付が入るようになったことで不要な過去ログを削除しやすくなったのではないでしょうか。
なお、IP 制限もしくは API 署名で認証通っていれば Index 削除は以下のようなコマンド(curl で -XDELETE 送るだけ)で簡単に出来ます。
確認もなくあっさり消えるのでお気をつけを。

bash
$ curl -XDELETE https://search-your-endpoint.ap-northeast-1.es.amazonaws.com/index-name-to-delete
{"acknowledged":true}

雑感

AWSLabs が fluetnd-output-amazon_es 出してくれないかなぁ(他人任せ)

Reference

追記(2016.01.19)

元になっている fluent-plugin-elasticsearch ですが、メモリリークの問題が報告されているようです。
実際に、初期 120MB ほどだったメモリ消費量が 500MB を超えていました。
td-agent を再起動すれば直りますが、場当たり的でイケてませんね・・・。

追記 2 (2016.05.10)

この場合元になっている fluent-plugin-elasticsearch の仕様上 index_name のオプションが無効になります(バグじゃないのこれ)

と書きましたが、logstash_prefix というオプションの存在を教えていただきました。
ありがとうございます。こちらを設定したところ無事 Index が変わりました(とても便利)