nginxのaccess.logをfluentdでS3に格納するまで

俺俺メモです。

環境

  • EC2 (Amazon Linux AMI 2013.03.1 64bit)
  • nginx 1.2.9(ソースコンパイルはせずにyum install nginxで入れたもの)
  • fluentd 0.10.33(td-agentを利用。s3プラグインは最初から入っていたものをそのまま利用)

※nginxもfluentdも同一EC2インスタンス上で稼働

nginx

ログフォーマットをLTSVに変えました。それだけ。
/etc/nginx/nginx.conf

log_format ltsv "time:$time_iso8601"
                "\thost:$remote_addr"
                "\txff:$http_x_forwarded_for"
                "\tmethod:$request_method"
                "\tpath:$request_uri"
                "\tstatus:$status"
                "\tua:$http_user_agent"
                "\treq_size:$request_length"
                "\treq_time:$request_time"
                "\tres_size:$bytes_sent"
                "\tbody_size:$body_bytes_sent"
                "\tapp_time:$upstream_response_time";

access_log  /var/log/nginx/access.log  ltsv;

fluentd

いきなりS3にアウトプットせずに、まずはファイルにアウトプットする。
/etc/td-agent/td-agent.conf

<source>
  type tail
  path /var/log/nginx/access.log
  tag nginx.access
  pos_file /tmp/td-agent/nginx.pos
  format ltsv
</source>

<match nginx.access>
  type file
  path /var/log/fluent/access_log
  #path /tmp/fluent-test.log
</match>

うまくいったのを確認して、S3にアウトプットする設定に変更。

<source>
  type tail
  path /var/log/nginx/access.log
  tag nginx.access
  pos_file /tmp/td-agent/nginx.pos
  format ltsv
</source>

<match nginx.access>
  type s3

  aws_key_id [アクセスキー]
  aws_sec_key [シークレットキー]
  s3_bucket [バケット名]
  s3_endpoint s3-ap-northeast-1.amazonaws.com
  path logs/
  buffer_path /var/log/fluent/s3

  time_slice_format %Y%m%d-%H
#  time_slice_wait 10m
  flush_interval 5s
  utc 
</match>

アクセスキーとシークレットキーというのがどこから取ってきたらよいのかよく分からなかったので記録。

  1. AWSのトップページにアクセス。
  2. 画面右上の「アカウント/コンソール」から「アカウント」を選択。
  3. 画面左のメニューから「セキュリティ証明書」を選択。
  4. 以下に表示されている「アクセスキーid」と「シークレットアクセスキー(「表示」をクリック)」がそれ。

あとハマったのはバケット名のところ。
既に登録していたS3のバケット名を入れていたのにうまくいっていなかった。
というかエラーメッセージはアクセスキーやシークレットキーがおかしいと言っていたのでなかなか気付けなかった。
以下、エラーメッセージ。

2013-06-22 13:51:11 +0000 [error]: unexpected error error="aws_key_id or aws_sec_key is invalid. Please check your configuration"
2013-06-22 13:51:11 +0000 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluent-plugin-s3-0.3.1/lib/fluent/plugin/out_s3.rb:162:in `rescue in check_apikeys'
2013-06-22 13:51:11 +0000 [error]: /usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluent-plugin-s3-0.3.1/lib/fluent/plugin/out_s3.rb:160:in `check_apikeys'
・・・略・・・

rubyのコードを読んでてなんとなく、バケット名を既存のものではなく存在しないものにしたらどうなるんだろう?と思ってやったら、その場合は新たにバケットを作るようだった。

  def ensure_bucket
    if !@bucket.exists?
      if @auto_create_bucket
        $log.info "Creating bucket #{@s3_bucket} on #{@s3_endpoint}"
        @s3.buckets.create(@s3_bucket)
      else
        raise "The specified bucket does not exist: bucket = #{@s3_bucket}"
      end
    end
  end

/usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluent-plugin-s3-0.3.1/lib/fluent/plugin/out_s3.rb

実際、「Creating bucket.....」のログが出てたわ。
んで、そのようにしたら急にエラーが出なくなって、その新しく作ったバケットにログが出力されるようになりましたとさ。
・・・何が悪かったのか結局よくは分からなかったけど、とにかくこれで動いた。S3に保存された!