AWS

CloudWatchでアラート設定

NEW 2026年8月18日

目次Category


AWSでEC2を運用していると、CPU使用率の上昇やWebサーバーのエラーなど、 異常をできるだけ早く検知したい場面があります。

そのようなときに役立つのが、 Amazon CloudWatchです。

この記事では、CloudWatchを初めて利用する方に向けて、 EC2のCPU使用率とApacheのエラーログを監視し、 異常を検知した際にメール通知を送る方法を解説します。

この記事でできること

  • CloudWatchの基本的な役割を理解する
  • EC2のCPU使用率を監視する
  • CPU使用率がしきい値を超えた際にメール通知を送る
  • CloudWatch Agentを使ってApacheのエラーログを監視する
  • アラートメールを日本語化する仕組みを理解する

この記事の対象者

  • AWSを学び始めた方
  • CloudWatchを初めて利用する方
  • EC2の監視方法を知りたい方

CloudWatchとは?

Amazon CloudWatchは、 AWSリソースやアプリケーションの状態を監視するサービスです。

EC2では、CPU使用率やネットワーク通信量などの情報を標準で確認できます。 また、CloudWatch Agentを導入することで、 EC2内のメモリ使用率やApacheのログなどもCloudWatchへ送信できます。

ポイント

CloudWatchは「監視」、CloudWatch Alarmは「条件の判定」、 SNSは「通知」を担当します。

今回構築する構成

今回は、EC2のCPU使用率とApacheのエラーログを監視し、 異常を検知した場合にメール通知を送信します。

EC2

CloudWatch / CloudWatch Agent

CloudWatch Alarm

SNS

メール通知

メール本文を日本語に整形する場合は、 CloudWatch AlarmからLambdaを呼び出し、 Lambdaが日本語に整形した内容をSNSへ送信します。

使用するAWSサービス

サービス役割
EC2監視対象となるサーバー
CloudWatchCPU使用率やログなどを監視する
CloudWatch Alarmしきい値をもとに状態を判定する
CloudWatch AgentEC2内のログなどをCloudWatchへ送信する
SNS登録したメールアドレスへ通知する
Systems ManagerCloudWatch Agentの導入と設定に使用する
Lambda通知内容を日本語に整形する

1. CPU使用率の監視とアラーム作成

はじめに、EC2のCPU使用率を監視します。 今回は、CPU使用率が50%以上になった場合に、 登録したメールアドレスへ通知するアラームを作成します。

手順1:SNSトピックを作成する

まず、CloudWatchからの通知を受け取るために、 SNSトピックを作成します。

設定内容

タイプ:Standard
トピック名:ojt-sns-topic-[名前]-01

  1. AWSマネジメントコンソールで「SNS」を検索します。
  2. 左側のメニューから「トピック」を開きます。
  3. 「トピックの作成」を選択します。
  4. タイプで「Standard」を選択します。
  5. トピック名を入力して作成します。
Amazon SNSでトピックを作成する画面
SNSトピックの作成画面。実際の操作では「Standard」を選択してください。

手順2:メールアドレスを登録する

  1. 作成したSNSトピックを開きます。
  2. 「サブスクリプションの作成」を選択します。
  3. プロトコルで「Email」を選択します。
  4. エンドポイントに通知先のメールアドレスを入力します。
  5. 「サブスクリプションの作成」を選択します。

登録したメールアドレスに確認メールが届きます。 メール内の「Confirm subscription」を選択して、 サブスクリプションを承認してください。

注意

メールアドレスを登録しただけでは通知を受信できません。 必ず確認メールからサブスクリプションを承認してください。

Amazon SNSでメールサブスクリプションを作成する画面
プロトコルで「Email」を選び、通知先のメールアドレスを入力します。

手順3:CloudWatchアラームを作成する

  1. AWSマネジメントコンソールで「CloudWatch」を検索します。
  2. 左側のメニューから「アラーム」を選択します。
  3. 「すべてのアラーム」を開きます。
  4. 「アラームの作成」を選択します。
  5. 「メトリクスの選択」を選択します。
  6. 「EC2」から「インスタンス別メトリクス」を開きます。
  7. 監視対象のインスタンスIDを確認し、「CPUUtilization」を選択します。
CloudWatchでCPUUtilizationのアラーム条件を設定する画面
CPUUtilizationを選択し、統計・期間・しきい値を設定します。

アラーム条件

項目設定値
統計平均
期間1分
しきい値の種類静的
条件CPUUtilizationが50以上
評価するデータポイント1/1

この設定では、1分間の平均CPU使用率が50%以上になると、 アラーム状態へ変化します。

通知先には、手順1で作成したSNSトピックを選択してください。

手順4:CPUに負荷をかけて動作確認する

EC2へ接続し、以下のコマンドを実行します。

cat /dev/zero | sha1sum &

コマンドを実行すると、EC2のCPUに負荷がかかります。 設定内容によって多少時間は異なりますが、1〜2分程度待つと、 CloudWatchのアラーム状態が 「OK」から「アラーム状態」へ変化します。 登録したメールアドレスに通知が届けば成功です。

動作確認が終わったら、以下のコマンドでCPU負荷を停止します。

killall sha1sum

注意

&を付けて実行した処理はバックグラウンドで動作します。 動作確認が完了したら、必ず停止コマンドを実行してください。

EC2にCPU負荷をかけてCloudWatchアラームとメール通知を確認する流れ
CPU負荷の開始、アラーム状態、メール通知、CPU負荷の停止を確認します。

2. Apacheログの監視とアラーム作成

次に、EC2内のApacheエラーログを監視します。

CloudWatchの標準メトリクスだけでは、 EC2内に保存されているApacheのログを取得できません。 そのため、EC2へCloudWatch Agentを導入します。

CloudWatch Agentとは?

EC2内のログなどを収集し、 CloudWatchへ送信するためのソフトウェアです。

EC2内のApacheログ

CloudWatch Agent

CloudWatch Logs

手順1:EC2用のIAMロールを作成する

EC2がCloudWatchへログを送信し、 Systems Managerから操作できるようにIAMロールを作成します。

設定内容

ロール名:ojt-ec2-roll-[名前]-01
ポリシー:CloudWatchAgentServerPolicy
ポリシー:AmazonSSMManagedInstanceCore

ロールを作成したら、AWSマネジメントコンソールで監視対象のEC2を選択し、 「アクション」→「セキュリティ」→「IAMロールを変更」を開きます。 その後、作成したIAMロールを選択して、「IAMロールを更新」を押します。

IAMロールにCloudWatchAgentServerPolicyとAmazonSSMManagedInstanceCoreを設定する画面
IAMロールへ2つのAWS管理ポリシーを付与します。
EC2の「アクション」→「セキュリティ」→「IAMロールを変更」から、作成したIAMロールをアタッチします。

手順2:設定ファイルをParameter Storeに保存する

CloudWatch Agent設定ファイルである config.jsonをテキストエディタで編集します。

CloudWatch Agentが収集するログファイルの場所や、 CloudWatch Logsに作成するロググループ名などを config.jsonに記述します。

Parameter Storeへ保存することで、 Run CommandからCloudWatch Agentの設定を読み込めるようになります。

config.jsonの内容

今回は、ApacheのアクセスログとエラーログをCloudWatch Logsへ送信するため、 以下の内容をconfig.jsonとして使用します。

{
  "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": "ojt-apache-accesslog-fujita-01",
            "log_stream_name": "fujita",
            "retention_in_days": 7
          },
          {
            "file_path": "/var/log/httpd/error_log",
            "log_group_name": "ojt-apache-error-log-fujita-01",
            "log_stream_name": "fujita",
            "retention_in_days": 7
          }
        ]
      }
    }
  }
}

主な設定内容

  • metrics_collection_interval:Agentの収集間隔を60秒に設定します。
  • run_as_user:CloudWatch Agentをrootユーザーとして動かします。
  • file_path:収集対象となるApacheログの保存場所です。
  • log_group_name:CloudWatch Logsに作成するロググループ名です。
  • log_stream_name:ログストリーム名です。
  • retention_in_days:ログの保存期間を7日間に設定します。

自分の環境に合わせて変更する箇所

log_group_namelog_stream_nameは、 自分の名前や命名規則に合わせて変更してください。 また、Apacheのログファイルが別の場所にある場合は、file_pathも変更します。

Systems ManagerのParameter StoreへCloudWatch Agent設定を保存する画面
config.jsonの内容をParameter Storeへ保存します。

手順3:Run CommandでCloudWatch Agentを導入する

Systems ManagerのRun Commandを利用して、 EC2へCloudWatch Agentをインストールします。

インストール後、Parameter Storeに保存した設定を読み込ませ、 CloudWatch Agentへ設定を適用します。

主な設定値

ドキュメント名:AmazonCloudWatch-ManageAgent
Action:configure
Mode:ec2
Configuration Source:ssm
Configuration Location:AmazonCloudWatch-linux
Restart:yes

Systems ManagerのRun CommandでCloudWatch Agentを設定する画面
対象のEC2を選択し、Parameter Storeの設定を読み込ませます。

手順4:CloudWatch Logsへの出力を確認する

CloudWatchの「ロググループ」を開き、 設定したApacheのエラーログが出力されていることを確認します。

ロググループ内のログストリームを開き、 ログイベントにApacheのログが表示されていれば成功です。

CloudWatch LogsにApacheのエラーログが出力されている画面
ロググループとログストリームを開き、ログイベントを確認します。

手順5:メトリクスフィルターとアラームを作成する

ログの中から特定の文字列を検知するために、 メトリクスフィルターを作成します。

今回は、Apacheのエラーログに含まれる errorという文字列を検知するように設定します。

メトリクスフィルター作成画面のフィルターパターンに、 以下の文字列を入力します。

error

ポイント

ログ内でerrorに一致するイベントが発生した際に、 メトリクス値として1を記録します。 そのメトリクスをCloudWatch Alarmで監視します。

メトリクスフィルターを作成したら、 そのメトリクスを監視するCloudWatchアラームを作成し、 通知先としてSNSトピックを指定します。

手順6:エラーログを書き込んで動作確認する

EC2へ接続し、以下のコマンドでApacheのエラーログへ errorという文字列を追記します。

echo "error" | sudo tee -a /var/log/httpd/error_log

CloudWatch Logsに追記した内容が表示され、 CloudWatchアラームが「アラーム状態」へ変化し、 メール通知が届けば成功です。

補足

viでログファイルを直接編集する方法もありますが、 初心者向けの記事では、ログの末尾へ追記できる tee -aを使用しています。

Apacheのエラーログを検知してCloudWatchアラームが発生した画面
ログの検知後、CloudWatchアラームとメール通知を確認します。

3. アラートメールの本文を日本語にする

CloudWatchからSNSを通して送信される標準のアラートメールには、 JSON形式の情報や英語の項目名が含まれます。

内容を確認することはできますが、 初めて見る人には少し分かりにくい場合があります。

そこで、CloudWatch AlarmからLambdaを呼び出し、 Lambdaが必要な情報を日本語に整形してからSNSへ送信します。

CloudWatch Alarm

Lambda

日本語に整形

SNS

メール通知

Lambdaで整形する主な情報

  • アラーム名
  • アラームが発生した時刻
  • 監視対象
  • アラームが発生した理由
  • 現在のアラーム状態

手順1:Lambda関数を作成する

  1. AWSマネジメントコンソールで「Lambda」を検索します。
  2. 「関数の作成」を選択します。
  3. 「一から作成」を選択します。
  4. 任意の関数名を入力します。例:ojt-cloudwatch-mail-fujita-01
  5. ランタイムで「Python 3.12」を選択します。
  6. 「関数の作成」を選択します。

手順2:Lambdaへコードを記述する

作成したLambda関数の「コード」タブを開き、 lambda_function.pyへ以下のコードを貼り付けて、「Deploy」を押します。

import os
from datetime import datetime, timedelta, timezone

import boto3


sns = boto3.client("sns")
SNS_TOPIC_ARN = os.environ["SNS_TOPIC_ARN"]


def lambda_handler(event, context):
    """
    CloudWatch Alarmの状態変化を受け取り、
    必要な情報を日本語に整形してSNSへ送信する。
    """

    alarm_data = event.get("alarmData", {})
    state = alarm_data.get("state", {})
    configuration = alarm_data.get("configuration", {})

    alarm_name = alarm_data.get("alarmName", "取得できませんでした")
    state_value = state.get("value", "UNKNOWN")
    reason = state.get("reason", "取得できませんでした")
    occurred_at = state.get("timestamp") or event.get("time", "")

    region = event.get("region", "取得できませんでした")
    account_id = event.get("accountId", "取得できませんでした")
    alarm_arn = event.get("alarmArn", "取得できませんでした")

    target = get_monitoring_target(configuration)
    occurred_at_jst = convert_to_jst(occurred_at)

    state_ja = {
        "ALARM": "アラーム状態",
        "OK": "正常",
        "INSUFFICIENT_DATA": "データ不足",
    }.get(state_value, state_value)

    subject = f"【CloudWatch】{alarm_name}:{state_ja}"

    message = f"""CloudWatchアラームの状態が変化しました。

■ アラーム名
{alarm_name}

■ 現在の状態
{state_ja}({state_value})

■ 発生時刻
{occurred_at_jst}

■ 監視対象
{target}

■ 発生理由
{reason}

■ AWSリージョン
{region}

■ AWSアカウントID
{account_id}

■ アラームARN
{alarm_arn}

AWSマネジメントコンソールで詳細を確認してください。
"""

    response = sns.publish(
        TopicArn=SNS_TOPIC_ARN,
        Subject=subject[:100],
        Message=message,
    )

    print(f"SNSへの送信に成功しました: {response['MessageId']}")

    return {
        "statusCode": 200,
        "message": "日本語のアラート通知を送信しました。",
    }


def get_monitoring_target(configuration):
    """アラーム設定から監視対象のメトリクスとディメンションを取得する。"""

    metrics = configuration.get("metrics", [])

    if not metrics:
        return "取得できませんでした"

    metric_stat = metrics[0].get("metricStat", {})
    metric = metric_stat.get("metric", {})

    namespace = metric.get("namespace", "不明")
    metric_name = metric.get("name", "不明")
    dimensions = metric.get("dimensions", {})

    dimension_text = ", ".join(
        f"{key}={value}" for key, value in dimensions.items()
    )

    if dimension_text:
        return f"{namespace} / {metric_name} / {dimension_text}"

    return f"{namespace} / {metric_name}"


def convert_to_jst(timestamp_text):
    """CloudWatchから受け取った時刻を日本時間へ変換する。"""

    if not timestamp_text:
        return "取得できませんでした"

    try:
        normalized = timestamp_text.replace("Z", "+00:00")

        if (
            len(normalized) >= 5
            and normalized[-5] in ("+", "-")
            and normalized[-3] != ":"
        ):
            normalized = normalized[:-2] + ":" + normalized[-2:]

        timestamp = datetime.fromisoformat(normalized)
        jst = timezone(timedelta(hours=9))

        return timestamp.astimezone(jst).strftime(
            "%Y年%m月%d日 %H時%M分%S秒"
        )

    except ValueError:
        return timestamp_text

コードの主な処理

  • CloudWatch Alarmからアラーム名・状態・発生理由・発生時刻を取得します。
  • 発生時刻を日本時間へ変換します。
  • アラーム状態を「正常」「アラーム状態」「データ不足」の日本語へ変換します。
  • 監視対象のメトリクスやEC2インスタンスIDを取得します。
  • 日本語へ整形した内容をSNSトピックへ送信します。

手順3:環境変数を設定する

Lambda関数の「設定」→「環境変数」→「編集」を開き、 次の環境変数を追加します。

環境変数

キー:SNS_TOPIC_ARN
値:通知先として使用するSNSトピックのARN

SNSトピックのARNは、Amazon SNSで作成したトピックの詳細画面から確認できます。

手順4:Lambdaの実行ロールへSNS送信権限を追加する

LambdaからSNSトピックへメッセージを送信するため、 Lambdaの実行ロールにsns:Publish権限を追加します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sns:Publish",
      "Resource": "通知先SNSトピックのARN"
    }
  ]
}

ポイント

Resourceには、環境変数SNS_TOPIC_ARNへ設定したものと同じSNSトピックのARNを指定します。

手順5:CloudWatch AlarmからLambdaを呼び出す

  1. CloudWatchで対象のアラームを開きます。
  2. 「アクション」からアラームの編集画面を開きます。
  3. 通知またはアクションの設定でLambdaアクションを追加します。
  4. 作成したLambda関数を選択します。
  5. 設定を保存します。

アラームの状態が変化するとLambdaが実行され、 日本語へ整形したメッセージがSNSを通じてメールで送信されます。

Lambdaの設定画面とOutlookで受信した日本語のCloudWatchアラートメール
Lambdaの設定例と、日本語へ整形したアラートメールの受信イメージです。

うまくいかない場合の確認ポイント

メールが届かない場合

  • SNSのサブスクリプションを承認しているか
  • 迷惑メールフォルダに入っていないか
  • アラームに正しいSNSトピックを設定しているか
  • CloudWatchアラームが「アラーム状態」になっているか

CPUアラームが発生しない場合

  • 監視対象のEC2インスタンスIDが正しいか
  • CPUUtilizationを選択しているか
  • しきい値が50%に設定されているか
  • 期間が1分、評価するデータポイントが1/1になっているか
  • CPU負荷をかけるコマンドが動作しているか

ログがCloudWatchに表示されない場合

  • EC2にIAMロールをアタッチしているか
  • CloudWatch Agentが起動しているか
  • config.jsonのログファイルパスが正しいか
  • Parameter Storeの名前を正しく指定しているか
  • 監視対象のログファイルが存在しているか
  • Systems Managerで対象EC2がマネージドノードとして認識されているか

ログアラームが発生しない場合

  • メトリクスフィルターのパターンがerrorになっているか
  • CloudWatch Logsにerrorを含む新しいログが出力されているか
  • 正しいカスタムメトリクスをアラームで選択しているか
  • 期間やしきい値の設定が正しいか

日本語メールが届かない場合

  • Lambdaの環境変数SNS_TOPIC_ARNが正しいか
  • Lambdaの実行ロールにsns:Publish権限があるか
  • CloudWatch Alarmに正しいLambda関数を設定しているか
  • Lambdaのコードを変更した後に「Deploy」を押しているか
  • LambdaのCloudWatch Logsにエラーが出ていないか
  • SNSトピックのメールサブスクリプションが承認済みか

まとめ

今回実施した内容

  • CloudWatchによるEC2のCPU使用率の監視
  • CloudWatch Alarmによるしきい値の判定
  • SNSを利用したメール通知
  • CloudWatch Agentを利用したApacheログの監視
  • メトリクスフィルターを利用したログアラームの作成
  • Lambdaを利用したアラートメールの日本語化

CloudWatchを活用すると、AWSリソースやログの異常を早期に発見できます。 初めて設定する場合は、まずCPU使用率の監視から始め、 その後にログ監視や通知内容のカスタマイズへ進むと理解しやすくなります。

今回の記事では、CPU使用率の監視、Apacheログの監視、 メール通知、日本語通知の仕組みまで紹介しました。

この記事を書いた人

藤田颯斗

hayato_fujita

こんにちわ、がんばります。