【EC2】 CloudWatch エージェントで Auto Scaling グループ配下にあるインスタンス内のログを CloudWatch Logs へ転送 (前編)

はじめに

以前、 Fluentd を使って Auto Scaling グループ配下にある EC2 インスタンス内のログを S3 へ転送した。
今回は、CloudWatch エージェントを用いて、Amazon CloudWatch Logs へ転送してみた。

なぜやるのか

こちら。

CloudWatch エージェントを用いて CloudWatch Logs に集約するメリット

  • マネジメントコンソール上から手軽に閲覧、検索、日時による絞り込み等が行える

  • CloudWatch 専用エージェントなので、Fluentd よりも構築・設定が簡単
    • Fluentd はいろいろできるかわりにやや複雑な仕様
  • ログのリアルタイム処理、ストリーミングが可能
    • Lambda、Kinesis、ElasticSearch Service
  • CloudWatch Logs → S3 へのエクスポートも可能

AWS を使っているのであれば、意外に CloudWatch Logs は良い選択肢なのかも?
(正直、あまり話題に挙がらず地味な印象であったが……)

環境

設定手順

正直、このドキュメントをみれば大体済む話です……

IAM ロール作成

2 種類必要になる。 ロール名は適当に。
EC2 であれば、これらをインスタンスロールとして設定すれば良い。

EC2RoleForCloudWatchAgentAdmin: CloudWatch エージェントの設定を管理するために必要な IAM ロール

ポリシーは下記。

  • AmazonEC2RoleforSSM ( SSM を使ってエージェントをインストールする場合 )
  • CloudWatchAgentAdminPolicy

ちなみに、CloudWatchAgentAdminPolicy と後述する CloudWatchAgentServerPolicy の違いは ssm:PutParameter の有無だけらしい。

@@ -17,7 +17,8 @@
         {
             "Effect": "Allow",
             "Action": [
-                "ssm:GetParameter"
+                "ssm:GetParameter",
+                "ssm:PutParameter"
             ],
             "Resource": "arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*"
         }

EC2RoleForCloudWatchAgent: 最低限 CloudWatch エージェントを稼働させる際に必要な IAM ロール

ポリシーは下記。

  • AmazonEC2RoleforSSM ( SSM を使ってエージェントをインストールする場合 )
  • CloudWatchAgentServerPolicy

EC2RoleForCloudWatchAgentAdmin と同様に作成。

Auto Scaling 用ゴールデンイメージ作成元マシンに CloudWatch エージェントのインストール

管理用ポリシーのアタッチ

EC2RoleForCloudWatchAgentAdmin をアタッチ。

System Manager Run Command を用いて、CloudWatch エージェントをインストール

System Manager Run Command (以下 Run Command) というまどろっこしい手順を踏まなくても普通にコマンドを叩いてインストールできるが、 どうも AWS 的には Run Command を使わせたい風味が漂っているのでそれに従う。

Run Command 画面のコマンドの実行を押下。

AWS-ConfigureAWSPackage を選択。

NameAmazonCloudWatchAgent

先程 EC2RoleForCloudWatchAgentAdmin ロールを付与したインスタンスを選択。

コマンド実行結果の出力先を適宜指定。

結果。

CloudWatch エージェントの設定作成

先程のインスタンスへ SSH ログイン後、ウィザードを実行するだけ。

このエージェントにはログだけでなく、カスタムメトリクス (メモリ使用率など) の収集機能もある。 まず、それに関する設定から聞かれる。

default metrics configmonitor cpu metrics per core など、追加課金が発生する可能性のある設定項目がいくつかあるので要注意。

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

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

Do you want to monitor metrics from CollectD?
1. yes
2. no
default choice: [1]:

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

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

Current config as follows:
{
    "metrics": {
        "append_dimensions": {
            "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
            "ImageId": "${aws:ImageId}",
            "InstanceId": "${aws:InstanceId}",
            "InstanceType": "${aws:InstanceType}"
        },
        "metrics_collected": {
            "collectd": {
                "metrics_aggregation_interval": 60
            },
            "mem": {
                "measurement": [
                    "mem_used_percent"
                ],
                "metrics_collection_interval": 60
            },
            "statsd": {
                "metrics_aggregation_interval": 60,
                "metrics_collection_interval": 10,
                "service_address": ":8125"
            },
            "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]:

引き続き、ログ収集の設定。
ここでは syslog、Apache のログを収集するように設定してみた。

Log group name は Auto Scaling グループ名などを適宜付与しないと、下の画面で見つける際に分かりづらいので要注意。

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]
Test-CloudWatchAgent-logs-messages

Do you want to specify any additional log files to monitor?
1. yes
2. no
default choice: [1]:
1

Log file path:
/var/log/httpd/access_log
Log group name:
default choice: [access_log]
Test-CloudWatchAgent-logs-access-log

Do you want to specify any additional log files to monitor?
1. yes
2. no
default choice: [1]:

Log file path:
/var/log/httpd/error_log
Log group name:
default choice: [error_log]
Test-CloudWatchAgent-logs-error-log

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": "Test-CloudWatchAgent-logs-messages"
                    },
                    {
                        "file_path": "/var/log/httpd/access_log",
                        "log_group_name": "Test-CloudWatchAgent-logs-access-log"
                    },
                    {
                        "file_path": "/var/log/httpd/error_log",
                        "log_group_name": "Test-CloudWatchAgent-logs-error-log"
                    }
                ]
            }
        }
    },
    "metrics": {
        "append_dimensions": {
            "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
            "ImageId": "${aws:ImageId}",
            "InstanceId": "${aws:InstanceId}",
            "InstanceType": "${aws:InstanceType}"
        },
        "metrics_collected": {
            "collectd": {
                "metrics_aggregation_interval": 60
            },
            "mem": {
                "measurement": [
                    "mem_used_percent"
                ],
                "metrics_collection_interval": 60
            },
            "statsd": {
                "metrics_aggregation_interval": 60,
                "metrics_collection_interval": 10,
                "service_address": ":8125"
            },
            "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.

最後に、Systems Manager パラメータストア へ作成した設定を転送するか聞かれるので、転送しておく (スケールアウト時に作成される新サーバー用の設定を一元管理するための仕組み)。

parameter store name については、プレフィックスとして AmazonCloudWatch- を付与しないと IAM ポリシーの制限より動作しないので要注意。 また、AutoScaling グループ名を付加したりして分かりやすい名前をつけよう。

Do you want to store the config in the SSM parameter store?
1. yes
2. no
default choice: [1]:
1

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-CloudWatchAgent

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]

Which AWS credential should be used to send json config to parameter store?
1. XXXXXXXXXXXXXXXXXXXX(From SDK)
2. Other
default choice: [1]:

Successfully put config to parameter store AmazonCloudWatch-Test-CloudWatchAgent.
Program exits now.

転送された。

Run Command を用いて、CloudWatch エージェントを起動

やはり SSH は使わせたくないらしい。
先程と同様に、RunCommand の画面で AmazonCloudWatch-ManageAgent を選択。

  • Optional Configuration Source = ssm
  • Optional Configuration Location = 先のウィザードで parameter store name として設定した値

これで、すんなり起動できると思うじゃん……?

CloudWatch Logs の /aws/ssm/AmazonCloudWatch-ManageAgent

/opt/aws/amazon-cloudwatch-agent/bin/config-downloader --output-file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json --download-source ssm:AmazonCloudWatch-Test-CloudWatchAgent --mode ec2 --config /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml
Region: ap-northeast-1
credsConfig: map[]
Start configuration validation...
/opt/aws/amazon-cloudwatch-agent/bin/config-translator --input /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json --output /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml --mode ec2 --config /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml
Valid Json input schema.
Configuration validation first phase succeeded
/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 failed
======== Error Log ========
2018/10/24 08:18:35 I! AmazonCloudWatchAgent Version 1.203420.0.
2018/10/24 08:18:35 E! Error parsing /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml, open /usr/share/collectd/types.db: no such file or directory

なにかファイルが足りないらしく、失敗……

EPEL リポジトリを追加。

# yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

足りないファイルは collectd というパッケージで提供されるらしい。

# yum provides /usr/share/collectd/types.db
読み込んだプラグイン:langpacks, priorities, update-motd
180 packages excluded due to repository priority protections
リポジトリー        : epel
一致          :
ファイル名    : /usr/share/collectd/types.db



collectd-5.8.0-4.el7.x86_64 : Statistics collection daemon for filling RRD files
リポジトリー        : @epel
一致          :
ファイル名    : /usr/share/collectd/types.db

とりあえずインストール (インストールすれば、起動はしなくても良いらしい)。

# yum install collectd
# systemctl list-unit-files
.
.
.
collectd.service                              disabled

再度、 Run Command で起動コマンドを実行すると成功するはず。

# ps auxwwf
.
.
.
root      3977  0.1  0.5 626600 22176 ?        Ssl  08:22   0:00 /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent -pidfile /opt/aws/amazon-cloudwatch-agent/var/amazon-cloudwatch-agent.pid -config /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml

CloudWatch に設定したログやメトリクスが届いてれば成功。

後編へ続く……