TOP>コラム一覧>【運用監視】CloudWatchAgentで収集したWindowsイベントログのエラーメッセージをメールで運用者に送る方法

【運用監視】CloudWatchAgentで収集したWindowsイベントログのエラーメッセージをメールで運用者に送る方法

はじめに

こんにちは。CTCの北川です。

EC2でWindows Serverを運用する際には、ログメッセージの収集とアラームの設定が非常に重要です。Windowsのイベントログを収集したい場合は、CloudWatch Agentを導入することで、比較的簡単にCloudWatch Logsにログメッセージを収集することができます。
エラーログが発生した際に、アラート通知を行う場合、エラーが発生したことだけを通知すれば良いのであれば、メトリクスフィルターを作成し、フィルターにヒットした際にアラーム通知する設定を行うことで実現が可能です。
しかし、エラー内容も含めてメールで通知したい場合は、CloudWatchだけでは実現が難しく、Lambdaとの連携が必要となります。
この記事では、Lambdaを活用して、イベントログにエラーが出力された際に、エラー内容も含めて運用者へメール通知する方法を解説していきます。

記事としてはWindowsイベントログを取り扱いますが、その他CloudWatch Logsで収集しているデータの多くに適用できるかと思いますので、適宜環境に合わせて設定いただければと存じます。

事前準備

本記事ではあらかじめWindowsServerを起動し、CloudWatchLogsへイベントログが出力されている状態から話を進めます。

事前準備として必要な内容に関しては以下になりますので適宜設定をお願いします。

  1. 1. EC2にてWindowsServerを作成
  2. 2. 上記インスタンスにCloudWatchAgent用のロールを付与
  3. 3. WindowsServerへCloudWatchAgentをインストール
  4. 4. CloudWatchAgentにてWindowsイベントログを取得できるよう初期設定を実施

今回CloudWatchAgentへ設定しているパラメータは以下になります。

{
  "logs": {
      "logs_collected": {
          "windows_events": {
              "collect_list": [
                  {
                      "event_format": "text",
                      "event_levels": [
                          "ERROR",
                          "CRITICAL"
                      ],
                      "event_name": "System",
                      "log_group_name": "ctc-system-test",
                      "log_stream_name": "{instance_id}-sys",
                      "retention_in_days": 3
                  },
                  {
                      "event_format": "text",
                      "event_levels": [
                          "ERROR",
                          "CRITICAL"
                      ],
                      "event_name": "Application",
                      "log_group_name": "ctc-app-test",
                      "log_stream_name": "{instance_id}-app",
                      "retention_in_days": 3
                  }
              ]
          }
      }
  },
  "metrics": {
      "aggregation_dimensions": [
          [
              "InstanceId"
          ]
      ],
             "append_dimensions": {
          "InstanceId": "${aws:InstanceId}"
      },
      "metrics_collected": {
          "LogicalDisk": {
              "measurement": [
                  "% Free Space"
              ],
              "metrics_collection_interval": 60,
              "resources": [
                  "*"
              ]
          },
          "Memory": {
              "measurement": [
                  "% Committed Bytes In Use",
                  "Available MBytes"
              ],
              "metrics_collection_interval": 60
          },
          "procstat": [
              {
                  "exe": "amazon-ssm-agent",
                  "measurement": [
                      "pid_count"
                  ],
                  "metrics_collection_interval": 60
              }
          ]
      }
  }
}

CloudWatchLogsへの出力は以下のようになっております。
環境に応じて適宜読み替えてください。

SNSの設定

まずは通知先としてトピックと運用者の情報を設定します。

以下のようにトピックを作成します。

作成したトピックのArnはLambdaにて利用しますので、どこかにメモしておいてください。

次にサブスクリプションを作成します。
トピックARNには上記で作成したトピックを選択し、エンドポイントには通知したいメールアドレスを指定します。

サブスクリプションの作成を終えると、設定したメールアドレスへ承認メールが届きますので、「Confirm subscription」のリンクをクリックします。

Lambda関数の作成

次にLambda関数を作成していきます。

Lambda画面から関数の情報を設定します。
今回はPythonを利用します。

関数の作成が出来ましたら、次にコードを記述していきます。
コードのサンプルは以下になります。
TopicArn=””の部分には作成したSNSトピックのArnを入力してください。

import json
import base64
import zlib
import boto3

def main(event, context):
    # CloudWatch Logsで収集したWindowsイベントログのエラーメッセージを取得
    data = zlib.decompress(base64.b64decode(event['awslogs']['data']), 16+zlib.MAX_WBITS)
    data_json = json.loads(data)

    log_message = json.loads(json.dumps(data_json["logEvents"][0]['message'], ensure_ascii=False))

    sns = boto3.client('sns')

    # メール送信
    publishResponse = sns.publish(
        TopicArn = "!!SNSで作成したTopicのArnを指定してください!!",
        Subject = "WindowsServerのイベントログにエラーが出力されました。",
        Message = "WindowsServerのイベントログに以下エラーが出力されました。\n\n{}\n\nエラー内容を確認し、トラブルシューティングを実施してください。\n".format(log_message)
    )
    
    responseStatus = publishResponse['ResponseMetadata']['HTTPStatusCode']
    
    if responseStatus != 200:
        raise Exception

def lambda_handler(event, context):
    try:
        main(event, context)
    except Exception as e:
        raise e  

以下画像のように入力が完了しましたらDeployボタンをクリックしてデプロイを行います。

CloudWatch Logs サブスクリプションフィルターの作成

それでは最後にCloudWatch Logsのサブスクリプションフィルターの設定を行っていきましょう。
Windowsイベントログを収集しているCloudWatch Logsのロググループを選択し、サブスクリプションフィルタータブから「Lambdaサブスクリプションフィルターを作成」をクリックします。

作成画面に移動しますので、先ほど作成したLambda関数を選択し、各種情報を入力していきます。
今回はERRORの文字列を認識しメール通知を行いますので、サブスクリプションフィルターのパターンはERRORとしています。

「ストリーミングを開始」をクリックしたら準備完了です。

実際に動かしてみる

それでは実際に動かしてみます。
WindowsイベントログがERRORを出力するような動作を行ってもよいのですが、今回はエラーのログを出力するテスト用コマンドを実行します。

> EventCreate /L System /T ERROR /SO “CreateSysEvent Test” /ID 200 /D “イベントログのエラー通知を行うテストを行っています。”

これによりCloudWatch Logsへエラーメッセージが送信され、それをトリガーにメール通知が行われました。

おわりに

いかがでしたでしょうか。
今回はCloudWatchAgentで収集したWindowsイベントログのエラーメッセージの内容をメールで運用者に送る方法についてご紹介いたしました。
運用監視を行う上で、どのようなエラーが発生したのかを即座に知ることは初動対応にかかる時間に直結していきます。
また、通知内容を運用者が分かりやすい形式にすることで、日々の運用業務の負荷も削減できるかと存じます。
とはいってもAWSの構築や運用すべてを自社だけではカバーしきれない事もあるかと思います。
運用を含めたAWS構築に関しまして、もしお手伝いが必要であれば是非CTCにご相談ください。

CTCは、AWSのビジネス利活用に向けて、お客様のステージに合わせた幅広い構築・運用支援サービスを提供しています。
経験豊富なエンジニアが、ワンストップかつ柔軟にご支援します。
ぜひ、お気軽にお問い合わせください。

お問い合わせ



【著者プロフィール】

北川 裕介 (きたがわ ゆうすけ)

伊藤忠テクノソリューションズ株式会社 クラウドアーキテクト

クラウド系のエンジニアとしてインフラ構築におけるPMやSEを担当。 近年はクラウドインフラのIaC化の実現も行っている。

北川 裕介 (きたがわ ゆうすけ)

TOP>コラム一覧>【運用監視】CloudWatchAgentで収集したWindowsイベントログのエラーメッセージをメールで運用者に送る方法

pagetop