CloudWatch Logsのchefによるセットアップ

少し前にCloudWatch Logsが発表されました。 これはEC2の各種ログをCloudWatchに転送し、マネジメントコンソールから閲覧ができるようになるという機能です。

 

FluentdとCloudWatch Logsの違い

ログの転送というと、これまではFluentdを使うのが一般的でした。Fluentdを使えば、フィルタを通してElasticSearchやMongoDBにログを転送して検索できるようにしたりなど、いろいろ凝ったことが出来ます。しかし単に長期間保存だけできればよいという場合もあるので、そういったときはFluentdを通してログをS3に放り込むような使い方がお手軽でした。S3に入れておけばデータ保全も万全ですし、古いログを自動で削除したりGlacierに移したりといったことが簡単にできます。しかし、Fluentdを通してS3に転送したログは細切れになっており、閲覧性が最悪でした。

CloudWatch Logsでは、Fluentdと同じように、EC2にログエージェントをインストールします。インストールされたログエージェントは指定されたログを収集し、CloudWatchに転送します。CloudWatch LogsのログエージェントにはFluentdのような高度なフィルタの機能は無く、単にログを転送するだけです。

しかしログ閲覧のUIにはCloudWatchのマネジメントコンソールが使えますので、S3に入れるよりは便利になります。また、特定文字列を検知してアラートを上げることなども可能です。

 

今回はCloudWatch Logsの機能を使ってApacheのログを転送し、かつログエージェントのセットアップをchefのレシピにしてみました。

 

 

セットアップ

IAMでの権限付与

まずIAM Roleで適切な権限をEC2に付与する必要があります。

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

ちなみに、2014/08/04の時点では、CloudWatch Logsはus-east-1しか対応していないためにResourceの指定でus-east-1リージョンを指定していますが、EC2インスタンスはどこのリージョンにいても問題ありません。

 

ログエージェントのインストールとセットアップ

以下のようにセットアップスクリプトをS3から取得して実行します。スクリプトの中で自動でインストールが行われ、続いて対話型で設定が進んでいきます。

wget https://s3.amazonaws.com/aws-cloudwatch/downloads/awslogs-agent-setup-v1.0.p
sudo python ./awslogs-agent-setup-v1.0.py --region us-east-1

以下は対話型の設定画面のログです。

Launching interactive setup of CloudWatch Logs agent ...

Step 1 of 5: Installing pip ...DONE

Step 2 of 5: Downloading the latest CloudWatch Logs agent bits ... DONE

Step 3 of 5: Configuring AWS CLI ...
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: us-east-1
Default output format [None]:

IAM Roleを使う場合はAccess KeyとSecret Access Keyは空欄のままEnterで問題ありません。

Step 4 of 5: Configuring the CloudWatch Logs Agent ...
Path of log file to upload [/var/log/messages]: /var/log/httpd/access_log
Destination Log Group name [/var/log/httpd/access_log]:

Choose Log Stream name:
  1. Use EC2 instance id.
  2. Use hostname.
  3. Custom.
Enter choice [1]: 2

Choose Log Event timestamp format:
  1. %b %d %H:%M:%S    (Dec 31 23:59:59)
  2. %d/%b/%Y:%H:%M:%S (10/Oct/2000:13:55:36)
  3. %Y-%m-%d %H:%M:%S (2008-09-08 11:52:54)
  4. Custom
Enter choice [1]: 2

Choose initial position of upload:
  1. From start of file.
  2. From end of file.
Enter choice [1]: 1
More log files to configure? [Y]: N

Step 5 of 5: Setting up agent as a daemon ...DONE

------------------------------------------------------
- Configuration file successfully saved at: /var/awslogs/etc/awslogs.conf
- You can begin accessing new log events after a few moments at https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#logs:
- You can use 'sudo service awslogs start|stop|status|restart' to control the daemon.
- To see diagnostic information for the CloudWatch Logs Agent, see /var/log/awslogs.log
- You can rerun interactive setup using 'sudo ./awslogs-agent-setup.py --region us-east-1 --only-generate-config'
------------------------------------------------------

ApacheのログのTimeFormatは、本来は「%d/%b/%Y:%H:%M:%S %z」ですが、そう指定すると実際に動作させた際に

WARNING - Thread-6 - Fall back to current time: {'source_id': ‘1234567890123456789012345678901234567890', 'timestamp': 1234567890, 'start_position': 123456L, 'end_position': 123457L}, reason: timestamp could not be parsed from message.

の様なログが出てタイムスタンプが正常にとれなくなってしまいますので、2を選択しましょう。

 

デーモンの起動と自動起動の設定

service awslogs start
Starting system awslogs daemon
Starting awslogs daemon

service awslogs status
 (pid  873) is running...

chkconfig awslogs on
chkconfig --list awslogs
awslogs             0:off     1:off     2:on     3:on     4:on     5:on     6:off

これでセットアップは完了です。

すでにCloudWatchへのログ転送が始まっています。

 

 

CloudWatchからのログの閲覧

マネジメントコンソールからCloudWatchを開きます。リージョンをus-east-1にする必要があることに注意してください。

CloudWatch Management Console

見るとわかりますがログを閲覧するだけの機能しかありません。検索も何もできません。。

しかしS3に入れるよりは便利だと思います。

 

chefのレシピを作成

ここまでで利用はできるようになりましたので、今度はchefのレシピにしてみます。ログエージェントのインストーラは-nオプションを渡すと対話をスキップしてセットアップを自動化することができます。

なお、対話スキップ時にはconfigのひな形を渡さなければならないので、予め用意しておく必要があります。一度どこかのインスタンスで対話式セットアップを実施して、出力されたconfigを拾ってくると良いです。対話式セットアップで出力されるconfigは、

/var/awslogs/etc/awslogs.conf

にあります。

 

recipes/default.rb

#config template
template "/tmp/awslogs.conf" do
 source "conf/awslogs.conf.erb"
 owner "root"
 group "root"
 mode 0644
end

#download setup file
remote_file "/tmp/awslogs-agent-setup-v1.0.py" do
 source "https://s3.amazonaws.com/aws-cloudwatch/downloads/awslogs-agent-setup-v1.0.py"
 owner "root"
 group "root"
 mode 0755
end

#install log agent
execute "install-log-agent" do
 command "/tmp/awslogs-agent-setup-v1.0.py -n --region us-east-1 -c /tmp/awslogs.conf"
end

#delete config template
file "/tmp/awslogs.conf" do
 action :delete
end

#delete setup file
file "/tmp/awslogs-agent-setup-v1.0.py" do
 action :delete
end

#start & chkconfig on
service "awslogs" do
 supports :status => true, :restart => true, :reload => true
 action [:enable, :restart]
end

上記のようなレシピになりました。templates/default/conf/awslogs.conf.erbとしてconfigのひな形を置いておく必要があります。

 

 

まとめ

CloudWatchのUIは貧弱ですが、S3に保存していたときよりは閲覧性が上がります。とりあえず保存しておけば良いという場合はCloudWatch Logsを使い、フィルタがつかいたい場合はFluentdにするという使い分けをしていけばよいと思います。

 

 

 

参考URL

 Amazon CloudWatch Logsでログファイルを監視する

Amazon CloudWatch Developer Guide