Fluentd経由でAWSのクラスに怒られた時の対処方


すごいゆるふわなタイトルですがマジでなんか怒られたので書いときます。

 * fluentd fails to start because "uninitialized constant Fluent::S3Output::AWS"

## 事の始まり

ログをS3にあげたかったんです。

するとFluentdをインストールするときにAmazon LinuxだったりCentOSだったりすると大体以下みたいなChefのレシピ書くとおもいます。

```ruby
## td.repoの設置
cookbook_file '/etc/yum.repos.d/td.repo' do
	mode 0644
end

## Fluentdのインストール
package "td-agent" do
  action :install
end

## 設定ファイルのインストール
cookbook_file '/etc/td-agent/td-agent.conf' do
	mode 0644
end

## モジュールのインストール
execute "install fluent-plugin-forest" do
  command "/usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-forest"
  creates "/tmp/.fluentd_plugin_install"
  action :run
end

## デーモンの起動とサーバ起動時に開始するように設定
service "td-agent" do
  action [:enable,:start]
end
```

要するにRPMから入れようって話ですね。さらにfluent-gem経由でfluent-plugin-s3を入れると上のエラーが発生しました。

## 原因究明

もちっと深くおっていくと「/usr/lib64/fluent/ruby/lib/ruby/gems/1.9.1/gems/fluent-plugin-s3-0.5.4/lib/fluent/plugin/out_s3.rb」の82行目とかで止まってるみたいでした。

そこを追うと

```ruby
@s3 = AWS::S3.new(options)
```

とあるだけなのでどうも新しいS3のオブジェクト作る段階で失敗しているみたいなんですよね。ちなみに設定ファイルのS3の設定はもんだいなさげでした。

エラーログもはいている様子もないのでどうしようもない感じです。

## やったこと

とりあえずRPM版は諦めました。

```bash
yum remove td-agent
```

このあとソースからRubyをいれて、GemからFluentdの最新版をインストール。

```bash
gem install fluentd
gem install fluent-plugin-s3
```

このままだとRPM時代に使われていたスクリプトがなくなるので、某所にあったのを持ってきて改造しました。

```bash
#!/bin/bash

PID_FILE=/var/run/fluentd.pid
CONF_FILE=/etc/fluentd/fluentd.conf
LOG_FILE=/var/log/fluentd/fluentd.log
PSNAME="fluentd --daemon"
F_USER=fluentd
F_GROUP=fluentd

start()
{
  PID=`pgrep -f "$PSNAME"`
  if [ -z "$PID" ]; then
    if [ -f $PID_FILE ]; then rm -f $PID_FILE; fi
  else
    echo "fluentd already started."
    return -1
  fi
  echo -n "Starting fluentd: "
  fluentd --daemon $PID_FILE --user $F_USER --group $F_GROUP --config $CONF_FILE --log $LOG_FILE -vv
  echo "done."
}

stop()
{
  PID=`pgrep -f "$PSNAME"`
  if [ -z "$PID" ]; then
    echo "fluentd already stopped."
    return 0
  fi
  echo -n "Stopping fluentd: "
  pkill -TERM -f "$PSNAME"
  count=0
  while [ ! -z "$PID" ]; do
    count=`expr $count + 1`
    if [ `expr $count % 10` == 0 ]; then pkill -KILL -f "$PSNAME"; fi
    if [ $count == 60 ]; then
      echo " failed."
      return -1
    fi
    sleep 1
    PID=`pgrep -f "$PSNAME"`
  done
  rm -f $PID_FILE
  echo "done."
}

restart()
{
  stop && start
}

update()
{
  gem update fluentd
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    restart
    ;;
  reload)
    pkill -HUP -f "$PSNAME"
    ;;
  condrestart)
    if [ ! -f $PID_FILE ]; then
      restart
    elif [ ! -f /proc/`cat $PID_FILE`/status ]; then
      restart
    fi
    ;;
  update)
    stop
    update
    start
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|reload}"
    exit 1
    ;;
esac
exit $?
```

もちろんこのままだと動かないので以下の設定をしてやります。

```bash
useradd fluentd
mkdir /varlog/fluentd
chown fluentd:fluentd /var/log/fluentd 
chmod +x /etc/init.d/fluentd
```

準備オッケーです。起動します。

```bash
/etc/init.d/fluentd start

Starting fluentd: done.
```

起動したらオッケーです。

##　ログを見る（Fluentdの）

本体のログをみてみましょう。

```bash
2015-02-18 09:40:35 +0000 [info]: fluent/root_agent.rb:142:add_source: adding source type="http"
2015-02-18 09:40:36 +0000 [debug]: plugin/in_http.rb:85:start: listening http on 0.0.0.0:8889
```
httpの8889で待ち受けるように設定をしてみたのでこんな感じで終わってればオッケーです。

次は流してみます。

```bash
curl -X POST -d 'json={"json":"testtest"}' http://0.0.0.0:8889/[tagname]
```

tagがマッチしていれば/var/log/fluentd/bufferの下にログバッファが作成されているはずです。

## 結論

迷ったら最新版。以上！！！！！！！

## 追記

gemfluent-plugin-forestいれてあげたほうがいいみたいです。

```bash
gem install fluent-plugin-forest
```

設定がs3_endpointからs3_regionに変わったぽいすね。

```config
s3_region ap-northeast-1
```