cloudpack の 自称 Sensu芸人 の かっぱこと 川原 洋平@inokara)です。

追記(2014/07/24)

export AWS_REGION=us-east-1 が引き継がれず service コマンドから td-agent が起動出来なくなる件ですが、@repeatedly さんにご指摘頂き /etc/sysconfig/td-agent に export AWS_REGION=us-east-1 を追加することで service コマンドにて td-agent の起動、再起動が出来ることを確認しております。

echo "export AWS_REGION=us-east-1" >> /etc/sysconfig/td-agent
service td-agent start

@repeatedly さん、有難うございました!

はじめに

先週、各インスタンスのログを CloudWatch に収集することが出来る CloudWatch Logs というサービスがリリースされました。CloudWatch Logs に関する情報は下記を御覧ください。

この三記事を抑えておけば貴方も CloudWatch Logs マスターの第一歩を踏み出せるかと思います。

で…

ぼやっと Twitter の Timeline を眺めていたら ryotarai さんが fluent-plugin-cloudwatch-logs という fluentd のプラグインを作成されたのを知ったのでどのようなプラグインなのかを試してみました。

fluent-plugin-cloudwatch-logs とは

fluent-plugin-cloudwatch-logs について…

  • リポジトリ
  • out_cloudwatch_logs(ログを CloudWatch Logs に送る?)
  • in_cloudwatch_logs(ログを CloudWatch Logs から取得する?)

out_cloudwatch_logs と in_cloudwatch_logs をどう使い分けるのかかが個人的にイマイチ理解出来ていません…すいません。

試す環境

試す環境は以下のような環境です。

  • Amazon EC2
  • CentOS 6.5
  • fluentd の代わりに td-agent(td-agent-1.1.20-0.x86_64)
  • fluent-plugin-cloudwatch-logs

というシンプルな構成です。

IAM の設定とインスタンス起動

IAM にて以下のようなロールを設定してインスタンス起動時に適用します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:*",
        "s3:GetObject"
      ],
      "Resource": [
        "arn:aws:logs:us-east-1:*:*",
        "arn:aws:s3:::*"
      ]
    }
  ]
}

各種インストールと設定

td-agent のインストール

td-agent のインストールは以下のとおりです。

curl -L http://toolbelt.treasuredata.com/sh/install-redhat.sh | sh
fluent-plugin-cloudwatch-logs のインストール

fluent-plugin-cloudwatch-logs のインストールは以下のとおりです。

/usr/lib64/fluent/ruby/bin/gem install fluent-plugin-cloudwatch-logs --no-ri --no-rdoc -V
リージョンの指定

コマンドラインより以下のようにリージョンを指定します。

export AWS_REGION=us-east-1
td-agent.conf の設定

個人的には td-agent.conf には最低限の設定をして include を利用して個別のファイルを読み込む方が好きなので td-agent.conf は以下のように設定します。

td-agent.conf
<source>
  type monitor_agent
  bind 0.0.0.0
  port 24220
</source>

include conf.d/*.conf

monitor_agent は Consul で検証した名残です。monitor_agent は何かと便利だと思っているのでだいたい入れるようにしています。fluent-plugin-cloudwatch-logs 自身の設定は Github のリポジトリに掲載されている example を利用させて頂きますので以下のように設定しました。

sudo mkdir /etc/td-agent/conf.d
cd /etc/td-agent/conf.d
wget https://raw.githubusercontent.com/ryotarai/fluent-plugin-cloudwatch-logs/master/example/fluentd.conf -O cloudwatch-logs.conf

尚、cloudwatch-logs.conf の内容は以下のとおりです。

cloudwatch-logs.conf
<source>
  type forward
</source>

<source>
  type cloudwatch_logs
  tag test.cloudwatch_logs.in
  log_group_name fluent-plugin-cloudwatch-example
  log_stream_name fluent-plugin-cloudwatch-example
  state_file /tmp/fluent-plugin-cloudwatch-example.state
</source>

<match test.cloudwatch_logs.out>
  type cloudwatch_logs
  log_group_name fluent-plugin-cloudwatch-example
  log_stream_name fluent-plugin-cloudwatch-example
  sequence_token_file /tmp/fluent-plugin-cloudwatch-example.seq
  auto_create_stream true
</match>

<match test.cloudwatch_logs.in>
  type stdout
</match>

out_cloudwatch_logs では sequence_token_file で指定したファイルに送信したログの token が記録されるようです。また、in_cloudwatch_logs では state_file に取得したログのポジションが記録されるようです。

起動

td-agent を起動します。

/etc/init.d/td-agent start

尚、service コマンドで起動しようとすると以下のようなメッセージが表示されて起動しませんでした。

01

export AWS_REGION=us-east-1 が service コマンドの場合引き継いてくれていないようです。service コマンドでの起動と /etc/init.d/${script} を利用したデーモン起動の挙動の違いについて以下の記事が大変参考になりました。

とりえずは /etc/init.d/td-agent start を使って起動するようにします。


試す

td-agent を起動直後

td-agent を起動すると既に以下のように CloudWatch Logs 側に Log Group と Log Stream は出来ていました。

Log Group

02

Log Stream

03

おお、なんとなく掴めてきました…fluent-plugin-cloudwatch-logs は AWS が提供するエージェントツールと同じような役割を持ったプラグインのようです。

ログを送ってみる

以下のようにしてログを送ってみたいと思います。

echo '{"kappa":"hage"}' | /usr/lib64/fluent/ruby/bin/fluent-cat test.cloudwatch_logs.out

実行したら以下のようにログが記録されています。

04

おお。AWS のエージェントを利用せずに CloudWatch Logs にログを登録することが出来ました。

ログを取ってみよう

以下のように一旦ログを送ってみたいと思います。

echo '{"kappa":"hage"}' | /usr/lib64/fluent/ruby/bin/fluent-cat test.cloudwatch_logs.out
echo '{"kappa":"aho"}' | /usr/lib64/fluent/ruby/bin/fluent-cat test.cloudwatch_logs.out
echo '{"kappa":"zura"}' | /usr/lib64/fluent/ruby/bin/fluent-cat test.cloudwatch_logs.out

設定では取ってきたログは以下のように stdout に出力するようになっています。

<match test.cloudwatch_logs.in>
  type stdout
</match>

暫くすると td-agent.log に以下のようなログが記録されました。

05

おお。


最後に

fluent-plugin-cloudwatch-logs を使えば…

  • out_cloudwatch_logs で任意のログを CloudWatch Logs に送ることが出来る
  • in_cloudwatch_logs で CloudWatch Logs から指定した Log Group と Log Stream からログを取得出来る

嬉しいこと

fluent-plugin-cloudwatch-logs を利用すれば…

  • AWS が提供するツールを導入することなく CloudWatch Logs を利用出来る
  • (と言うことは)CloudWatch Logs と td-agent を二つインストールする必要が無い
  • CloudWatch Logs に溜めておいたログを回収して別のツールで可視化や保存も出来そう(あとで試そう)

ちょっと疑問

  • CloudWatch Logs のアグリゲータとの通信が切れた場合等の挙動(バッファリングは?)
  • 処理の性能とか

注意点

今後、改善されるかもしれませんが…

  • td-agent を起動する際には service コマンドではなく /etc/init.d/td-agent start で
  • たまに td-agent 側で以下のようなログが出力されて CloudWatch Logs にログが登録出来ない現象があった(発生原因を調べる)
2014-07-19 04:41:48 +0000 [warn]: temporarily failed to flush the buffer. next_retry=2014-07-19 04:42:50 +0000 error_class="Aws::CloudWatchLogs::Errors::InvalidSequenceTokenException" error="The given sequenceToken is invalid. The next ex
pected sequenceToken is: null" instance=69971155699340

元記事は、こちら