AWS CloudWatch で、Amazon Linux のパフォーマンスとログの監視をしてみる

# ０．はじめに

Amazon Linuxを利用していますが、
パフォーマンス監視は Zabbix を使って、
ログ監視は特に何も、
という感じでした。

CloudWatch のメトリクスの保存期間も長くなったみたいですし、
運用の手間やリスク、コスト削減も考慮して、
パフォーマンス監視を CloudWatch、
ログ監視を CloudWatch Logs、
にしようかと思います。

# １．IAM Role へのポリシーのアタッチ
1. 以下の IAM ポリシーを作成します。
    * ポリシー名 : GSCloudWatchWriteOnlyAccess　※ 任意
    * 説明 : ※ 任意
    * ポリシードキュメント : 
 
    ```
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Stmt1459146265000",
                "Effect": "Allow",
                "Action": [
                    "cloudwatch:PutMetricData"
                ],
                "Resource": [
                    "*"
                ]
            },
            {
                "Sid": "Stmt1459146665000",
                "Effect": "Allow",
                "Action": [
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream",
                    "logs:PutLogEvents"
                ],
                "Resource": [
                    "arn:aws:logs:*:*:*"
                ]
            }
        ]
    }
    ```
<br>
1. 作成したポリシーを EC2 インスタンスに割り当てられている IAM Role に付与します。

# ２．CloudWatch へのメトリクスデータの送信
1. 色々調べたところ、collectd と その CloudWatch 用プラグインを利用するのが一般的みたいなので、今回はその手順で進めていきます。
<br><br>
    * [新しい collectd の CloudWatch プラグイン \| Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/new-cloudwatch-plugin-for-collectd/)
    * [collectdのCloudWatchプラグインを試してみた ｜ Developers\.IO](http://dev.classmethod.jp/cloud/aws/collectd-cloudwatch/)
    * [EC2のメモリ使用量とdisk使用量をcollectdでサクッとCloudWatchに登録 \- Qiita](https://qiita.com/wadatin/items/7236aafe5a3f553d86ff)
<br><br>
1. collectd をインストールします。

    ```bash
    $ sudo yum -y install collectd
    ```
<br>
1. collectd の CloudWatch 用プラグインをインストールします。

    ```bash
    $ sudo git clone https://github.com/awslabs/collectd-cloudwatch.git
    $ cd collectd-cloudwatch/src
    $ sudo ./setup.py

    Installing dependencies ... OK
    Installing python dependencies ... OK
    Downloading plugin ... OK
    Extracting plugin ... OK
    Moving to collectd plugins directory ... OK
    Copying CloudWatch plugin include file ... OK
    
    Choose AWS region for published metrics:
      1. Automatic [ap-northeast-1]
      2. Custom
    Enter choice [1]: 
    
    Choose hostname for published metrics:
      1. EC2 instance id [i-00484bb5ac67e244d]
      2. Custom
    Enter choice [1]: 
    
    Choose authentication method:
      1. IAM Role [testuekamawindowsserver]
      2. IAM User
    Enter choice [1]: 
    
    Enter proxy server name:
      1. None
      2. Custom
    Enter choice [1]: 
    
    Enter proxy server port:
      1. None
      2. Custom
    Enter choice [1]: 
    
    Include the Auto-Scaling Group name as a metric dimension:
      1. No
      2. Yes
    Enter choice [1]: 
    
    Include the FixedDimension as a metric dimension:
      1. No
      2. Yes
    Enter choice [1]: 
    
    Enable high resolution:
      1. Yes
      2. No
    Enter choice [2]: 
    
    Enter flush internal:
      1. Default 60s
      2. Custom
    Enter choice [1]: 
    
    Choose how to install CloudWatch plugin in collectd:
      1. Do not modify existing collectd configuration
      2. Add plugin to the existing configuration
      3. Use CloudWatch recommended configuration (4 metrics)
    Enter choice [3]: 
    Plugin configuration written successfully.
    Creating backup of the original configuration ... OK
    Replacing collectd configuration ... OK
    Replacing whitelist configuration ... OK
    Stopping collectd process ... NOT OK
    Starting collectd process ... NOT OK
    Installation cancelled due to an error.
    Executed command: '/usr/sbin/collectd'.
    Error output: 'Error: Reading the config file failed!
    Read the syslog for details.'.
    ```
<br>
1. collectd の起動に失敗しています。collectd の python 用ライブラリが足りないみたいなので、インストールします。
    * 参考 : [\[error\] plugin\_load: Could not find plugin "python" in /usr/lib64/collectd · Issue \#48 · awslabs/collectd\-cloudwatch · GitHub](https://github.com/awslabs/collectd-cloudwatch/issues/48)
<br><br>

    ```bash
    $ sudo yum -y install collectd-python
    ```
<br>
1. collectd を起動します。

    ```bash
    $ sudo service collectd start
    ```
<br>
1. collectd の自動起動の設定をします。

    ```bash
    $ sudo chkconfig collectd on
    $ sudo chkconfig --list | grep collectd

    collectd           0:off    1:off    2:on    3:on    4:on    5:on    6:off
    ```
<br>
1. /etc/collectd.conf の設定を変更します。

    ```bash
    $ sudo cp -frp /etc/collectd.conf /etc/collectd.conf.ORG
    $ sudo vi /etc/collectd.conf
    ```
    * cpu : 
        * LoadPlugin cpu をコメント解除し、以下の設定を行う。

        ```
        <Plugin cpu>
                ReportByCpu false
                ReportByState true
                ValuesPercentage true
        </Plugin>
        ```
    * df : 
        * LoadPlugin df をコメント解除し、以下の設定を行う。

        ```
        <Plugin df>
        #       Device "/dev/hda1" 
        #       Device "192.168.0.2:/mnt/nfs" 
        #       MountPoint "/home" 
        #       FSType "ext3" 
        #       IgnoreSelected false
                ReportByDevice false
                ReportInodes false
                ValuesAbsolute true
                ValuesPercentage true
        </Plugin>
        ```
    * load : 
        * LoadPlugin load をコメント解除し、以下の設定を行う。

        ```
        <Plugin load>
                ReportRelative true
        </Plugin>
        ```
    * memory : 
        * LoadPlugin memory をコメント解除し、以下の設定を行う。

        ```
        <Plugin memory>
                ValuesAbsolute true
                ValuesPercentage true
        </Plugin>
        ```
    * swap : 
        * LoadPlugin swap をコメント解除し、以下の設定を行う。

        ```
        <Plugin swap>
                ReportByDevice false
                ReportBytes false
                ValuesAbsolute false
                ValuesPercentage true
        </Plugin>
        ```
<br>
1. /opt/collectd-plugins/cloudwatch/config/whitelist.conf の設定を変更します。以下のメトリクスの中で不要なものがあれば、適当に削除して下さい。
    * 参考 : [GitHub \- SungardAS/collectd\-docker: collectd container to collect metrics and currently forwards them to Cloudwatch](https://github.com/SungardAS/collectd-docker)

    ```bash
    $ cd /opt/collectd-plugins/cloudwatch/config/
    $ sudo cp -frp whitelist.conf whitelist.conf.ORG
    $ sudo vi whitelist.conf
    ```

    ```
cpu-.*
df-root-df_complex-free
df-root-df_complex-reserved
df-root-df_complex-used
df-root-percent_bytes-free
df-root-percent_bytes-reserved
df-root-percent_bytes-used
load--load-relative
memory--percent-free
memory--percent-used
memory--memory-free
memory--memory-used
swap--percent-cached
swap--percent-free
swap--percent-used
    ```
<br>
1. collectd を再起動します。

    ```bash
    $ sudo service collectd restart
    ```
<br>
1. CloudWatch のマネジメントコンソールの左側ペインから、「メトリクス」を選択します。カスタム名前空間の「collectd」→「Host, PluginInstance」→ EC2 インスタンスの ID でフィルタをかけて、設定したメトリクスのデータがあるか確認します。
<br>
    * ![FireShot Capture 165 - CloudWatch Management Console_ - https___ap-northeast-1.console.aws.png](https://qiita-image-store.s3.amazonaws.com/0/161939/d952ceb1-5a43-8d89-3621-7f85abf21c21.png)
<br><br>
    * ![FireShot Capture 166 - CloudWatch Management Console_ - https___ap-northeast-1.console.aws.png](https://qiita-image-store.s3.amazonaws.com/0/161939/d78d65dc-961e-a4e1-b649-ee8e31b62c3a.png)
<br><br>
    * ![FireShot Capture 171 - CloudWatch Management Console_ - https___ap-northeast-1.console.aws.png](https://qiita-image-store.s3.amazonaws.com/0/161939/0c23bf63-7825-2423-27ae-6237a335e95c.png)

# ３．CloudWatch Logs へのログデータの送信
1. awslogs をインストールします。

    ```bash
    $ sudo yum -y install awslogs
    ```
<br>
1. /etc/awslogs/awscli.conf の設定を変更します。

    ```bash
    $ sudo cp -frp /etc/awslogs/awscli.conf /etc/awslogs/awscli.conf.ORG
    $ sudo vi /etc/awslogs/awscli.conf
    ```

    ```
    [plugins]
    cwlogs = cwlogs
    [default]
    region = ap-northeast-1
    ```
<br>
1. /etc/awslogs/awslogs.conf の設定を変更します。
    * apache や nginx の設定もしています。不要であれば、削除して下さい。

    ```bash
    $ sudo cp -frp /etc/awslogs/awslogs.conf /etc/awslogs/awslogs.conf.ORG
    $ sudo vi /etc/awslogs/awslogs.conf
    ```

    ```
    [/var/log/messages]
    datetime_format = %b %d %H:%M:%S
    file = /var/log/messages
    buffer_duration = 5000
    log_stream_name = {instance_id}
    initial_position = start_of_file
    log_group_name = AmazonLinux/var/log/messages
    
    [/var/log/cron]
    datetime_format = %b %d %H:%M:%S
    file = /var/log/cron
    buffer_duration = 5000
    log_stream_name = {instance_id}
    initial_position = start_of_file
    log_group_name = AmazonLinux/var/log/cron
    
    [/etc/httpd/logs/access_log]
    datetime_format = [%a %b %d %H:%M:%S %Y]
    file = /etc/httpd/logs/access_log
    buffer_duration = 5000
    log_stream_name = {instance_id}
    initial_position = start_of_file
    log_group_name = AmazonLinux/etc/httpd/logs/access_log
    
    [/etc/httpd/logs/error_log]
    datetime_format = [%a %b %d %H:%M:%S %Y]
    file = /etc/httpd/logs/error_log
    buffer_duration = 5000
    log_stream_name = {instance_id}
    initial_position = start_of_file
    log_group_name = AmazonLinux/etc/httpd/logs/error_log
    
    [/etc/httpd/logs/ssl_access_log]
    datetime_format = [%a %b %d %H:%M:%S %Y]
    file = /etc/httpd/logs/ssl_access_log
    buffer_duration = 5000
    log_stream_name = {instance_id}
    initial_position = start_of_file
    log_group_name = AmazonLinux/etc/httpd/logs/ssl_access_log
    
    [/etc/httpd/logs/ssl_error_log]
    datetime_format = [%a %b %d %H:%M:%S %Y]
    file = /etc/httpd/logs/ssl_error_log
    buffer_duration = 5000
    log_stream_name = {instance_id}
    initial_position = start_of_file
    log_group_name = AmazonLinux/etc/httpd/logs/ssl_error_log
    
    [/etc/httpd/logs/ssl_request_log]
    datetime_format = [%a %b %d %H:%M:%S %Y]
    file = /etc/httpd/logs/ssl_request_log
    buffer_duration = 5000
    log_stream_name = {instance_id}
    initial_position = start_of_file
    log_group_name = AmazonLinux/etc/httpd/logs/ssl_request_log
    
    [/var/log/nginx/access.log]
    datetime_format = %Y/%m/%d %H:%M:%S
    file = /var/log/nginx/access.log
    buffer_duration = 5000
    log_stream_name = {instance_id}
    initial_position = start_of_file
    log_group_name = AmazonLinux/var/log/nginx/access.log
    
    [/var/log/nginx/backend.access.log]
    datetime_format = %Y/%m/%d %H:%M:%S
    file = /var/log/nginx/access.log
    buffer_duration = 5000
    log_stream_name = {instance_id}
    initial_position = start_of_file
    log_group_name = AmazonLinux/var/log/nginx/backend.access.log
    
    [/var/log/nginx/badactor.log]
    datetime_format = %Y/%m/%d %H:%M:%S
    file = /var/log/nginx/badactor.log
    buffer_duration = 5000
    log_stream_name = {instance_id}
    initial_position = start_of_file
    log_group_name = AmazonLinux/var/log/nginx/badactor.log
    
    [/var/log/nginx/error.log]
    datetime_format = %Y/%m/%d %H:%M:%S
    file = /var/log/nginx/error.log
    buffer_duration = 5000
    log_stream_name = {instance_id}
    initial_position = start_of_file
    log_group_name = AmazonLinux/var/log/nginx/error.log
    ```
<br>
1. awslogs を起動します。

    ```bash
    $ sudo service awslogs start
    ```
<br>
1. awslogs の自動起動の設定をします。

    ```bash
    $ sudo chkconfig awslogs on
    $ sudo chkconfig --list | grep awslogs

    awslogs            0:off    1:off    2:on    3:on    4:on    5:on    6:off
    ```

# ９９．ハマりポイント

* 今回は、凡ミスばかりで本当に自分が嫌になりました…。もう、毎回、何やってんだ…。
<br><br>
* CloudWatch へのメトリクスデータの送信では、 CloudWatch のカスタム名前空間の「collectd」ではなく、AWS の EC2 のフィルタに表示されると勘違いして、全然ログが出てこないと悩んでいました…。もう、本当馬鹿…。
<br><br>
* 後、/etc/collectd.conf の設定も結構悩みました。
<br><br>
* CloudWatch Logs へのログデータの送信では、/etc/awslogs/awscli.conf の設定を /etc/awslogs/awslogs.conf にすると勘違いして、本当に無駄な時間を浪費しました…。

# ＸＸ．まとめ



以下、参考にさせて頂いたサイトです。
ありがとうございました。

* [CloudWatch Logs エージェントのリファレンス \- Amazon CloudWatch ログ](http://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AgentReference.html)
* [AWSの監視に便利なAmazon CloudWatch Logsの使い方 \- WPJ](https://www.webprofessional.jp/monitoring-of-aws-cloudwatch/)
* [AWS EC2インスタンス CloudWatch Logs\(awslogs\)インストールとCloudWatch保存対象ログの追加 \- Qiita](https://qiita.com/na0AaooQ/items/a3b0e5384399b66b742b)
* [Amazon CloudWatch Logsでログファイルを監視する ｜ Developers\.IO](http://dev.classmethod.jp/cloud/aws/amazon-cloudwatch-logs/)
* [CloudWatch LogsでLinuxのログファイル監視を試してみた \| mooapp](https://moomindani.wordpress.com/2014/07/11/cloudwatch-logs-try/)
* [\[AWS\]CloudWatch Log エージェントインストールと設定/ansibleも作ってみた – ADACHIN SERVER Lab](https://blog.adachin.me/wordpress/archives/4662)