🦔

CloudWatch Agent でメトリクスとログを監視してみた

2023/02/06に公開


はじめに

AWS初心者のArishoです!
Auto Scaling で日々 EC2 インスタンスが入れ替わってしまうため、ログをどこかに保管したいと感じた場面がありました。
そこで、アプリケーションのエラーログや Apache のエラーログを CloudWatch に取り込めるCloudWatch Agent について勉強してみました。



CloudWatch Agent とは

EC2 インスタンスやオンプレミスサーバーにインストールすることで、メトリクスやログを収集して CloudWatch へ送信することができます。また、ログのアーカイブや分析時に役立ちます。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html



CloudWatch Agent 設定ファイルとは

CludWatch Agent 設定ファイルは、agent、logs、metrics の3つの節句ションかなる JSON
ファイルで、どんなメトリクスを監視するか、どのログファイルを取り込むかなどを設定します。
サーバー上またはパラメータストアに保存します。

1. agent セクション

監視する EC2 インスタンスがあるリージョンの情報やメトリクスを収集する頻度など、
エージェントの全体的な設定に関するフィールドが含まれています。

2. logs セクション

CloudWatch Logs に取り込みたいログのパス、CloudWatch Logs のロググループ名、ログストリーム(同じソースを共有する一連のログイベント)の設定などを指定します。ログファイルの取り込み設定は複数設定することができます。

3. metrics セクション

CloudWatch で監視するメトリクスを指定します。例えばディスクの使用済み容量などです。
メトリクスは複数設定することが可能です。
ログを収集するだけの場合は、ファイルから metrics セクションを省略して問題ないようです。
監視できるメトリクスは、 AWS ドキュメントを参照ください。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/metrics-collected-by-CloudWatch-agent.html#linux-metrics-enabled-by-CloudWatch-agent



パラメータストアとは

パラメータストアは、設定データ管理と機密管理のための安全な階層型ストレージを提供する
AWS Systems Manager のサービスです。
パスワード、データベース文字列、Amazon Machine Image (AMI) ID、ライセンスコードなどのデータをパラメータ値として保存ができます。

パラメータストアに保存することで簡単に設定の変更や AWS リソースへ反映ができるため、
CloudWatch Agent 設定ファイルを保存することをおすすめします。

詳しくは、下記の記事を参照ください。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html




やってみる - メトリクスおよびログを監視する

1. 事前準備

前提条件として、メトリクスおよびログを監視する対象の EC2 インスタンスがあること。
下記の IAM ロールが対象 EC2 インスタンスにアタッチされていること。

2. collectdをインストールする

対象の EC2 インスタンス内に collectd をインストールします。
collectd は、サーバの統計情報を収集するためのオープンソースソフトウェアです。

  • collectd インストールコマンド
sudo amazon-linux-extras install collectd

// Amazon Linux 2023 を使用する場合は、以下コマンドでインストール
yum install collectd

詳しくは、下記の記事を参照ください。
https://blog.serverworks.co.jp/tech/2020/03/30/collectd/

3. CloudWatch Agent をインストールする

対象の EC2 インスタンス内に CloudWatch Agent をインストールします。

  • CloudWatch Agent インストールコマンド
sudo yum install amazon-cloudwatch-agent

インスト―ル場所は、「/opt/aws/amazon-cloudwatch-agent 」になります。

4. CloudWatch Agent 設定ファイルを作成する

CloudWatch Agent 設定ファイルウィザードを起動します。

  • CloudWatch Agent 設定ファイルウィザード起動コマンド
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

CloudWatch Agent 設定ファイルを作成する際、以下の項目を質問形式で聞かれるので設定する
値で回答します。


================================================================
= Welcome to the Amazon CloudWatch Agent Configuration Manager =
=                                                              =
= CloudWatch Agent allows you to collect metrics and logs from =
= your host and send them to CloudWatch. Additional CloudWatch =
= charges may apply.                                           =
================================================================

//どのOSでエージェントを使用するか。
On which OS are you planning to use the agent?
1. linux
2. windows
3. darwin
default choice: [1]:

//エージェントを Amazon EC2 インスタンスとオンプレミスサーバーのどちらにインストールするか。
Trying to fetch the default region based on ec2 metadata...
Are you using EC2 or On-Premises hosts?
1. EC2
2. On-Premises
default choice: [1]:

//どのユーザでエージェントを実行するか。
Which user are you planning to run the agent?
1. root
2. cwagent
3. others
default choice: [1]:

//StatsD を起動するか。( StatsD は指標データを集計するためのデーモン)
Do you want to turn on StatsD daemon?
1. yes
2. no
default choice: [1]:

//StatsD のポート番号は何番にするか。
Which port do you want StatsD daemon to listen to?
default choice: [8125]

//メトリクスの収集間隔を何秒にするか。
What is the collect interval for StatsD daemon?
1. 10s
2. 30s
3. 60s
default choice: [1]:

//収集したメトリクスの集計間隔を何秒にするか。
What is the aggregation interval for metrics collected by StatsD daemon?
1. Do not aggregate
2. 10s
3. 30s
4. 60s
default choice: [4]:

//収集したメトリクスを collectd で監視をするか。(※ collectd を利用するにはインストールが必要となります。)
Do you want to monitor metrics from CollectD? WARNING: CollectD must be installed or the Agent will fail to start
1. yes
2. no
default choice: [1]:

//CPU、メモリなどのホストメトリクスを監視するか。
Do you want to monitor any host metrics? e.g. CPU, memory, etc.
1. yes
2. no
default choice: [1]:

//CPUメトリクスをコアごとに監視するか。
Do you want to monitor cpu metrics per core?
1. yes
2. no
default choice: [1]:

//メトリクスに利用可能なディメンション(一意の識別子)を追加するか。
Do you want to add ec2 dimensions (ImageId, InstanceId, InstanceType, AutoScalingGroupName) into all of your metrics if the info is available?
1. yes
2. no
default choice: [1]:

//ec2 ディメンション (InstanceId) を集約するか。
Do you want to aggregate ec2 dimensions (InstanceId)?
1. yes
2. no
default choice: [1]:

//メトリクスの収集間隔をより高頻度で収集するか。
Would you like to collect your metrics at high resolution (sub-minute resolution)? This enables sub-minute resolution for all metrics, but you can customize for specific metrics in the output json file.
1. 1s
2. 10s
3. 30s
4. 60s
default choice: [4]:

//デフォルトはどのメトリクス構成がいいか。
Which default metrics config do you want?
1. Basic
2. Standard
3. Advanced
4. None
default choice: [1]:

//一旦、上記で設定した内容が表示されます。
Current config as follows:
{
        "agent": {
                "metrics_collection_interval": 60,
                "run_as_user": "root"
        },
        "metrics": {
                "aggregation_dimensions": [
                        [
                                "InstanceId"
                        ]
                ],
                "append_dimensions": {
                        "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
                        "ImageId": "${aws:ImageId}",
                        "InstanceId": "${aws:InstanceId}",
                        "InstanceType": "${aws:InstanceType}"
                },
                "metrics_collected": {
                        "collectd": {
                                "metrics_aggregation_interval": 60
                        },
                        "disk": {
                                "measurement": [
                                        "used_percent"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "mem": {
                                "measurement": [
                                        "mem_used_percent"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "statsd": {
                                "metrics_aggregation_interval": 60,
                                "metrics_collection_interval": 10,
                                "service_address": ":8125"
                        }
                }
        }
}

//上記の内容で設定して良いか。
Are you satisfied with the above config? Note: it can be manually customized after the wizard completes to add additional items.
1. yes
2. no
default choice: [1]:

//既存の CloudWatch Agent があるか。
Do you have any existing CloudWatch Log Agent (http://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html) configuration file to import for migration?
1. yes
2. no
default choice: [2]:

//監視(取得)したいログファイルがあるか。
Do you want to monitor any log files?
1. yes
2. no
default choice: [1]:
//監視するログファイルがある場合、ファイルのパス、格納先のロググループ名、ログストリーム名を入力します。
Log file path:
/var/www/html/fuel/app/logs/fatalerror/ *.log
Log group name:
default choice: [*.log]
dls-prd-a00x_asg_application-fatalerror
Log stream name:
default choice: [{instance_id}]

//ロググループの保持期間を何日にするか。
Log Group Retention in days
1. -1
2. 1
3. 3
4. 5
5. 7
6. 14
7. 30
8. 60
9. 90
10. 120
11. 150
12. 180
13. 365
14. 400
15. 545
16. 731
17. 1827
18. 3653
default choice: [1]:

//監視(取得)したいログファイルが他にあるか。
Do you want to specify any additional log files to monitor?
1. yes
2. no
default choice: [1]:
//他にログファイルがある場合は「2」を選択。ここで複数ログファイルの監視(取得)設定をします。

//設定内容の確認。
Saved config file to /opt/aws/amazon-cloudwatch-agent/bin/config.json successfully.
Current config as follows:
{
        "agent": {
                "metrics_collection_interval": 60,
                "run_as_user": "root"
        },
        "logs": {
                "logs_collected": {
                        "files": {
                                "collect_list": [
                                        {
                                                "file_path": "/var/www/html/fuel/app/logs/fatalerror/*.log",
                                                "log_group_name": "dls-prd-a00x_asg_application-fatalerror",
                                                "log_stream_name": "{instance_id}",
                                                "retention_in_days": -1
                                        },
                                        {
                                                "file_path": "",
                                                "log_group_name": ".",
                                                "log_stream_name": "{instance_id}",
                                                "retention_in_days": -1
                                        }
                                ]
                        }
                }
        },
        "metrics": {
                "aggregation_dimensions": [
                        [
                                "InstanceId"
                        ]
                ],
                "append_dimensions": {
                        "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
                        "ImageId": "${aws:ImageId}",
                        "InstanceId": "${aws:InstanceId}",
                        "InstanceType": "${aws:InstanceType}"
                },
                "metrics_collected": {
                        "collectd": {
                                "metrics_aggregation_interval": 60
                        },
                        "disk": {
                                "measurement": [
                                        "used_percent"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "mem": {
                                "measurement": [
                                        "mem_used_percent"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "statsd": {
                                "metrics_aggregation_interval": 60,
                                "metrics_collection_interval": 10,
                                "service_address": ":8125"
                        }
                }
        }
}

//CloudWatch Agent 設定ファイルを SSM パラメータストアに保存するか。
Please check the above content of the config.
The config file is also located at /opt/aws/amazon-cloudwatch-agent/bin/config.json.
Edit it manually if needed.
Do you want to store the config in the SSM parameter store?
1. yes
2. no
default choice: [1]:

//パラメータストア名を入力します。(※ 命名規則は、AmazonCloudWath-〇〇〇)
What parameter store name do you want to use to store your config? (Use 'AmazonCloudWatch-' prefix if you use our managed AWS policy)
default choice: [AmazonCloudWatch-linux]
AmazonCloudWatch-test

//パラメータストアを保存するリージョンをどこにするか。
Trying to fetch the default region based on ec2 metadata...
Which region do you want to store the config in the parameter store?
default choice: [ap-northeast-1]

//CloudWatch Agent 設定ファイルをパラメータに送る際のクレデンシャルを何にするか。
Which AWS credential should be used to send json config to parameter store?
1. ASIATFLMSAZFPTB3PD4B(From SDK)
2. Other
default choice: [1]:

//設定完了。
Successfully put config to parameter store AmazonCloudWatch-test.
Program exits now.



上記の設定が完了すると、作成した CloudWatch Agent 設定ファイルが Systems Manager の
パラメータストアに表示されます。 ※「パラメータストアに保存」を選択した場合となります。
(例. AmazonCloudWatch-linux パラメータを作成して保存した場合)
パラメータ


以下、パラメータストアに保存した CloudWatch Agent 設定ファイルの中身となります。
(例. AmazonCloudWatch-linux パラメータに保存したCloudWatch Agent 設定ファイルの内容)
設定ファイル1
設定ファイル2
設定ファイル3


追加で監視したいメトリクスやログファイルがある場合は、パラメータストアに保存した CloudWatch Agent 設定ファイルを編集する事で追加ができます。

パラメータストア内に保存しない場合、以下のディレクトリで CloudWatch Agent 設定ファイルを確認および編集する事ができます。

cd /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d


5. Systems Manager から CloudWatch Agent を起動

Systems Manager(以下「SSM」と称する)は、AWS アプリケーションおよびリソースの
オペレーションハブでエンドツーエンドの管理を行ってくれます。
SSM の Run Command でターゲットに指定した EC2 インスタンスに対して CloudWatch Agent を起動します。

SSM ダッシュボードのサイドメニューから「Run Command」を選択し、「Run Command」のボタンをクリックします。
Run Command


以下の設定を行います。

  • コマンドドキュメント :「AmazonCloudWatch-ManageAgent
    コマンド1
  • Action :「configure(append)- 追加」or「configure - 上書き
  • Optional Configuration Source : 「ssm
  • Mode :「ec2
  • Optional Configuration Source :「パラメータストアに保存したパラメータ名
  • Optional Restart :「yes
  • ターゲット :「インスタンスを手動で選択する:対象の EC2 インスタンス ID をクリック」
    (タグの指定を選択した場合、同じタグが付いている EC2 インスタンスに対して実行することもできます。)
    コマンド2
    コマンド3

6. SSM 以外からの起動 (5.を実行した場合は不要)

対象の EC2 インスタンスに SSH 接続もしくは SSM で接続し、CloudWatch Agent を開始します。

  • CloudWatch Agent 開始コマンド
sudo systemctl start amazon-cloudwatch-agent.service

「amazon-cloudwatch-agent.d」配下にある全ての Agent 設定ファイルの内容が実行されます。

7. 確認

AmazonCloudWatch のロググループに、ログファイルが取り込まれているかを確認します。
上記で設定したメトリクスおよびログファイルが取り込まれていれば、完了となります。
(例. ロググループ「/var/log/httpd/error_log」にログファイルを取り込む場合)
ロググループ
ログファイル


CloudWatch Agent 設定ファイルで設定したロググループが作成され、その中にログファイルが取り込まれていることが確認できました。ログストリーム(同じソースを共有する一連のログイベント)はインスタンス ID を設定しているので、各インスタンスでログファイルが取り込まれています。

8. 番外編

EC2 インスタンス起動と同時に、ログファイルを CloudWach Logs に送ることもできます。
上記の1.~7.まで設定した EC2 インスタンスを用意します。
EC2 インスタンスに SSH もしくは SSM で接続し、以下の設定を行います。

1. CloudWatch Agent の自動起動設定

自動起動設定を行うことで、EC2 インスタンスが起動すると CloudWach Agent が動き出します。

  • 自動起動設定
sudo systemctl enable amazon-cloudwatch-agent


2. State ファイルを削除

CloudWatch Agent が起動した際に State ファイルがあると取得してくれないため、削除する必要があります。
また、削除するにあたり CloudWatch Agent を停止する必要があります。

  • CloudWatch Agent を停止
sudo systemctl stop amazon-cloudwatch-agent.service
  • State ファイルに移動
cd /opt/aws/amazon-cloudwatch-agent/logs/state/
  • State ファイルを削除
rm /opt/aws/amazon-cloudwatch-agent/logs/state/削除する State ファイル名

上記の設定が完了したら AMI を取得し終了になります。
この AMI から EC2 インスタンスを立ち上げることで、自動でログやメトリクスを取得することができます。



ロググループにログが取り込まれない場合

Cloudwatch Logs でログが取り込まれない場合は、以下の原因が考えられます。

原因 1 - State ファイルの重複

Stateファイルは CloudWatch Agent がどこまでログを読み込んだかを記録しているファイルです。Stateファイルが重複してしまうと、うまく取り込めないようです。
Stateファイルを削除することで、再度 CloudWatch Logs にログを送ることができます。

まず、対象の EC2 インスタンス内で、エージェントを停止します。

  • エージェント停止コマンド
sudo systemctl stop amazon-cloudwatch-agent.service

次に、State ファイルを削除します。Stateファイルは、下記のパス配下にあります。
また、State ファイル名は取得したファイルのパスになります。
ex) 「/var/log/httpd/access_log」 ⇒ 「var_log_httpd_acces_log」

cd /opt/aws/amazon-cloudwatch-agent/logs/state/

対象のファイルを削除します。

  • ファイル削除コマンド
rm /opt/aws/amazon-cloudwatch-agent/logs/state/削除する State ファイル名

最後に、「SSM からエージェントを起動する」 or 「対象の EC2 インスタンス内でエージェントを起動」をします。

State ファイルを削除し、もう一度エージェントを起動することでログを CloudWatch Logs に送ることができるようになります。

原因 2 - エージェントのバージョン問題

State ファイルが原因ではない場合は、エージェントのバージョンアップに問題がある可能性があります。
以下のコマンドでエージェントをアップデートします。

  • エージェントアップデートコマンド
sudo rpm -U ./amazon-cloudwatch-agent.rpm

エージェントをアップデートした後、デーモンを再起動します。

  • systemd に変更内容を反映とデーモンを再起動コマンド
sudo systemctl daemon-reload
sudo systemctl restart amazon-cloudwatch-agent.service




まとめ

今回は、EC2インスタンス内のログファイルとメトリクスを CloudWatch のロググループで監視することを行いました。




登場コマンドまとめ

登場コマンドまとめ
  • CloudWatch Agent をインストールする。
sudo yum install amazon-cloudwatch-agent
  • CloudWatch Agent を開始する。
sudo systemctl start amazon-cloudwatch-agent.service
  • CloudWatch Agent を停止する。
sudo systemctl stop amazon-cloudwatch-agent.service
  • CloudWatch Agent の起動ステータスを確認。
sudo systemctl status  amazon-cloudwatch-agent.service
  • CloudWatch Agent の自動起動を確認。
systemctl list-unit-files | grep amazon-cloudwatch-agent.service
  • ファイルを削除する。
rm 削除するファイルのパス

Discussion