はじめに
個人開発しているRailsアプリ「TaskLink」の本番環境で、CloudWatchによる監視を導入しました。
これまでに以下の監視を構築しています。
- ディスク使用率監視
- メモリ使用率監視
- CPU使用率監視
- SNSメール通知
今回はさらに、RailsアプリのログをCloudWatch Logsへ送信し、AWSコンソールから確認できるようにしました。
構成
Railsでは本番環境でSTDOUTへログを出力しています。
config.logger = ActiveSupport::TaggedLogging.logger(STDOUT)
ログの流れは以下のようになります。
Rails / Puma
↓
systemd journal
↓
/var/log/syslog
↓
CloudWatch Agent
↓
CloudWatch Logs
CloudWatch Agent設定
CloudWatch Agentの設定ファイルへログ収集設定を追加しました。
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/syslog",
"log_group_name": "/tasklink/syslog",
"log_stream_name": "{instance_id}"
}
]
}
}
}
発生したトラブル① Permission denied
CloudWatch Agent起動後、ログを確認すると以下のエラーが発生しました。
Failed to tail file /var/log/syslog with error: open /var/log/syslog: permission denied
原因はCloudWatch Agentが cwagent ユーザーで実行されており、syslogを読み取る権限がなかったためです。
今回は設定ファイルの
"run_as_user": "root"
へ変更することで解決しました。
発生したトラブル② 設定ファイル競合
設定変更後もAgentが起動しませんでした。
ログを確認すると、
Failed to merge multiple json config files.
Different values are specified for run_as_user
というエラーが発生していました。
原因はバックアップ用に保存していた
file_config.json.bak
もCloudWatch Agentが読み込んでいたためです。
最終的に不要なバックアップファイルを設定ディレクトリ外へ移動して解決しました。
sudo mv file_config.json.bak ../file_config.json.bak.old
動作確認
CloudWatch Agent起動後、
/tasklink/syslog
というロググループが自動作成されました。
ログストリーム内には以下のようなRailsログが保存されることを確認できました。
Started GET "/"
Completed 200 OK
ActionController::RoutingError
まとめ
今回の対応により、
- CloudWatch Metrics
- CloudWatch Alarm
- Amazon SNS
- CloudWatch Logs
を利用した監視基盤を構築できました。
これにより、サーバーリソースの監視だけでなく、RailsアプリケーションのログもAWS上で一元管理できるようになりました。
今後はCloudWatch Logsのメトリクスフィルターを利用し、500エラー発生時の自動通知も実装していく予定です。