FluentdでログをS3に保存させようとしたが失敗する


WEBに転がっている記事や公式を元に、EC2に吐かれるログをFluentd→S3という形で保存させようとしたときにめちゃくちゃハマってしまった。

いまいま考えてみれば初歩の初歩だったりして余計に悲しくなるというエンジニアあるあるですが、同じようにハマッている人は以下のことを再確認してみてください。

環境

エラー内容

まず私の環境で発生したエラーログです。UIで確認してます。
再起動ループが発生していたのか、以下のエラーが一生出ているって感じでした。

画像のエラー内容

2017-05-26 11:00:23 +0900 [error]: unexpected error error_class=RuntimeError error=#<RuntimeError: can't call S3 API. Please check your aws_key_id / aws_sec_key or s3_region configuration. error = #<Seahorse::Client::NetworkingError: unable to connect to `logmylog.s3.s3.xxxx.amazonaws.com.amazonaws.com`; SocketError: getaddrinfo: Name or service not known>>
2017-05-26 11:00:20 +0900 [error]: fluentd main process died unexpectedly. restarting.

そのときのconfig

/etc/td-agent/td-agent.conf
~省略、以下末尾~
<source>
  @type tail
  format apache2
  path /var/log/httpd/access_log
  pos_file /var/log/td-agent/apache2.access_log.pos
  tag s3.apache.access
</source>

<match s3.*.*>
  type s3
  aws_key_id xxxxxxxxxx
  aws_sec_key xxxxxxxxxxxxxx
  s3_bucket logmylog
  s3_region s3.xxxxx.amazonaws.com
  format out_file
  include_time_key false
  store_as gzip
  use_ssl true
  buffer_type memory
</match>

エラーログに吐かれているファイルを確認しても、原因はわからず。
configを変更するだけでなく、インスタンスを一度作り直すとかまでしても結局同じでがっつりハマっていました。

うまくいったconfig

結論です。以下がエラーを解消したconfigになります。

/etc/td-agent/td-agent.conf
<source>
  @type tail
  format apache2
  path /var/log/httpd/access_log
  pos_file /var/log/td-agent/apache2.access_log.pos
  tag s3.apache.access
</source>

<match s3.*.*>
  type s3
  s3_bucket logmylog
  s3_region xxxxx
  format out_file
  include_time_key false
  store_as gzip
  use_ssl true
  buffer_type memory
</match>

確認事項

リージョンとエンドポイント

解消した経緯ですが、エラーログのタイトルを今一度確認し素直に従ってみることに。

Please check your aws_key_id / aws_sec_key or s3_region configuration.

何度確認してもエンドポイントはあっている・・・。
ちなみにアクセスキーとシークレットキーも間違っていないことを確認しました。

しかし、ひとつ思い込みがありました。
このドキュメントはS3のものであってFluentdではありません。

ということでFluentdの公式を再確認。

<match pattern>
  @type s3

  aws_key_id YOUR_AWS_KEY_ID
  aws_sec_key YOUR_AWS_SECRET_KEY
  s3_bucket YOUR_S3_BUCKET_NAME
  s3_region ap-northeast-1
  path logs/
  buffer_path /var/log/fluent/s3

  time_slice_format %Y%m%d%H
  time_slice_wait 10m
  utc

  buffer_chunk_limit 256m
</match>

エンドポイント指定じゃない!!
リージョン指定??
s3_endpointという記述を、このconfigを書く前に記述していたのですが、公式に非推奨とあったので消しました。多分その名残りでリージョン指定場所にエンドポイントを記述していた可能性があります。

なのでまずは基本のキホンですがこういった勘違いがないか確認しましょう(泣)

Keyの記述

Fluentdの公式にもある通りアクセスキーとシークレットキーの例が記載されています。当然私のconfigにも記述していたのですが、エラーログのタイトルにはこいつらもあってるかチェックしろとあります。
なので、いっそ記述をコメントアウトしてやりました。

すると、なぜかエラーが解消される事態・・・。
いや、万々歳なんですけど意味がわからず気持ち悪い。

ちなみにEC2に対してはIAMロールでS3FullAccessを付与しています。
なので理論上はアクセスキー等がなくてもS3への操作は可能です。

このあたりはまた調査します。
何か有力情報をお持ちの方はよろしくお願いします!(T 3 T)