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

# ０．はじめに

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

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

# １．EC2Config の最新バージョンへのアップデート
1. 以下のサイトの手順に従って、アップデートします。
    * [EC2Config の最新バージョンのインストール \- Amazon Elastic Compute Cloud](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/UsingConfig_Install.html)

# ２．Amazon EC2 Systems Manager (SSM) エージェントのインストール
1. EC2 インスタンスに割り当てられている IAM Role に「AmazonEC2RoleforSSM」を付与します。
    * ※ 参考 : [複数のWindows Serverにカスタムメトリクスを一括設定する方法 ｜ Developers\.IO](http://dev.classmethod.jp/cloud/aws/windows-server-runcommand-custom-metrics/)
<br><br>
1. 以下のサイトの手順に従って、アップデートします。
    * [SSM エージェントのインストール \- Amazon EC2 Systems Manager](http://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/ssm-agent.html#sysman-install-ssm-win)
<br><br>
1. [2018.03.09追記] 以下のサイトの手順に従って、SSM のログを CloudWatchLogs へ送信する様に設定します。
    * [CloudWatch Logs へのログの送信 \(SSM エージェント\) \- AWS Systems Manager](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/monitoring-ssm-agent.html)
    * 私は、SSM/Log というロググループ名にしました。

# ３．Amazon EC2 Systems Manager (SSM) エージェントを使っての CloudWatch の設定
1. 以下のサイトを参考にしました。
    * [Windows ServerのCloudWatch LogsをSSMで行う ｜ Developers\.IO](http://dev.classmethod.jp/cloud/aws/set_cloudwatch-logs_on_windows-server_with_ssm/)
<br><br>
1. まず、以下の json ファイルを準備します。
    * 78 行目 : "NameSpace": "System/Detail/Windows"
        * これが、カスタム名前空間になります。適当な名称に変更して下さい。
    * 44-69 行目 : 
        * C ドラのメトリクスの設定になります。他のドライブを追加するのであれば、C を D に変えて、行を追加して下さい。
        * 85 行目にも追加するのを忘れずに。

    ```json:Sample-ConfigureCloudWatch-Windows.json
{
    "EngineConfiguration": {
        "PollInterval": "00:00:15",
        "Components": [
            {
                "Id": "CPULoadAverage",
                "FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "CategoryName": "System",
                    "CounterName": "Processor Queue Length",
                    "InstanceName": "",
                    "MetricName": "CPULoadAverage",
                    "Unit": "Percent",
                    "DimensionName": "InstanceId",
                    "DimensionValue": "{instance_id}"
                }
            },
            {
                "Id": "MemoryAvailable",
                "FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "CategoryName": "Memory",
                    "CounterName": "Available Bytes",
                    "InstanceName": "",
                    "MetricName": "MemoryAvailable",
                    "Unit": "Bytes",
                    "DimensionName": "InstanceId",
                    "DimensionValue": "{instance_id}"
                }
            },
            {
                "Id": "MemoryFree",
                "FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "CategoryName": "Memory",
                    "CounterName": "Free & Zero Page List Bytes",
                    "InstanceName": "",
                    "MetricName": "MemoryFree",
                    "Unit": "Bytes",
                    "DimensionName": "InstanceId",
                    "DimensionValue": "{instance_id}"
                }
            },
            {
                "Id": "MemoryCommitLimit",
                "FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "CategoryName": "Memory",
                    "CounterName": "Commit Limit",
                    "InstanceName": "",
                    "MetricName": "MemoryCommitLimit",
                    "Unit": "Bytes",
                    "DimensionName": "InstanceId",
                    "DimensionValue": "{instance_id}"
                }
            },
            {
                "Id": "MemoryCommitted",
                "FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "CategoryName": "Memory",
                    "CounterName": "Committed Bytes",
                    "InstanceName": "",
                    "MetricName": "MemoryCommitted",
                    "Unit": "Bytes",
                    "DimensionName": "InstanceId",
                    "DimensionValue": "{instance_id}"
                }
            },
            {
                "Id": "MemoryCommitUtilization",
                "FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "CategoryName": "Memory",
                    "CounterName": "% Committed Bytes in Use",
                    "InstanceName": "",
                    "MetricName": "MemoryCommitUtilization",
                    "Unit": "Percent",
                    "DimensionName": "InstanceId",
                    "DimensionValue": "{instance_id}"
                }
            },
            {
                "Id": "DiskAvailableMegabytesC",
                "FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "CategoryName": "LogicalDisk",
                    "CounterName": "Free Megabytes",
                    "InstanceName": "C:",
                    "MetricName": "DiskAvailableMegabytesC",
                    "Unit": "Megabytes",
                    "DimensionName": "InstanceId",
                    "DimensionValue": "{instance_id}"
                }
            },
            {
                "Id": "DiskFreePercentC",
                "FullName": "AWS.EC2.Windows.CloudWatch.PerformanceCounterComponent.PerformanceCounterInputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters": {
                    "CategoryName": "LogicalDisk",
                    "CounterName": "% Free Space",
                    "InstanceName": "C:",
                    "MetricName": "DiskFreePercentC",
                    "Unit": "Percent",
                    "DimensionName": "InstanceId",
                    "DimensionValue": "{instance_id}"
                }
            },
            {
                "Id": "CloudWatch",
                "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatch.CloudWatchOutputComponent,AWS.EC2.Windows.CloudWatch",
                "Parameters":
                {
                    "AccessKey": "",
                    "SecretKey": "",
                    "Region": "ap-northeast-1",
                    "NameSpace": "System/Detail/Windows"
                }
            }
        ],
        "Flows": {
            "Flows":
            [
                "(CPULoadAverage,MemoryAvailable,MemoryFree,MemoryCommitLimit,MemoryCommitted,MemoryCommitUtilization,DiskAvailableMegabytesC,DiskFreePercentC),CloudWatch"
            ]
        }
    }
}
    ```
<br>
1. EC2 のマネジメントコンソールの左側ペインから、「SYSTEMS MANAGER 共有リソース」→「マネージドインスタンス」を選択します。対象となる EC2 インスタンスが表示されるはずなので選択し(表示されなければ、これまでの手順に何か問題があるのかも？)、「関連付けの作成」ボタンを押下します。
<br>
    * ![FireShot Capture 152 - EC2 Management C_ - https___ap-northeast-1.console.aws.amazon.com_ec2_v2_home.png](https://qiita-image-store.s3.amazonaws.com/0/161939/9843ec53-c31f-a1c4-e4ab-4e24f02f4219.png)
<br><br>
1. 「関連付けの作成」画面が表示されるので、以下の項目を入力し、「関連付けの作成」ボタンを押下します。
    * 関連付けの名前 : Sample-ConfigureCloudWatch-Windows　※ 任意
    * ドキュメントを選択
        * ドキュメント : AWS-ConfigureCloudWatch
        * バージョンの説明 : -
    * ターゲット　※ 対象となる EC2 インスタンスが設定されれば OK。
        * ターゲットの選択 : インスタンスの手動選択　※ 任意
        * インスタンスの選択 : 対象となる EC2 インスタンス
    * スケジュール
        * 指定 : Cron スケジュールビルダー　※ デフォルト
        * 関連付けの実行 : 30 分ごと　※ デフォルト
    * パラメーター
        * Status : Enabled　※ デフォルト
        * Properties : ※ json ファイルの内容をコピペ
    * 詳細設定
        * S3 への書き込み : □　※ デフォルト
<br><br>
    * ![FireShot Capture 153 - EC2 Management C_ - https___ap-northeast-1.console.aws.amazon.com_ec2_v2_home.png](https://qiita-image-store.s3.amazonaws.com/0/161939/4e0ea802-e2f8-dc40-c28a-df32958a0d4b.png)
<br><br>
1. 「関連付けの作成」の結果画面が表示されるので、「閉じる」ボタンを押下します。
<br>
    * ![FireShot Capture 158 - EC2 Management C_ - https___ap-northeast-1.console.aws.amazon.com_ec2_v2_home.png](https://qiita-image-store.s3.amazonaws.com/0/161939/3dc2691f-981f-efcf-dd18-c566cb3baefb.png)
<br><br>
1. 元の一覧画面が表示されるので、関連付けがちゃんと作成されているか確認します。
    * ※しばらくすると、ステータスが「保留中」から「成功」に変わるはずです。
<br><br>
    * ![FireShot Capture 159 - EC2 Management C_ - https___ap-northeast-1.console.aws.amazon.com_ec2_v2_home.png](https://qiita-image-store.s3.amazonaws.com/0/161939/cbfceb24-b019-9f5a-f42f-3105bc30eb8c.png)
<br><br>
    * ![FireShot Capture 160 - EC2 Management C_ - https___ap-northeast-1.console.aws.amazon.com_ec2_v2_home_.png](https://qiita-image-store.s3.amazonaws.com/0/161939/a21134d5-c0d1-8c60-24e6-8760c2d0fd36.png)
<br><br>
1. CloudWatch のマネジメントコンソールの左側ペインから、「メトリクス」を選択します。設定したカスタム名前空間と EC2 インスタンスの ID でフィルタをかけて、設定したメトリクスのデータがあるか確認します。
<br>
    * ![FireShot Capture 161 - CloudWatch Management Console_ - https___ap-northeast-1.console.aws_.png](https://qiita-image-store.s3.amazonaws.com/0/161939/0fdf2e55-40ad-da62-1526-04b0af46c183.png)

# ４．Amazon EC2 Systems Manager (SSM) エージェントを使っての CloudWatch Logs の設定
1. CloudWatch Logs の設定も、CloudWatch の手順と同じです。違うのは、json ファイルの設定内容だけです。
<br><br>
1. 以下、EventLog の json ファイルです。
    * 36 行目 : "LogGroup": "Windows/EventLog"
        * ロググループです。適当な名称に変更して下さい。
    * 10,18,26 行目 : 
        * 出力レベルです。適当な値に変更して下さい。

    ```json:Sample-ConfigureCloudWatchLogs-Windows_EventLog.json
    {
        "EngineConfiguration": {
            "PollInterval": "00:00:15",
            "Components": [
                {
                    "Id": "ApplicationEventLog",
                    "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                    "Parameters": {
                        "LogName": "Application",
                        "Levels": "7"
                    }
                },
                {
                    "Id": "SystemEventLog",
                    "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                    "Parameters": {
                        "LogName": "System",
                        "Levels": "7"
                    }
                },
                {
                    "Id": "SecurityEventLog",
                    "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                    "Parameters": {
                    "LogName": "Security",
                    "Levels": "7"
                    }
                },
                {
                    "Id": "CloudWatchLogs",
                    "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                    "Parameters": {
                        "AccessKey": "",
                        "SecretKey": "",
                        "Region": "ap-northeast-1",
                        "LogGroup": "Windows/EventLog",
                        "LogStream": "{instance_id}"
                    }
                }
            ],
            "Flows": {
                "Flows":
                [
                    "(ApplicationEventLog,SystemEventLog,SecurityEventLog),CloudWatchLogs"
                ]
            }
        }
    }
    ```
<br>
1. 以下、IIS ログの json ファイルです。
    * 22 行目 : "LogGroup": "Windows/IisLog"
        * ロググループです。適当な名称に変更して下さい。
    * 5-14 行目 : 
        * サイト毎の設定となります。W3SVC1 以外にも取得したのであれば、変更し行を追加して下さい。
        * 30 行目にも追加するのを忘れずに。

    ```json:Sample-ConfigureCloudWatchLogs-Windows_IisLog.json
    {
        "EngineConfiguration": {
            "PollInterval": "00:00:15",
            "Components": [
                {
                    "Id": "IISLogW3SVC1",
                    "FullName": "AWS.EC2.Windows.CloudWatch.IisLog.IisLogInputComponent,AWS.EC2.Windows.CloudWatch",
                    "Parameters": {
                        "LogName": "IISLogW3SVC1",
                        "LogDirectoryPath": "C:\\inetpub\\logs\\LogFiles\\W3SVC1",
                        "TimestampFormat": "yyyy-MM-dd HH:mm:ss",
                        "Encoding": "UTF-8"
                    }
                },
                {
                    "Id": "CloudWatchLogs",
                    "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                    "Parameters": {
                        "AccessKey": "",
                        "SecretKey": "",
                        "Region": "ap-northeast-1",
                        "LogGroup": "Windows/IisLog",
                        "LogStream": "{instance_id}"
                    }
                }
            ],
            "Flows": {
                "Flows":
                [
                    "(IISLogW3SVC1),CloudWatchLogs"
                ]
            }
         }
    }
    ```
<br>
1. 以下、カスタムログの json ファイルです。
    * 24 行目 : "LogGroup": "Windows/CustomLog"
        * ロググループです。適当な名称に変更して下さい。
    * 5-16 行目 : 
        * 取得したいログファイル毎の設定となります。適宜変更して下さい。
    * ※すいません。こちら未確認です…。

    ```json:Sample-ConfigureCloudWatchLogs-Windows_CustomLog.json
    {
        "EngineConfiguration": {
            "PollInterval": "00:00:15",
            "Components": [
                {
                    "Id": "CustomLogs",
                    "FullName": "AWS.EC2.Windows.CloudWatch.CustomLog.CustomLogInputComponent,AWS.EC2.Windows.CloudWatch",
                    "Parameters": {
                        "LogDirectoryPath": "C:\\CustomLogs\\",
                        "TimestampFormat": "MM/dd/yyyy HH:mm:ss",
                        "Encoding": "UTF-8",
                        "Filter": "",
                        "CultureName": "en-US",
                        "TimeZoneKind": "Local"
                    }
                },
                {
                    "Id": "CloudWatchLogs",
                    "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                    "Parameters": {
                        "AccessKey": "",
                        "SecretKey": "",
                        "Region": "ap-northeast-1",
                        "LogGroup": "Windows/CustomLog",
                        "LogStream": "{instance_id}"
                    }
                }
            ],
            "Flows": {
                "Flows":
                [
                    "(CustomLogs),CloudWatchLogs"
                ]
            }
        }
    }
    ```
<br>
1. 以下、ETW の json ファイルです。
    * 24 行目 : "LogGroup": "Windows/ETW"
        * ロググループです。適当な名称に変更して下さい。
    * 5-16 行目 : 
        * 取得したいログファイル毎の設定となります。適宜変更して下さい。
    * ※すいません。こちら未確認です…。

    ```json:Sample-ConfigureCloudWatchLogs-Windows_ETW.json
    {
        "EngineConfiguration": {
            "PollInterval": "00:00:15",
            "Components": [
                {
                    "Id": "ETW",
                    "FullName": "AWS.EC2.Windows.CloudWatch.EventLog.EventLogInputComponent,AWS.EC2.Windows.CloudWatch",
                    "Parameters": {
                        "LogName": "Microsoft-Windows-WinINet/Analytic",
                        "Levels": "4"
                    }
                },
                {
                    "Id": "CloudWatchLogs",
                    "FullName": "AWS.EC2.Windows.CloudWatch.CloudWatchLogsOutput,AWS.EC2.Windows.CloudWatch",
                    "Parameters": {
                        "AccessKey": "",
                        "SecretKey": "",
                        "Region": "ap-northeast-1",
                        "LogGroup": "Windows/ETW",
                        "LogStream": "{instance_id}"
                    }
                }
            ],
            "Flows": {
                "Flows":
                [
                    "(ETW),CloudWatchLogs"
                ]
            }
        }
    }
    ```
<br>
1. CloudWatch のマネジメントコンソールの左側ペインから、「ログ」を選択します。ロググループの一覧が表示されるので、設定したロググループと EC2 インスタンスの ID でフィルタをかけて、設定したログのデータがあるか確認します。
<br>
    * ![FireShot Capture 162 - CloudWatch Management Console_ - https___ap-northeast-1.console.aws.png](https://qiita-image-store.s3.amazonaws.com/0/161939/07550b92-3366-1f26-4ecd-c6ccd55b2ca4.png)
<br><br>
    * ![FireShot Capture 163 - CloudWatch Management Console_ - https___ap-northeast-1.console.aws.png](https://qiita-image-store.s3.amazonaws.com/0/161939/8b8931d8-479b-b778-5dbc-1f4dcd4dec0b.png)
<br><br>
    * ![FireShot Capture 164 - CloudWatch Management Console_ - https___ap-northeast-1.console.aws_.png](https://qiita-image-store.s3.amazonaws.com/0/161939/2609cd22-e2aa-9423-bc41-698fa61e20a8.png)

# ９９．ハマりポイント

* 今回も結構ハマりました…。毎回、何やってんだ…。
<br><br>
* 最初、今回の手順ではなく「SYSTEMS MANAGER 共有リソース」にある「ドキュメント」を作成して対応しようと思ったんですが、ドキュメントの作成がうまくいかず…、断念…。サポートセンターに問い合わせ中です。
<br><br>
* その後、今回の手順で設定を進めたんですが、json ファイルの設定内容でハマりました。特にディスクの空容量のメトリクスの取得とかがよくわからず、難儀しました。こちらのサイトで何とか解決しました。ありがとうございます。
    * [Amazon CloudWatch編～Windows Server2012でカスタムメトリクスを設定してみた～ \| CloudWatch WindowsServer \| ナレコムAWSレシピ](https://recipe.kc-cloud.jp/archives/8732)

# ＸＸ．まとめ

これで、
何とか運用監視も AWS だけで事足りる様になるのではと。

CloudWatch の 15ヶ月のデータ保存じゃ短すぎる!!
という場合は、
こちらのサイトのやり方などもあるみたいです。

* [【そんなときどうする？】DynamoDBのデータを可視化したい！　LambdaのBlueprintを使って、Elasticsearch Serviceと簡単連携 – サーバーワークスエンジニアブログ](http://blog.serverworks.co.jp/tech/2016/05/30/elasticsearch-service/)