概要
EC2 インスタンスで動くアプリケーションの応答が遅くなっていないかを見たいとき、CPU 使用率のような EC2 の標準のメトリクスだけでは分かりません。レスポンスタイムはアプリケーションしか知らない値だからです。
よく使われるのは、アプリケーションがレスポンスタイムをログに書き、CloudWatch エージェントでそのログを CloudWatch Logs に送り、メトリクスフィルターでログから数値を取り出してメトリクスにする方法です。メトリクスになれば、平均や最大をグラフで見られ、CloudWatch アラームで閾値を超えたときに SNS へ通知できます。フリート(複数のインスタンス)のログを 1 つのロググループに集めれば、フリート全体の統計になります。
この記事では、ログからメトリクスを作る流れと、メトリクスフィルターの書き方、アラームの設定を整理します。実践では、EC2 の疑似アプリが書くアクセスログを CloudWatch Logs に送り、レスポンスタイムのメトリクスを作って、遅くなったらアラームが鳴ることを確かめます。

クラウドおさる荷運びの所要時間は、運んだ猿にしか分からぬでござる。だから日誌(ログ)に書かせて、日誌から数字だけを拾い出す。遅くなったら見張りが太鼓(アラーム)を鳴らす。今日はその仕組みを作るでござるよ。
この記事のメリット
- EC2 の標準メトリクスでは分からない、アプリケーションの値を監視する方法が分かる
- CloudWatch エージェントでログファイルを CloudWatch Logs に送れるようになる
- メトリクスフィルターで、JSON のログから数値を取り出してメトリクスにできるようになる
- 平均レスポンスタイムが閾値を超えたら SNS に通知するアラームを作れるようになる
執筆者とキャラクター紹介
執筆者:土肥(とひ)
株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。


クラウドおさる



はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。



基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。



猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。
技術解説
ログからメトリクスを作る流れ
| 段階 | 使うもの | やること |
|---|---|---|
| 1. ログに書く | アプリケーション | 1 リクエストごとに、レスポンスタイムを含む行をログファイルに書く |
| 2. 送る | CloudWatch エージェント | ログファイルを CloudWatch Logs のロググループに送り続ける |
| 3. 数値を取り出す | メトリクスフィルター | ログの行から数値を取り出し、カスタムメトリクスとして記録する |
| 4. 見る・知らせる | CloudWatch のグラフとアラーム | 平均・最大を表示し、閾値を超えたら SNS に通知する |
ほかにも、アプリケーションが PutMetricData で直接カスタムメトリクスを送る方法や、埋め込みメトリクスフォーマット(EMF)でログに書いてメトリクスを自動で作る方法もあります。
CloudWatch エージェント
CloudWatch エージェントは、EC2 やオンプレミスのサーバーで動き、ログファイルやメモリ使用率などのメトリクスを CloudWatch に送るソフトウェアです。送るログは設定ファイル(JSON)の logs に書きます。
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/dva-app/access.log",
"log_group_name": "/dva/app/access",
"log_stream_name": "{instance_id}"
}
]
}
}
}
}log_stream_name に {instance_id} と書くと、インスタンスごとに別のログストリームになり、同じロググループに集まります。インスタンスの IAM ロールには、ログを送る権限(AWS 管理ポリシー CloudWatchAgentServerPolicy など)が必要です。
メトリクスフィルター
メトリクスフィルターは、ロググループに届いたログの行をパターンで探し、一致した行からメトリクスの値を取り出します。ログが JSON なら、$.フィールド名 で値を参照できます。
| 設定 | 例 | 意味 |
|---|---|---|
| フィルターパターン | { $.latency_ms = * } | latency_ms を持つ行に一致する |
| メトリクスの名前空間 / 名前 | DVA/App / ResponseTime | 作るカスタムメトリクス |
| メトリクス値 | $.latency_ms | 行の latency_ms の値をそのまま記録する |
| 単位 | Milliseconds | 値の単位 |
メトリクスフィルターは、作成した後に届いたログからメトリクスを作ります。作成前のログはさかのぼって数えません。





日誌から数字を拾う網を張っても、網を張る前に流れた日誌は拾えぬのでござる。監視を始めたい日が来る前に、網を張っておくのが肝でござるな。
アラームと通知
CloudWatch アラームは、メトリクスの統計(平均・最大など)が、指定した期間で閾値を超えたかを評価し、状態を OK・アラーム状態・データ不足 の間で切り替えます。アラーム状態になったときのアクションに SNS トピックを指定すると、トピックのサブスクリプション(メール・Lambda など)へ通知が届きます。



Inspector や SSM Agent に「レスポンスタイムを測ってくれ」と頼んでも、そういう係ではないのでござる。アプリの値はログかカスタムメトリクスで出す、試験ではここを取り違えやすいでござるぞ。
実践
EC2 インスタンス dva-cwlogs-app では、疑似アプリ dva-app が 1 秒ごとに /var/log/dva-app/access.log へ JSON の行({"path": "/items", "status": 200, "latency_ms": 123})を書いています。通常は 80〜200 ms で、/tmp/slow というファイルがある間は 400〜900 ms になります。このログを CloudWatch Logs に送り、レスポンスタイムのメトリクスとアラームを作ります。
前提条件
- リージョン:
ap-northeast-1(東京) - 以下のリソースが作成済みであること
まだ用意していない場合は、「作り方の参考」の記事の手順で作れます。リソース名は、この記事の名前に読み替えてください。
| リソース種別 | リソース名 | 内容 | 作り方の参考 |
|---|---|---|---|
| EC2 インスタンス | dva-cwlogs-app | Amazon Linux 2023。Session Manager で接続でき、CloudWatch エージェント(amazon-cloudwatch-agent)がインストール済み(未設定・未起動)。疑似アプリ dva-app が起動している | Amazon EC2 でインスタンスを起動しSSH接続する |
| IAM ロール | dva-cwlogs-app-role | 上のインスタンスのロール。AmazonSSMManagedInstanceCore と CloudWatchAgentServerPolicy | ― |
| SNS トピック | dva-latency-alarm-topic | アラームの通知先(サブスクリプションなし) | Amazon SNS でトピックを作成しメッセージを配信する |
作成するリソース一覧
| リソース種別 | リソース名 | 用途 |
|---|---|---|
| ロググループ | /dva/app/access | エージェントが送るアクセスログ(エージェントが自動で作る) |
| メトリクスフィルター | dva-app-latency | ログからレスポンスタイムを取り出す |
| カスタムメトリクス | DVA/App の ResponseTime | レスポンスタイム(ミリ秒) |
| CloudWatch アラーム | dva-app-latency-high | 平均レスポンスタイムが 300 ms を超えたら通知 |
手順 1: CloudWatch エージェントでログを送る
AWS マネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します。EC2 のコンソールで dva-cwlogs-app を選択し、「接続」→「Session Manager」タブ →「接続」をクリックします。
ターミナルで、アプリのログが書かれていることを確かめます。
tail -n 3 /var/log/dva-app/access.log技術解説の設定ファイルを /opt/aws/amazon-cloudwatch-agent/etc/dva-config.json として保存し、エージェントに読み込ませて起動します。
sudo tee /opt/aws/amazon-cloudwatch-agent/etc/dva-config.json > /dev/null <<'EOF'
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/dva-app/access.log",
"log_group_name": "/dva/app/access",
"log_stream_name": "{instance_id}"
}
]
}
}
}
}
EOF
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config -m ec2 -s \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/dva-config.json
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a statusstatus の結果で "status": "running" になっていれば、エージェントが動いています。


上部の検索バーに CloudWatch と入力し、「CloudWatch」を選択します。左側ナビゲーションの「ログ」→「ロググループ」で /dva/app/access を開くと、インスタンス ID の名前のログストリームに、アプリのログが届いています。
手順 2: メトリクスフィルターを作る
ロググループ /dva/app/access の画面で「メトリクスフィルター」タブを選択し、「メトリクスフィルターを作成」をクリックします。
- フィルターパターン:
{ $.latency_ms = * } - 「パターンをテスト」: 「カスタムログデータ」の欄に
{"path": "/items", "status": 200, "latency_ms": 123}を貼り、「パターンをテスト」をクリックして 1 件一致することを確認する
「次へ」をクリックし、「メトリクスの割り当て」で以下を設定します。
- フィルター名:
dva-app-latency - メトリクス名前空間:
DVA/App - メトリクス名:
ResponseTime - メトリクス値:
$.latency_ms - 単位:
ミリ秒


「次へ」をクリックし、「プレビューと作成」の画面で「メトリクスフィルターを作成」をクリックします。
手順 3: 平均と最大をグラフで見る
フィルターを作ってから値がメトリクスに出始めるまで数分かかります。数分待ってから、左側ナビゲーションの「メトリクス」→「クラシックメトリクス」を選択し、「カスタム名前空間」の DVA/App →「メトリクスのディメンションなし」→ ResponseTime を選択します。「グラフ化したメトリクス」タブで、統計を「平均」、期間を「1 分」にします。同じメトリクスをもう 1 行追加し、統計を「最大」にすると、平均と最大が並んで表示されます。





日誌の数字が、平均と最大の折れ線になったでござる。インスタンスが増えても、同じロググループに集めれば、フリート全体の値として見られるのでござるな。
手順 4: アラームを作る
平均のメトリクスの行の「アクション」から、ベルのアイコン(アラームを作成)をクリックします。アラームの作成は 4 ステップで、名前空間・メトリクス名・統計(平均値)・期間(1 分)は入力済みの状態で始まります。以下を設定します。
- 統計: 平均値、期間: 1 分(入力済み)
- 条件: 「静的」、「より大きい」(どちらもデフォルト)、しきい値
300 - 「その他の設定」の「アラームを実行するデータポイント」:
1/1(デフォルト) - 通知: アラーム状態トリガーで「既存の SNS トピックを選択」し、送信先に
dva-latency-alarm-topicのトピックの ARN(arn:aws:sns:ap-northeast-1:<アカウントID>:dva-latency-alarm-topic)を入力(名前で候補が出ない場合があります。サブスクリプションが無いので「トピックにエンドポイントがありません」と表示されますが、そのまま進めます) - アラーム名:
dva-app-latency-high
最後のステップで「アラームの作成」をクリックします。しばらくすると、アラームの状態は OK になります。
手順 5: 遅くして、アラーム状態になることを確かめる
Session Manager のターミナルで、疑似アプリを遅くします。
sudo touch /tmp/slow数分すると、平均のレスポンスタイムが 300 ms を超え、アラーム dva-app-latency-high の状態が「アラーム状態」に変わります。アラームの「履歴」タブには、状態の変更と、SNS トピックへのアクションが実行された記録が残ります。


今回の SNS トピックにはサブスクリプションを付けていないので、通知はどこにも届きません。実際の運用では、トピックにメールアドレスなどのサブスクリプションを追加して、通知を受け取ります。
確認が終わったら、sudo rm /tmp/slow で元に戻します。数分後にアラームは OK に戻ります。
まとめ
| 要件 | 使うもの |
|---|---|
| アプリのレスポンスタイムを CloudWatch に集める | ログに書き、CloudWatch エージェントで CloudWatch Logs に送る |
| ログから数値を取り出してメトリクスにする | メトリクスフィルター(JSON なら $.フィールド名) |
| 平均・最大を見る | CloudWatch のメトリクスのグラフ(統計を切り替える) |
| 閾値を超えたらすぐ通知する | CloudWatch アラーム + SNS |
- アプリケーションしか知らない値は、ログかカスタムメトリクス(
PutMetricData、EMF)で CloudWatch に出す - CloudWatch エージェントは、設定ファイルの
logsに書いたファイルを CloudWatch Logs に送る。インスタンスのロールに送る権限が必要 - メトリクスフィルターは、作成後に届いたログから値を取り出してカスタムメトリクスにする
- アラームは統計と期間で閾値を評価し、アラーム状態になったら SNS トピックへ通知する
- Inspector や SSM Agent はアプリのレスポンスタイムを集める仕組みではない
参照先
- CloudWatch エージェントを使用してメトリクス、ログ、トレースを収集する – Amazon CloudWatch
- CloudWatch エージェント設定ファイルを手動で作成または編集する – Amazon CloudWatch
- フィルターを使用したログイベントからのメトリクスの作成 – Amazon CloudWatch Logs
- メトリクスフィルター、サブスクリプションフィルター、フィルターログイベント、およびライブテールのフィルターパターン構文 – Amazon CloudWatch Logs
- Amazon CloudWatch でのアラームの使用 – Amazon CloudWatch














