Skip to content

監視方針 ​

概要 ​

本番の AWS リソースを CloudWatch アラームで監視し、発報を Slack へ届けるための方針をまとめる。リージョンは ap-northeast-1(東京)で、管理下のアラームは 60 件である。

このページは「何をどう監視するか」の方針を扱う。適用・手動実行・切り戻しといった手を動かす手順は h2t/infrastructure の docs/ にある手順書へ分けてある(「手順書の置き場所」を参照)。

方針 ​

要件は次の 2 つである。

#要件具体化したもの
1止まっていたら Slack へ通知するサイト(ALB から見た正常なホスト数)とサーバー(EC2 のステータスチェック)の死活を見る
2負荷が 90% でもアラートを出すCPU・メモリ・ディスクの使用率を 90% で見る。DB は加えて空き容量の枯渇も見る

設計はリソースの種別ではなくシステム単位で立てている。全システムがサーバー 1 台構成であり、EC2 が止まればそのシステムは全停止するためである。1 台構成であることは「正常なホスト数が 1 台を下回ったら異常」という閾値の根拠にもなっている。

死活でも負荷 90% でもない項目(応答時間・レイテンシ・レプリカ遅延など)は監視しない。何が起きたかを掘り下げるための指標であり、止まっているか否かの判断には使わないためである。

発報(ALARM)と復帰(OK)の両方を通知する。復帰まで届くことで、対応が済んだのか放置されているのかを Slack の履歴だけで追える。

監視の対象 ​

システムごとの内訳は次のとおりである。件数は管理下 60 件の内訳であり、合計は 60 になる。

システムサイト(ALB)サーバー(EC2)DB(RDS のインスタンス)件数
GMACgmac-productiongmac-app-productiongmac-db-production
gmac-db-production-ap-northeast-1a
12
GCORgcor-productiongcor-app-productiongcor-db-production-cluster-instance-19
PIPITkingmeo-productionkingmeo-app-productionkingmeo-db-production-cluster-instance-1-ap-northeast-1c9
Kuchikomi Onekuchikomi-one-productionKuchikomi Onekuchikomi-one-db-production9
meo-timesmeotimes-elbmeo-timesmeotimes-instance-1-ap-northeast-1a9
smart-meosmart-meo-listingplussmart-meo-listingplusなし6
スクレイピング基盤——scraper-instance-1-ap-northeast-1c5
通知基盤———1

PIPIT のリソース名は kingmeo-* である。名前とサービス名が一致しないため、meo を含む meo-times と取り違えないよう注意する。

スクレイピング基盤は EC2 を持たず、Lambda(sync_database / fetch_search_ranking)と Aurora(scraper)で動く。通知基盤は Lambda h2t-alarm-notifier だけである。

監視の対象にしないもの ​

対象扱い理由
GMAC ステージング(gmac-staging)監視しない検証用であり、夜間・土日祝は自動で停止する。停止をもって異常とは扱えない
社内基盤の踏み台(h2-dev-bastion)計測だけ行い、アラームは作らない本番のサービスを担っていない。CloudWatch agent は入れてあり、取れたメモリの実測はインスタンスサイズの適正化(h2t/infrastructure の Issue #38)の判断材料として使う

以前の棚卸し(Issue #30)で挙がっていた検証環境の places-app-staging / places-db-staging は現存しないため、対象に含めていない。停止中の環境を抱えたまま監視をどう扱うかを決める必要は、いまのところ生じていない。

監視項目と閾値 ​

層ごとの内訳である。「欠測」はデータ点が無い評価枠の扱い(treat_missing_data)を指す。

層監視する内容メトリクス統計条件欠測件数
サイト正常なホスト数AWS/ApplicationELB の HealthyHostCountAverage1 未満異常6
サーバー(死活)ステータスチェックAWS/EC2 の StatusCheckFailedAverage0 を超える判断しない6
サーバー(死活・自動復旧)システム側のステータスチェックAWS/EC2 の StatusCheckFailed_SystemMaximum0.99 以上判断しない6
サーバー(負荷)CPU 使用率AWS/EC2 の CPUUtilizationAverage90% を超える判断しない6
サーバー(負荷)メモリ使用率H2T/EC2 の mem_used_percentAverage90% を超える判断しない6
サーバー(負荷)ディスク使用率H2T/EC2 の disk_used_percentMaximum90% を超える判断しない6
DB(負荷)CPU 使用率AWS/RDS の CPUUtilizationAverage90% を超える判断しない7
DB(枯渇)空きメモリAWS/RDS の FreeableMemoryAverage100 MB 未満判断しない7
DB(枯渇)空きローカルストレージAWS/RDS の FreeLocalStorageAverage200 MB 未満判断しない7
スクレイピング起動の途絶AWS/Lambda の InvocationsSum1 時間の枠が 16 回続けて 0異常1
スクレイピング実行時間AWS/Lambda の DurationMaximum150 秒を超える正常1
通知基盤エラー数AWS/Lambda の ErrorsSum0 を超える正常1

評価の間隔は 5 分(自動復旧の 6 件は 1 分、起動の途絶は 1 時間)である。ディスクだけ統計を Maximum にしているのは、1 台に複数のファイルシステムの系列があり、Average では 1 つの逼迫が薄まって発報しないためである。

閾値の根拠 ​

閾値値根拠
負荷(CPU・メモリ・ディスク)90%「負荷 90% でもアラートを出す」という要件そのものである。EC2 と RDS で値をそろえてある
正常なホスト数1 未満全システムがサーバー 1 台構成であり、1 台でも欠ければサイトが応答しない
DB の空きメモリ100 MBGMAC の DB に元からあった値を、他の DB へもそろえた
DB の空きローカルストレージ200 MB同上
スクレイピングの実行時間150 秒正常時の実測は 98.6〜106.5 秒、Issue #41 の障害時は 180.9〜185.0 秒であった。両者の間に置いてある
スクレイピングの起動の途絶16 時間定期実行は 08:00 と 17:00(JST)で、最大の間隔は 15 時間である。1 時間の余裕を足した
通知基盤のエラー1 件以上通知が壊れると他のすべての監視が届かなくなるため、1 件でも異常とする

起動の途絶だけはメトリクス数式で評価する。起動が無い時間帯はデータ点そのものが出ないため、素の欠測評価に任せると発報が 16 時間より遅れ得る。Invocations の 1 時間ごとの Sum に FILL(m1, 0) を掛けて各枠へ明示的な 0 を作り、16 枠続けて 0 =最後の起動から最大 16 時間で確実に発報する形にしている。

欠測の扱い ​

データ点が無い枠をどう評価するかは 3 通りに分かれる。

扱い件数対象そう決めた理由
異常(breaching)7サイトの HealthyHostCount 6 件と、スクレイピングの起動の途絶 1 件欠測は「正常なホストが数えられない」「メトリクスごと消えた」状態であり、死活の観点では異常に倒す
正常(notBreaching)2スクレイピングの実行時間と、通知基盤のエラー数対象の関数が疎にしか動かず、実行の合間は必ず欠測になる。データが無い状態は異常を意味しない
判断しない(missing)51上記以外常時データが出る系列であり、欠測は起きない前提である

アラーム名と閾値が食い違う 3 件 ​

EC2.gmac-app-production.CPUUtilization_over_85 と RDS の ..._over_80 2 件は、名前と裏腹に実際の閾値が 90% である。アラーム名は Terraform への取り込み(import)の鍵であり、改名すると削除と再作成になって発報の履歴まで失われるため、名前は変えない方針を採っている。閾値の正はコード(terraform/monitoring-alarms/alarms.tf)であり、名前ではない。

通知の流れ ​

CloudWatch アラームが SNS トピックへ発報し、トピックが Lambda を呼び、Lambda が本文を組み立てて Slack へ投稿する。

経路の要素決めごと
通知先の指定60 件すべてが AlarmActions と OKActions の両方に h2t-alarm-notification を指す。発報も復帰も届く
投稿先Slack の Incoming Webhook。届く先のチャンネルは Webhook 側で決まる
Webhook URLSSM Parameter Store の /h2t/alarm-notifier/slack-webhook-url(SecureString)に置き、Lambda が実行のたびに復号して読む。コード・Terraform の state・ログには残さない
差し替えSSM のパラメータを書き換えるだけでよい。Terraform を適用し直す必要はない

Slack の本文は日本語で組み立てる。見出しで状態を区別するため、一覧を眺めるだけで発報と復帰を見分けられる。

状態見出し
ALARM🔴 ALARM 発生
OK🟢 OK 復旧
上記以外(INSUFFICIENT_DATA を含む)⚠️ と、受け取った値をそのまま

見出しに続けて、説明・状態の遷移(JST)・理由・対象(名前空間/メトリクス名/ディメンション)・条件(統計/比較演算子/閾値/間隔/評価回数)・リージョンを並べる。ComparisonOperator などの API の列挙値は原文のまま出す。CloudWatch の画面と突き合わせられるようにするためである。

自動復旧の 6 件(awsec2- で始まるもの)は、通知先に加えて arn:aws:automate:ap-northeast-1:ec2:recover を併記している。発報すると Slack へ届くと同時に、実際にインスタンスの復旧処理が走る。

発報したときの動き ​

Slack の通知を受けた担当者が、アラーム名から層を読み取って次の順に確認する。復帰(🟢 OK 復旧)が届くまで見届ける。

通知されたアラーム最初に確認すること
ELB.*.HealthyHostCount_under_1該当システムのサイトが応答するか。応答しなければサーバー(EC2)の状態へ進む
EC2.*.StatusCheckFailedインスタンスが動いているか。停止・再起動中でないか
awsec2-*(自動復旧)復旧処理が走っているため、復旧が終わってサービスが戻ったかまで見る
EC2.*.CPUUtilization_over_* / mem_used_percent_over_90何が使っているかをプロセス単位で見る。恒常的に高いならサイズの適正化(Issue #38)の対象になる
EC2.*.disk_used_percent_over_90ログやアップロードの肥大を疑う。空けても再発するなら容量そのものを見直す
RDS.*.CPUUtilization_over_90重いクエリと接続数を見る
RDS.*.FreeableMemory_under_100m / FreeLocalStorage_under_200m枯渇はサイトの停止に直結する。空き容量の回復を最優先で行う
Lambda.sync_database.Duration_over_150s / Lambda.fetch_search_ranking.Invocations_under_1_16hスクレイピングの起動が途絶えていないか。sync_database のログと VPC エンドポイントの状態を見る
Lambda.h2t-alarm-notifier.Errors_over_0**通知そのものが壊れている。**他の発報が Slack へ届いていない可能性があるため、CloudWatch のアラーム一覧を直接確認する

sync_database と fetch_search_ranking の発報は、Issue #41 と同じ壊れ方(外部へ到達できずに待たされる)を捉えるためのものである。切り分けの具体的な手順は h2t/infrastructure の docs/monitoring-alarms.md の「スクレイピングの検知が発報したときの調べ方」にまとめてある。

収集の仕組み ​

メモリとディスクは標準メトリクス(AWS/EC2)に含まれない。OS の中から送る必要があるため、EC2 8 台に CloudWatch agent を入れ、60 秒ごとに名前空間 H2T/EC2 へ送っている。

種別メトリクス名ディメンション
CPUcpu_usage_active / cpu_usage_idleInstanceId
メモリmem_used_percent / mem_used / mem_totalInstanceId
ディスクdisk_used_percent / disk_free / disk_usedInstanceId + path + device + fstype

ディスクだけディメンションが 4 つになるのは、agent がファイルシステムごとに path / device / fstype を自動で付けるためである。disk_used_percent には InstanceId だけの系列が存在せず、アラーム側で 4 つとも指定しなければ永久に INSUFFICIENT_DATA のままになる。device と fstype は台ごとに違うため、他の台の値を写して埋めてはならない。

導入状況 ​

インスタンスOSagentアラーム
gmac-app-productionAmazon Linux 初代導入済みあり
gcor-app-productionAmazon Linux 2導入済みあり
kingmeo-app-productionAmazon Linux 2導入済みあり
Kuchikomi OneAmazon Linux 初代導入済みあり
meo-timesAmazon Linux 初代導入済みあり
smart-meo-listingplusAmazon Linux 2導入済みあり
h2-dev-bastionAmazon Linux 2導入済み作らない(監視対象外)
gmac-stagingAmazon Linux 初代導入済み(mem_used と mem_total が欠けている)作らない(監視対象外)

この名前空間に依存しているもの ​

H2T/EC2 を読んでいるのはアラームだけではない。 費用のレポート(Lambda h2t-cost-report)と日次の健全性チェック(Lambda daily-health-check)も同じ名前空間とメトリクス名を読む。どちらも系列が見つからなければその項目を省いて投稿するだけでエラーにならないため、設定を変えると誰も気づかないまま値だけが欠けた投稿が続く。

変えたもの起きること
名前空間(H2T/EC2)2 つの Lambda とアラーム 12 件が一斉に値を失う
メトリクス名(mem_used_percent など)該当の項目だけが投稿から消える。日次レポートは他の行がそのまま出るため気づきにくい
append_dimensions を増やす系列が別物になり、既存の指定では引けなくなる
収集間隔(60 秒)値は届き続けるが、5 分単位で評価するアラームの点の数が変わる

したがって 1 台だけ設定を変えるということはしない。 変えるときは 8 台すべてを同じ内容にそろえ、アラームと 2 つの Lambda の側も併せて見直す。

運用 ​

対象の増減 ​

監視の対象を増やす・減らすときは、コンソールで直接触らず h2t/infrastructure の terraform/monitoring-alarms/ を直して適用する。コンソールで変えると次回の適用で打ち消され、変えたこと自体も記録に残らない。

場面直すもの
新しくアラームを作るalarms.tf に定義を足し、scripts/alarm_classification.json の added へ名前を足す
既存のアラームを管理下へ入れるalarms.tf と imports.tf の両方に足し、alarm_classification.json の keep へ名前を足す
管理下から外して消すalarms.tf(取り込んだものは imports.tf も)から取り除き、alarm_classification.json からも取り除く

いずれも件数の期待値を持つ検査があり、片方だけ直すと検査で止まる。具体的なコマンドは docs/monitoring-alarms.md の「対象の増減」を参照する。メモリ・ディスクのアラームを足すには、その台に CloudWatch agent が入っていて H2T/EC2 へ系列が届いていることが前提になる。

疑似発報のやり方 ​

通知が Slack まで届くことは、障害の発生を待たずに確かめられる。aws cloudwatch set-alarm-state でアラームを ALARM へ落とし、Slack に届いたことを確認してから OK へ戻す。種別ごとに 1 件以上を選んで行う。

awsec2- で始まる 6 件では行わない。 ec2:recover が併記されており、状態を ALARM にすると実際に復旧処理が走るためである。

変更するときに崩れる前提 ​

変えるもの併せて見直すもの
スクレイピングの定期実行の時刻(08:00 / 17:00 JST)起動の途絶を 16 時間で捉える前提が崩れる。Lambda.fetch_search_ranking.Invocations_under_1_16h の評価回数を見直す
CloudWatch agent の名前空間・メトリクス名・ディメンションアラーム 12 件と 2 つの Lambda が黙って値を失う
SNS トピック h2t-alarm-notification の削除60 件の通知先が宛先の無い ARN になる。Issue #30 の状態へ戻る

手順書の置き場所 ​

手を動かす手順は h2t/infrastructure の docs/ にある。

手順書扱う範囲
docs/monitoring-alarms.mdアラームの適用・差分の見方・疑似発報・対象の増減・不要なアラームの削除と切り戻し
docs/alarm-notification.md通知経路の適用・Webhook の差し替え・届かないときの確かめ方
docs/cloudwatch-agent.mdagent の設定・導入・確認

経緯 ​

2026 年 8 月、通知先の SNS トピックが存在せず、本番の多くのリソースに監視が付いていない状態が見つかった(h2t/infrastructure の Issue #30)。ここを起点に、通知経路を作り直し、既存のアラームを取捨選択して Terraform の管理下へ移し、不足していた監視を足し、メモリとディスクを取れるようにするところまでを段階的に整えた。その結果が本ページに記した 60 件である。

Issue行ったこと
#30監視が機能していないことの把握(起点)
#43通知経路の新設(SNS + Lambda + Slack)
#44既存アラームの整理。実体の無いものの削除と通知先の差し替え
#45未監視だった本番リソースへのアラーム追加
#46CloudWatch agent の導入。メモリ・ディスクを取れるようにした
#47Zabbix の残骸の撤去(進行中)
#50スクレイピングが実行されないことの検知