【CloudWatch】EC2のメモリ監視&ログ収集

公開:2021/02/01
更新:2021/02/07
20 min読了の目安(約18100字TECH技術記事

はじめに

CloudWatchはAWSリソースの状態を収集したり、監視したり、通知をしたり、分析をしたりすることができる非常に有用なAWSサービスである。

AWSのマネージメントコンソールでCloudWatchにアクセスすると、EC2のCPU使用率、ディスクIOなど様々リソースに関するデータを確認することができる。
これらの収集されたデータをメトリクスという。

ただし、デフォルトで監視できるメトリクスには限りがあり、メモリ使用率等は設定を追加しないと監視することができない。
このようなユーザーの設定を追加しないと監視できないメトリクスをカスタムメトリクスという。

今回は、このカスタムメトリクスの設定を追加し、EC2のメモリ監視を行った。
また、リソース監視の他にログの収集を行ってみたいと思う。

ゴール

今回メモリ監視、ログ収集を行う構成は上記の図の通り。
上記構成は、以下の記事で作成しているので詳細は割愛する。

https://zenn.dev/soshimiyamoto/articles/2d835cf2c3fb5a

上記の構成図のEC2から、

  • Apacheのアクセスログの収集
  • メモリ使用率の監視

を行ってみる。

手順

大まかには以下の手順で行う。

  1. IAMロールの作成&EC2にアタッチ
  2. SSMエージェントのインストール
  3. CloudWatchエージェントのインストール
  4. CloudWatchエージェントの設定変更
  5. エージェントの起動
  6. 動作確認

実際に設定してみる

1. IAMロールの作成&EC2にアタッチ

本当はこれくらいの作業ならマネージメントコンソールでポチポチと作成して、EC2にアタッチ!ってやればよかったのだが、どうせなら環境構築のところからCloudFormationで一気に作成!ってやりたかったので、CloudFormationでIAMロール作成とEC2にアタッチを同時に行う。

wordpress_tmeplate.yaml(中略)
   #  IAM Role
  # ------------------------------------------------------------#
  CloudWatchAgentAdminRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          Effect: "Allow"
          Principal:
            Service:
            - "ec2.amazonaws.com"
          Action:
            - "sts:AssumeRole"
      Path: "/"
      RoleName: CloudWatchAgentAdminRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM
        - arn:aws:iam::aws:policy/CloudWatchAgentAdminPolicy
      Tags: 
        - Key: Name
          Value: CloudWatchAgentAdminRole
  • IAMロールは"AWS::IAM::Roleで作成する。
  • AssumeRolePolicyDocumentは必須項目であり、いわゆる画面で設定するところの「信頼関係」を表す。
    そのIAMロールを使用するサービスを表すPrincipal等を設定する。
  • 今回は、AWSが用意しているポリシーを利用するため、ManagedPolicyArnsプロパティを利用して以下のポリシーを付与した。
    • AmazonEC2RoleforSSM : AWS Systems Managerを利用するための権限
    • CloudWatchAgentAdminPolicy : CloudWatchAgentを設定したり、ログやメトリクスをCloudWatchに送信したりするための権限


wordpress_tmeplate.yaml(中略)
  # ------------------------------------------------------------#
  #  IAM Instance Profile
  # ------------------------------------------------------------#
  InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: "/"
      Roles:
      - !Ref CloudWatchAgentAdminRole
  # ------------------------------------------------------------#
  • IAMロールをアタッチするためにインスタンスプロファイルを作成する。
    EC2インスタンスに直接IAMロールをアタッチするのではなく、実はインスタンスプロファイルなる箱を作ってそこに情報を渡しており、そのプロファイルがアタッチされているのである。
    以下がわかりやすい。

https://dev.classmethod.jp/articles/do_you_know_iaminstanceprofile/
wordpress_tmeplate.yaml(中略)
  # ------------------------------------------------------------#
  #  EC2
  # ------------------------------------------------------------#
  
  WebServer: 
    Type: AWS::EC2::Instance
    Properties: 
      # 中略
      IamInstanceProfile: !Ref InstanceProfile
      # 中略
  • EC2にIAMロールを付与するにはIamInstanceProfileプロパティを使用する。

IAMロールを作成するだけでもCloudFormationで作成すると、細かい設定まで知ることができて勉強になるのでお勧めする。

ちなみに上記で作成すると、環境が立ち上がった時点で以下のようにIAMロールがアタッチされていることがわかる。

2. SSMエージェントのインストール

  • SSMエージェントとは

AWS Systems Manager は、AWS でインフラストラクチャを表示および制御するために使用できる AWS のサービスです。Systems Manager コンソールを使用すると、複数の AWS のサービスのオペレーションデータを表示して、AWS リソース間でオペレーションタスクを自動化することができます。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/what-is-systems-manager.html

AWS Systems Manager (SSM) とは上記の通りで、このサービスを使うと、SSMエージェントをインストールしている複数のインスタンスに対して、コマンドを送信したり、パッチを当てたりするなど様々なことができるようになる。

今回は、SSMを使ってCloudWatchエージェントのインストールと設定を行ってみる。
以下のコマンドでインストールする。

yum -y install https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm

3. CloudWatchエージェントのインストール

  • サービス > Systems Manager の左ペインから「Run Command」を選択する。
  • 「コマンドの実行」を押下
  • 「AWS-ConfigureAWSPackage」を選択
  • Nameに「AmazonCloudWatchAgent」, Versionに「latest」を入力
項目 設定値
Action Install
Installation Type Uninstall and reinstall
Name AmazonCloudWatchAgent
Additional Arguments 0
  • ターゲットで、「インスタンスを手動で選択する」を選択し、エージェントをインストール対象のEC2インスタンスを選択する。

この時、AmazonEC2RoleforSSMのポリシーがアタッチされていないと、選択対象のインスタンス一覧に表示されない。

  • 「実行」を押下

  • 成功したことを確認

  • /opt/aws/amazon-cloudwatch-agent/以下にファイルが追加されている。

4. エージェントの設定変更

CloudWatchエージェントの設定の仕方には以下の2種類がある。

  1. ウィザードを使用して CloudWatch エージェント設定ファイルを作成する
  2. CloudWatch エージェント設定ファイルを手動で作成または編集する

今回は、1の方法で設定してみる。

  • EC2にSSHでログインして以下を実行
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

  • 対象サーバーの選択
  • デフォルトのlinuxで良いのでEnterを押下
=============================================================
= Welcome to the AWS CloudWatch Agent Configuration Manager =
=============================================================
On which OS are you planning to use the agent?
1. linux
2. windows
3. darwin
default choice: [1]:

  • EC2かオンプレミスか選択
  • デフォルトのEC2なのでEnterを押下
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]:

  • エージェントを実行するユーザーの選択
  • デフォルトのrootなのでEnterを押下
Which user are you planning to run the agent?
1. root
2. cwagent
3. others
default choice: [1]:

  • StatsD daemonをオンにするか
  • デフォルトの「オンにする」なのでEnterを押下
  • StatsDとはサーバーの統計情報を取得するためのデーモンとのこと。

A network daemon that runs on the Node.js platform and listens for statistics, like counters and timers, sent over UDP or TCP and sends aggregates to one or more pluggable backend services (e.g., Graphite).

https://github.com/statsd/statsd
  • CloudWatchではカスタムメトリクスを収集するために利用されているのこと。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-custom-metrics-statsd.html
Do you want to turn on StatsD daemon?
1. yes
2. no
default choice: [1]:

  • StatsD がどのポートを利用するか
  • デフォルトの8125でよいのEnterを押下
Which port do you want StatsD daemon to listen to?
default choice: [8125]

  • StatsD daemonの収集間隔の指定です。
  • デフォルトの10秒でよいのでEnterを押下
What is the collect interval for StatsD daemon?
1. 10s
2. 30s
3. 60s
default choice: [1]:

  • StatsD daemonによって収集されるデータの時間間隔
  • デフォルトの60秒でよいのでEnterを押下
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を使ってメトリクスを監視するか
  • 利用するのでEnterを押下
  • CollectDとは、サーバーの統計情報を収集するデーモンとのこと。

collectd is a daemon which collects system and application performance metrics periodically and provides mechanisms to store the values in a variety of ways, for example in RRD files.

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

  • CPU, メモリを監視するか
  • 監視するのでEnter
Do you want to monitor any host metrics? e.g. CPU, memory, etc.
1. yes
2. no
default choice: [1]:

  • 1コアあたりのCPUを監視するか。(ただし追加料金が発生する)
  • デフォルトのyesでよいため、Enterを押下
Do you want to monitor cpu metrics per core? Additional CloudWatch charges may apply.
1. yes
2. no
default choice: [1]:

  • EC2のイメージID, インスタンスID なども項目に追加したいか。
  • デフォルトのyesで良いのでEnter
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]:

  • メトリクスを高解像度で収集したいか。
  • デフォルトの60秒で良いのでEnterを押下
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]:

  • どのデフォルトメトリクス設定を適用するか。
  • 今回はメモリの使用量を取得できればいいので、1のBasicを選択
  • Basic, Standard, Advancedで取得できるメトリクスが変わるとのこと。
  • 詳細は以下を参照

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-cloudwatch-agent-configuration-file-wizard.html
Which default metrics config do you want?
1. Basic
2. Standard
3. Advanced
4. None
default choice: [1]:

  • 今までの設定情報が出力される。
  • mem_used_percentを取得する設定なので問題なさそう。
  • このまま次の設定に行くのでEnter
Current config as follows:
{
        "agent": {
                "metrics_collection_interval": 60,
                "run_as_user": "root"
        },
        "metrics": {
                "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 Logエージェントが存在しており、設定を統合するか
  • 存在していないので、デフォルトのEnterを押下
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]:
  • 実はここで少し詰まった。ログ収集の際にはCloudWatchLogエージェントが必要であり、あらかじめこれをインストールする必要があるのではと誤解していた。現在ではCloudWatch Logエージェントの利用は非推奨であり、これをCloudWatchエージェントにマージする際はこれをyesにする必要がある。

廃止が予定されている古い CloudWatch Logs エージェント用です。代わりに統合 CloudWatch エージェントを使用することを強くお勧めします。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AgentReference.html
  • ログファイルを監視したいか。
  • Apacheのアクセスログを収集したいのでデフォルトのyes
  • ログファイルのパスを聞かれるので、「/var/log/httpd/access_log」を入力
  • ロググループの名前:「HttpAccessLog」とした。
  • ログストリーム名:デフォルトのインスタンスIDでよいのでEnter
Do you want to monitor any log files?
1. yes
2. no
default choice: [1]:

Log file path:
/var/log/httpd/access_log
Log group name:
default choice: [access_log]
HttpAccessLog
Log stream name:
default choice: [{instance_id}]

  • 他のログを追加したいか
  • アクセスログだけでよいので、2を入力
Do you want to specify any additional log files to monitor?
1. yes
2. no
default choice: [1]:
2

  • ここまでの設定が表示される。
  • Access Logの設定が追加されていることがわかる。
  • 以下の設定ファイルは/opt/aws/amazon-cloudwatch-agent/bin/config.jsonに保存されているとのこと。
  • この設定をSSMパラメータストアに保存するかと聞かれるのでyes
  • パラメータストアとは、このような設定値を保存することができるサービスで、この設定を他のEC2でも使いまわすことがで着るようになったりする。
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/log/httpd/access_log",
                                                "log_group_name": "access_log",
                                                "log_stream_name": "{instance_id}"
                                        }
                                ]
                        }
                }
        },
        "metrics": {
                "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"
                        }
                }
        }
}
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]:

  • どんな名前でパラメータストアに保存するか。
  • デフォルトのAmazonCloudWatch-linuxでよいので、Enter
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]

  • パラメータストアをどのリージョンに保存するか
  • ap-northeast-1でよいので、Enter
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]

  • どのAWSクレデンシャルを使ってパラメータストアに送信するか。
  • 今回はAmazonEC2RoleForSSMを使ってSSMへのアクセス権限を付与しているためデフォルトの1。
  • 適切なロールがついていないとここでエラー終了する。
Which AWS credential should be used to send json config to parameter store?
1. XXXXXXXXXXXXXXXXXXX(From SDK)
2. Other
default choice: [1]:
1
Successfully put config to parameter store AmazonCloudWatch-linux.
Program exits now.

5. エージェントの起動

ここでは、エージェントを起動して、ログとメトリクスが送信されていることを確認する。

  • サービス > Systems Manager の左ペインから「Run Command」を選択する。

  • 「コマンドの実行」を押下

  • 「AmazonCloudWatch-ManageAgent」を選択

  • Optional Configuration Locationにパラメータ名「AmazonCloudWatch-linux」を入力

項目 設定値
Action Configure
Mode ec2
Optional Configuration Source ssm
Optional Configuration Location AmazonCloudWatch-linux
Optional Open Telemetry Collector Configuration Source
Optional Restart yes
  • ターゲットで、「インスタンスを手動で選択する」を選択し、エージェントをインストール対象のEC2インスタンスを選択する。

  • 「実行」を押下

  • ここで失敗した。

  • ログを見てみる

  • Collectdがないよーと言っているっぽい。

2021-01-31T13:22:06Z E! [telegraf] Error running agent: Error parsing /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml, open /usr/share/collectd/types.db: no such file or directory
  • amazon-lnux-extrasコマンドでインストール
    ※yumではインストールできなかった。(Amazon Linux)
amazon-linux-extras install collectd
  • 再度「実行」を押下して成功したことを確認

6. 動作確認

ここまでで設定を行ったので、ログとメトリクスがCloudWatchに送信されているか確認する。

メトリクスの確認

  • サービス > CloudWatch の左ペインから「メトリクス」を選択

  • CWAgentが追加されていることが確認できるので選択

  • ImageId, InstanceId, InstanceTypeを選択。

  • ちなみにもう一方にはディスク利用量が収集されていた。

  • インスタンス名WebServerのメモリ使用率が取得できていることがわかる。

ログの確認

  • サービス > CloudWatch の左ペインから「ロググループ」を選択

  • 自分で設定したHttpAccessLogが存在することが確認できるので選択

  • 次にログストリームが自分で設定したインスタンスIDになっていることが確認できるので選択

  • ログが収集されていることが確認できる(ヘルスチェックしかアクセスがないが)

注意

  • EC2にCloudWatchAgentAdminPolicyを付与していたが、これだとSSMにパラメータをputできる権限が付与されているので、CloudWatchAgentServerPolicyに置き換えて権限を下げておくとよい。
  • ここでは、AmazonEC2RoleForSSMを利用しているが、実は非推奨らしい。。

https://dev.classmethod.jp/articles/check-amazonec2roleforssm-policy/

まとめ

CloudWatchエージェントを用いてカスタムメトリクスとログがCloudWatchに収集できていることが確認できた。

非常に有用なツールなので是非とも使っていきたい。

ただ、データを溜めすぎるとコストが跳ね上がるので、膨大なデータを入れるのであればS3とかに入れてAthenaでクエリをたたいてQuickSightで可視化するなどの方法もある。
いつかそれをやってみたい。

以上です。