Linux + CloudWatch Agentのメトリクス/ログ管理

2019-09-25

はじめに

目的

  • EC2インスタンス上のLinuxサーバーが個々に持つログを収集して、CloudWatch Logsに集約すること。
  • CloudWatchを使って、各EC2インスタンスのカスタムメトリクスを監視すること。

前提条件

  • Linuxに、amazon-ssm-agentがインストールされていること。
  • EC2インスタンスのroleには、AmazonEC2ReadOnlyAccess、CloudWatchFullAccess、AmazonSSMFullAccessのポリシーがアタッチされていること。
  • サーバーOSは、CentOS 7 を使用しています。
  • Windows Server のCloudWatch Agentによるメトリクス/ログ管理は、下記の記事を参照ください。
 

CloudWatch Agentのインストール

インストール状態の確認

  • LinuxにCloud Watch Agent がインストールされているかを確認します。下記のyum list installedコマンドを実行し、出力結果にamazon-cloudwatch-agentがあればインストール済みです。
 

$ sudo yum list installed | grep cloudwatch
amazon-cloudwatch-agent.x86_64          1.208036.0-1                   installed
 

エージェントのインストール

  • LinuxにCloud Watch Agent がインストールされていない場合、SSM(Systems Manager)からインストールを行います。
  • SSMのRunCommandより、「AWS-ConfigureAWSPackage」を選択し、Action、Nameのパラメータを指定します。
  • AWS-ConfigureAWSPackage
    • Action: Install
    • Name: AmazonCloudWatchAgent
 

設定ファイル(JSON)の作成方法

ウィザードを使って設定ファイルを作成する

  • 下記コマンドを実行し、ウィザードを使って設定ファイルを作成します。

$ cd /opt/aws/amazon-cloudwatch-agent/etc
$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
=============================================================
= Welcome to the AWS CloudWatch Agent Configuration Manager =
=============================================================
On which OS are you planning to use the agent?
1. linux
2. windows
default choice: [1]:

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]:

Do you want to turn on StatsD daemon?
1. yes
2. no
default choice: [1]:
2
Do you want to monitor metrics from CollectD?
1. yes
2. no
default choice: [1]:
2
Do you want to monitor any host metrics? e.g. CPU, memory, etc.
1. yes
2. no
default choice: [1]:

Do you want to monitor cpu metrics per core? Additional CloudWatch charges may apply.
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]:

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]:
3
Current config as follows:
{
        "metrics": {
                "append_dimensions": {
                        "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
                        "ImageId": "${aws:ImageId}",
                        "InstanceId": "${aws:InstanceId}",
                        "InstanceType": "${aws:InstanceType}"
                },
                "metrics_collected": {
                        "cpu": {
                                "measurement": [
                                        "cpu_usage_idle",
                                        "cpu_usage_iowait",
                                        "cpu_usage_user",
                                        "cpu_usage_system"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ],
                                "totalcpu": false
                        },
                        "disk": {
                                "measurement": [
                                        "used_percent",
                                        "inodes_free"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "diskio": {
                                "measurement": [
                                        "io_time",
                                        "write_bytes",
                                        "read_bytes",
                                        "writes",
                                        "reads"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "mem": {
                                "measurement": [
                                        "mem_used_percent"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "netstat": {
                                "measurement": [
                                        "tcp_established",
                                        "tcp_time_wait"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "swap": {
                                "measurement": [
                                        "swap_used_percent"
                                ],
                                "metrics_collection_interval": 60
                        }
                }
        }
}
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]:

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/log/messages
Log group name:
default choice: [messages]
Linux_/var/log/messages
Log stream name:
default choice: [{instance_id}]
{local_hostname}_{instance_id}
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:
{
        "logs": {
                "logs_collected": {
                        "files": {
                                "collect_list": [
                                        {
                                                "file_path": "/var/log/messages",
                                                "log_group_name": "Linux_/var/log/messages",
                                                "log_stream_name": "{local_hostname}_{instance_id}"
                                        }
                                ]
                        }
                }
        },
        "metrics": {
                "append_dimensions": {
                        "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
                        "ImageId": "${aws:ImageId}",
                        "InstanceId": "${aws:InstanceId}",
                        "InstanceType": "${aws:InstanceType}"
                },
                "metrics_collected": {
                        "cpu": {
                                "measurement": [
                                        "cpu_usage_idle",
                                        "cpu_usage_iowait",
                                        "cpu_usage_user",
                                        "cpu_usage_system"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ],
                                "totalcpu": false
                        },
                        "disk": {
                                "measurement": [
                                        "used_percent",
                                        "inodes_free"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "diskio": {
                                "measurement": [
                                        "io_time",
                                        "write_bytes",
                                        "read_bytes",
                                        "writes",
                                        "reads"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "mem": {
                                "measurement": [
                                        "mem_used_percent"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "netstat": {
                                "measurement": [
                                        "tcp_established",
                                        "tcp_time_wait"
                                ],
                                "metrics_collection_interval": 60
                        },
                        "swap": {
                                "measurement": [
                                        "swap_used_percent"
                                ],
                                "metrics_collection_interval": 60
                        }
                }
        }
}
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]:
2
Program exits now.
 
  • ウィザードでメトリクスを設定する際に、事前定義されたメトリクスセット(1. Basic / 2. Standard / 3. Advanced)を選択します。メトリクスセットの内容およびその他ウィザードを使用した設定ファイルの作成については、下記ドキュメントを参照ください。
 

手動で設定ファイルを作成する

  • 既に動作実績のある設定ファイルが手元にある場合は、サーバーに合わせてカスタマイズする方法がお勧めです。
  • 一から手動で作成する場合は、下記ドキュメントのサンプルを使用します。
 
  • CloudWatch エージェント設定ファイルは、agentmetricslogs の 3 つのセクションを持つ JSON ファイルです。
    • agent セクションには、エージェントの全体的な設定に関するフィールドが含まれています。ウィザードを使用する場合、agent セクションは作成されません。
    • metrics セクションでは、収集と CloudWatch への発行に関するカスタムメトリクスを指定します。ログを収集するためだけにエージェントを使用している場合は、ファイルから metrics セクションを省略できます。
    • logs セクションでは、CloudWatch Logs に発行されるログファイルを指定します。サーバーで Windows Server が実行されている場合、これには Windows イベントログからのイベントが含まれることがあります。

  • log_stream_nameにサーバーの判別をしやすくするため、{local_hostname}を指定しています。{hostname} は、EC2メタデータからホスト名を取得しますが、{local_hostname} は、OSのネットワーク設定ファイルから取得したホスト名を使用します。些細な違いですが、日常的にログを見る場合に何をヘッダーに付けるかを設計しましょう。
  • その他手動で設定ファイルを作成する場合の説明は、ドキュメントを参照ください。
 

エージェントの起動方法

  • 設定ファイルを配置し、エージェントのサービスを起動します。

$ cd /opt/aws/amazon-cloudwatch-agent/etc
$ sudo cp ../bin/config.json ./amazon-cloudwatch-agent.json
$ sudo systemctl restart amazon-cloudwatch-agent
$ 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 Mon 2019-02-25 11:24:54 UTC; 5s ago
 Main PID: 10975 (start-amazon-cl)
   CGroup: /system.slice/amazon-cloudwatch-agent.service
           tq10975 /opt/aws/amazon-cloudwatch-agent/bin/start-amazon-cloudwat...
           mq10988 /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-age...

Feb 25 11:24:54 ip-10-10-0-6.ap-northeast-1.compute.internal systemd[1]: Star...
Hint: Some lines were ellipsized, use -l to show in full.
 

CloudWatch Logsでロググループをチェック!

  • CloudWatch Logsより、ロググループ、ログストリームが作成されたことを確認します。
  • メトリクスより、EC2のカスタムメトリクスが監視できていることを確認します。
 

トラブルシューティング

エージェントが起動できない場合

  • 私の経験上、下記の理由でエージェントが起動できない場合がありました。
  • EC2インスタンスのロールに権限が足りない。サービス起動時にEC2をreadする権限必要であり、AmazonEC2ReadOnlyAccessを追加することで、解決しました。
    • 繰り返しとなりますが、EC2インスタンスのroleには、AmazonEC2ReadOnlyAccess、CloudWatchFullAccess、AmazonSSMFullAccessのポリシーがアタッチされている必要があります。
  • エージェントの設定ファイルの記述に誤りがある。手動で設定ファイルを作成した場合、記述が誤っていることがあります。以下シンプルなサンプルです。一度シンプルな設定ファイルに置き換えて、テストしてみましょう。

{
        "logs": {
                "logs_collected": {
                        "files": {
                                "collect_list": [
                                        {
                                                "file_path": "/var/log/messages",
                                                "log_group_name": "Linux_/var/log/messages",
                                                "log_stream_name": "{local_hostname}_{instance_id}"
                                        }
                                ]
                        }
                }
        }
}