AWS CloudWatchにEC2のRailsアプリケーションのログを連携するための手順
今はコンテナが主流かもしれませんが、レガシーなシステムではEC2が複数台構成になっているため、AWS CloudWatchの1箇所にアプリケーションのログを集約したいと思います。
今回はその連携手順で、Amazon Linux 2に設定を行います。
1. CloudWatch Agentのインストールと設定
まず、監視ツールであるCloudWatchエージェントのインストールを行います。
このエージェントは、CloudWatchと連携し、システムやアプリケーションのパフォーマンスデータを収集してCloudWatchに送信します。
$ sudo yum install -y amazon-cloudwatch-agent
...
...
===================================================================================================================================================================================================================
Package アーキテクチャー バージョン リポジトリー 容量
===================================================================================================================================================================================================================
インストール中:
amazon-cloudwatch-agent x86_64 1.300039.0-1.amzn2 amzn2-core 108 M
トランザクションの要約
===================================================================================================================================================================================================================
インストール 1 パッケージ
総ダウンロード容量: 108 M
インストール容量: 416 M
Downloading packages:
amazon-cloudwatch-agent-1.300039.0-1.amzn2.x86_64.rpm | 108 MB 00:00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
create group cwagent, result: 0
create user cwagent, result: 0
インストール中 : amazon-cloudwatch-agent-1.300039.0-1.amzn2.x86_64 1/1
検証中 : amazon-cloudwatch-agent-1.300039.0-1.amzn2.x86_64 1/1
インストール:
amazon-cloudwatch-agent.x86_64 0:1.300039.0-1.amzn2
完了しました!
2.CloudWatch Agentの設定
CloudWatchエージェントのための設定ファイルの作成を行います。以下に、その設定ファイルの一例を示します。
/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
を新規作成します。
file_path
にはログファイルのパスを指定log_group_name
にはCloudWatch Logsで使用するロググループの名前を指定します。本番環境なので、productionを指定(開発環境ならdevelopなど)log_stream_name
にはログストリームの名前を指定します。今回の場合、EC2のインスタンスID:{instance_id}を指定
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/www/owani/log/production.log",
"log_group_name": "/ec2/owani/production",
"log_stream_name": "{instance_id}"
}
]
}
}
}
}
3.CloudWatchエージェントの設定ファイルを適用
CloudWatchエージェントを起動し、設定ファイルを適用します。
$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \
-s
****** processing amazon-cloudwatch-agent ******
I! Trying to detect region from ec2 D! [EC2] Found active network interface I! imds retry client will retry 1 timesSuccessfully fetched the config and saved in /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/file_amazon-cloudwatch-agent.json.tmp
Start configuration validation...
2024/05/31 14:40:19 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/file_amazon-cloudwatch-agent.json.tmp ...
2024/05/31 14:40:19 I! Valid Json input schema.
2024/05/31 14:40:19 Configuration validation first phase succeeded
I! Detecting run_as_user...
I! Trying to detect region from ec2
D! [EC2] Found active network interface
I! imds retry client will retry 1 times
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent -schematest -config /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml
Configuration validation second phase succeeded
Configuration validation succeeded
amazon-cloudwatch-agent has already been stopped
Created symlink from /etc/systemd/system/multi-user.target.wants/amazon-cloudwatch-agent.service to /etc/systemd/system/amazon-cloudwatch-agent.service.
状態を確認してみました。
amazon-cloudwatch-agent has already been stopped
というメッセージが表示されましたが、CloudWatchエージェントは起動しているようです。
$ sudo systemctl status amazon-cloudwatch-agent
● amazon-cloudwatch-agent.service - Amazon CloudWatch Agent
Loaded: loaded (/etc/systemd/system/amazon-cloudwatch-agent.service; enabled; vendor preset: disabled)
Active: active (running) since 金 2024-05-31 14:40:19 JST; 2min 17s ago
Main PID: 25978 (amazon-cloudwat)
さらにログを確認します。
AWS CloudWatchエージェントが適切な認証情報を取得できていないことが示唆されています。これはEC2インスタンスにIAMロールが適用されていないためです。IAMロールを設定し、必要なポリシーを付与することでこの問題は解決できます。
$ sudo tail -f /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log
<head>
<title>404 - Not Found</title>
</head>
<body>
<h1>404 - Not Found</h1>
</body>
</html>
status code: 404, request id:
2024-05-31T05:44:03Z W! [outputs.cloudwatchlogs] Retried 10 time, going to sleep 41.318716939s before retrying.
2024-05-31T05:44:44Z E! [outputs.cloudwatchlogs] Aws error received when sending logs to /ec2/owani/production/i-00as62287062b8342: NoCredentialProviders: no valid providers in chain
caused by: EnvAccessKeyNotFound: failed to find credentials in the environment.
SharedCredsLoad: failed to load profile, .
EC2RoleRequestError: no EC2 instance role found
caused by: EC2MetadataError: failed to make EC2Metadata request
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>404 - Not Found</title>
</head>
<body>
<h1>404 - Not Found</h1>
</body>
</html>
status code: 404, request id:
2024-05-31T05:44:44Z W! [outputs.cloudwatchlogs] Retried 11 time, going to sleep 45.887183752s before retrying.
4. IAMロールの設定
EC2インスタンスに適用されているIAMロールがある場合には、CloudWatch Logsへの書き込み権限を与えます。以下のポリシーをIAMロールにアタッチしてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:PutLogEvents",
"logs:CreateLogStream",
"logs:CreateLogGroup"
],
"Resource": "*"
}
]
}
※私の場合、EC2にIAMロールを設定していませんでしたので下記の手順を進めます。
IAMロールを作成
私は、まずIAMロールを作成し、必要なポリシーを付与します。そして、そのIAMロールをEC2インスタンスにアタッチします。
- AWSマネジメントコンソールにログインします。
- IAMコンソールに移動します。
- 左側のナビゲーションペインで「ロール」を選択し、「ロールを作成」ボタンをクリックします。
- 「信頼されたエンティティの種類を選択」画面で「AWSサービス」を選択し、サービスまたはユースケースは「EC2」を選択します。
- [ 次へ ] をクリックします。
- 「許可を追加:許可ポリシー」画面で「CloudWatchAgentServerPolicy」を検索し、チェックボックスをオンにします。
- [ 次へ ] をクリックします。
- ロール名を入力します(例:
EC2CloudWatchRole
)。 - [ ロールを作成 ] ボタンをクリックします。
インスタンスプロファイルの作成
インスタンスプロファイルの作成方法が画面からわからなかったので、AWS CLIを使用しました。
前提:AWS CLIは調べて使えるようにしておきます
AWS CLIを使用してインスタンスプロファイルを作成します。まず、IAMロールに対応するインスタンスプロファイルを作成します。
% aws iam create-instance-profile --instance-profile-name EC2CloudWatchProfile
次に、作成したインスタンスプロファイルに既存のIAMロールをアタッチします。
% aws iam add-role-to-instance-profile --instance-profile-name EC2CloudWatchProfile --role-name EC2CloudWatchRole
EC2インスタンスにIAMロールをアタッチ
- EC2コンソールに移動します。
- 対象のEC2インスタンスを選択します。
- 「アクション」メニューから「セキュリティ」→「IAMロールの変更」を選択します。
- 先ほど作成したIAMロールを選択し、[ IAMロールの更新 ] ボタンをクリックします。
5. CloudWatchエージェントの再起動
EC2インスタンスにIAMロールが正しくアタッチされたことを確認した後、CloudWatchエージェントを再起動します。
$ sudo systemctl restart amazon-cloudwatch-agent
6. CloudWatchロググループの確認
- CloudWatchに移動し、ロググループが作成されているか確認します(例:
/ec2/owani/production
)。 - ログストリームが作成され、ログが送信されていることを確認します。(例:今回の場合インスタンスID:i-00as62287062b8342)