What to Configure When Monitoring Servers and Databases 24/7
公開日 2026-08-13 · 更新日 2026-08-13 · 最終検証日 2026-08-13
結論
Design liveness monitoring, performance monitoring, and log monitoring as three separate things, and assign metrics across the host, database, and application layers. On top of that, always add synthetic monitoring that checks, from outside, the very path users actually take. An event where everything is fine internally but users are failing can still happen, and only synthetic monitoring can prevent a "the customer notices first" situation. Build thresholds not as a single fixed value but around conditions of duration and rate of change.
この文書の適用条件
| 対象製品 | Amazon RDS / Amazon Aurora / SQL Server / MySQL / Amazon CloudWatch |
|---|---|
| 確認バージョン | AWS CLI v2 / the public API of Amazon CloudWatch, MySQL 5.7 and later, SQL Server 2012 and later (based on the specification as of 2026-08-13) |
| 適用環境 | AWS, Azure, on-premises |
| 必要権限 | Creating a CloudWatch alarm requires `cloudwatch:PutMetricAlarm`. Checking MySQL state requires `PROCESS`-equivalent privileges; SQL Server requires `VIEW SERVER STATE` |
| 実行影響 | The SQL is read-only. `put-metric-alarm` creates a new CloudWatch alarm resource |
| 再起動 | Not required |
| 最終検証日 | 2026-08-13 |
そのまま実行できるコマンド
- 対象
- Amazon CloudWatch (AWS CLI v2)
- 権限
- cloudwatch:PutMetricAlarm
- 変更作業
- Yes (creates or overwrites a CloudWatch alarm)
- Production実行
- Possible, but decide the notification target and response procedure before creating it
# 対象: Amazon CloudWatch(AWS CLI v2)
# 権限: cloudwatch:PutMetricAlarm
# 変更作業: あり(同名アラームが存在する場合は上書きされる)
# Production 実行: 可能。通知先とランブックを用意してから作成すること
#
# 通知先の SNS トピック ARN は環境変数で渡す(この文書には実 ARN を記載しない)
# export SNS_TOPIC_ARN="<自環境の SNS トピック ARN>"
aws cloudwatch put-metric-alarm \
--alarm-name "rds-db-sample-instance-cpu-sustained" \
--alarm-description "CPU使用率が継続して高い状態を検知する" \
--namespace AWS/RDS \
--metric-name CPUUtilization \
--dimensions Name=DBInstanceIdentifier,Value=db-sample-instance \
--statistic Average \
--period 300 \
--evaluation-periods 3 \
--datapoints-to-alarm 3 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--treat-missing-data missing \
--alarm-actions "$SNS_TOPIC_ARN" \
--ok-actions "$SNS_TOPIC_ARN"`--threshold 80` is only there to show the syntax — it is not a recommended value. Decide the threshold from your own environment's normal-time distribution (p95, p99). The key point is that `--evaluation-periods` and `--datapoints-to-alarm` make "sustained" a condition. Firing on a single spike is a cause of alert fatigue. Specifying `--treat-missing-data` is mandatory so the behavior during a data gap is decided explicitly.
- 対象
- MySQL 5.7 and later / Amazon Aurora MySQL
- 権限
- Read access to global status variables (`PROCESS`-equivalent privilege)
- 変更作業
- None (read-only)
- Production実行
- Possible
-- 対象: MySQL 5.7 以降 / Amazon Aurora MySQL
-- 権限: グローバル状態変数の参照権限(PROCESS 権限相当)
-- 変更作業: なし(参照のみ)
-- Production 実行: 可能
-- 現在の接続数
SHOW STATUS LIKE 'Threads_connected';
-- 起動以降の最大同時接続数(ピークの把握に使う)
SHOW STATUS LIKE 'Max_used_connections';
-- 接続上限
SHOW VARIABLES LIKE 'max_connections';
-- 上限に達して拒否された接続の累計
SHOW STATUS LIKE 'Aborted_connects';Compare `Threads_connected` against `max_connections` to get a utilization ratio. Since `Max_used_connections` is the peak since startup, it reveals a spike that an instantaneous reading would miss. For monitoring, look at the utilization trend, not just an instantaneous value.
- 対象
- SQL Server 2012 and later / Amazon RDS for SQL Server
- 権限
- VIEW SERVER STATE
- 変更作業
- None (read-only)
- Production実行
- Possible
-- 対象: SQL Server 2012 以降 / Amazon RDS for SQL Server
-- 権限: VIEW SERVER STATE
-- 変更作業: なし(参照のみ)
-- Production 実行: 可能
SELECT
(SELECT COUNT(*) FROM sys.dm_exec_sessions
WHERE is_user_process = 1) AS user_sessions,
(SELECT COUNT(*) FROM sys.dm_exec_requests
WHERE session_id > 50) AS active_requests,
(SELECT COUNT(*) FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0) AS blocked_requests,
@@MAX_CONNECTIONS AS max_connections_configured;`@@MAX_CONNECTIONS` returns the configured limit. If `sp_configure`'s `user connections` is 0 (the default), the product's default limit is returned, so the real constraint becomes memory and worker threads. What matters for monitoring is less the ratio to the limit and more the trend of `blocked_requests` — once it starts climbing, move on to investigating a blocking chain.
- 対象
- Amazon CloudWatch (AWS CLI v2)
- 権限
- cloudwatch:DescribeAlarms
- 変更作業
- None (read-only)
- Production実行
- Possible
# 対象: Amazon CloudWatch(AWS CLI v2)
# 権限: cloudwatch:DescribeAlarms
# 変更作業: なし(参照のみ)
# Production 実行: 可能
aws cloudwatch describe-alarms \
--query "MetricAlarms[].{Name:AlarmName,Metric:MetricName,\
Threshold:Threshold,Periods:EvaluationPeriods,Missing:TreatMissingData,\
State:StateValue,Actions:AlarmActions[0],Enabled:ActionsEnabled}" \
--output tableAn alarm where `Enabled` is false, one where `Actions` is empty, or one whose `State` has been `INSUFFICIENT_DATA` for a long time is effectively non-functional. When inventorying monitoring setup, look for these three first.
結果の読み方
| 列 | 意味 | 確認するポイント |
|---|---|---|
| Threads_connected / user_sessions | Current connection count | Look at the ratio to the limit. If pegged just below the limit, suspect pool configuration or a leak |
| Max_used_connections | Max concurrent connections since startup | A peak invisible from an instantaneous reading. If close to the limit, there's no headroom |
| max_connections / max_connections_configured | The configured connection limit | Whether the application-side pool's combined maximum exceeds this |
| Aborted_connects | Cumulative count of connections that failed to establish | A continuing increase points to auth failures or hitting the limit — cross-check against log monitoring |
| active_requests | Number of currently executing requests | A high connection count with a low active count indicates idle connections, which calls for a different response |
| blocked_requests | Number of blocked requests | The point where it starts rising from zero is where investigation begins; if sustained, trace the blocking chain |
| AlarmName / State | Alarm name and current state | One stuck at INSUFFICIENT_DATA for a long time isn't actually being monitored |
| TreatMissingData | How a data gap is handled | Left unspecified, behavior during a gap can differ from what's intended — decide this explicitly |
| ActionsEnabled / AlarmActions | Whether notification is enabled, and its destination | If false or the destination is empty, it fires but reaches no one |
こういう状況で使います
- An incident is sometimes learned about from a customer report
- There are too many alerts, and important ones get buried
- Who responds overnight and on holidays hasn't been decided
- Alerts arrive, but the recipient doesn't know what to do
- Monitoring is in place, but there's no list of what is actually being monitored
- Only easy-to-understand metrics like CPU utilization are watched, while lock waits and replication lag are not
考えられる原因(可能性の高い順)
01
The three types of monitoring are not distinguished
Liveness monitoring (does the process or endpoint respond), performance monitoring (does it respond but has it slowed down), and log monitoring (are errors occurring) differ in purpose and in what they can detect. Relying on just one misses whatever the other two would have caught.
02
Only internal metrics are being watched
Even with CPU, memory, and connection count all normal, a problem with DNS, the load balancer, a certificate, an application exception, or an external dependency can leave the service unusable from the user's side. No amount of internal metrics can monitor that path.
03
Thresholds are designed as a single fixed value
A single-shot condition like "notify if CPU exceeds 80%" fires even on a normal spike. Alerts that fire too often get ignored, and real alerts end up missed as a result. Duration (how many times in a row it was exceeded) and rate of change (the deviation from normal) need to be built into the condition.
04
Alerts have no response procedure attached
Without deciding what the recipient should check, how far they can handle it themselves, and under what condition to escalate, a notification stops at "noticed" and never turns into a response.
05
No structure is designed for nights and holidays
24/7 monitoring is not "the monitoring tool runs 24/7" — it is "it reaches someone who can respond, 24/7." Without an on-call rotation, a next contact when someone cannot be reached, and a way to spread the load among responders, a notification at 2am just sits there until the next morning.
06
The monitoring configuration has never been inventoried
A notification destination still pointing at a former employee, an action left disabled, or a target resource that has already been deleted — these all become "monitoring that exists but does not work." Correct at the time it was configured, it degrades over time.
確認手順
- 1
Build a list of what is monitored
参照のみList out what is currently monitored at each of the host, database, and application layers. Make the current state visible before discussing gaps.
- 2
Check whether synthetic monitoring exists
参照のみCheck whether anything monitors, from outside, the path users actually take (DNS → LB → app → DB). If not, this is the top-priority addition.
- 3
Inventory alarms
参照のみUse `describe-alarms` to find ones that are disabled, have an empty notification destination, or have been `INSUFFICIENT_DATA` for a long time.
- 4
Count how many alerts fired in the past
参照のみCount how many fired in the last month and how many of those actually required a response. A high no-response-needed ratio points to threshold design as the cause.
- 5
Review how past incidents were actually detected
参照のみFor recent incidents, check whether monitoring caught it first or a user report came first. Any instance of the latter pinpoints a monitoring gap.
- 6
Write out the escalation path
参照のみDocument the first responder, the second responder, a fallback when someone cannot be reached, and who is responsible when a judgment call is needed.
- 7
Add alarms
低Create alarms for any gaps with `put-metric-alarm`. Prepare the notification destination and runbook before creating one.
対応方法
すぐに実施できる低リスクの対応
Add synthetic monitoring
低Periodically send requests from outside to the endpoint users actually use, and record the status code and response time. This is the only way to prevent a "the customer notices first" situation.
Fix alarms whose notifications never arrive
低Fix alarms where ActionsEnabled is false, the notification destination is empty, or the destination address is invalid. This comes before adding more monitoring items.
事前検討が必要な変更
Assign monitoring items per layer
低Host layer: CPU, memory, swap, disk usage, disk wait time, network. Database layer: connection count and limit, active session count, lock waits and blocking chains, replication lag, transaction log / binlog usage, slow query count, buffer cache hit ratio, login failures. Application layer: HTTP status ratio, response time percentiles, queue backlog.
Build duration and rate of change into thresholds
低Condition on "exceeded n times in a row" rather than a single excursion, and combine it with items judged by deviation from the normal-time distribution. In CloudWatch, this corresponds to `--evaluation-periods` and `--datapoints-to-alarm`.
Prepare a runbook for each alert
参照のみFor each alert, write down what to check, how far the responder may act on their own, and under what condition to escalate. Making "no runbook, no alert" an operational rule works well.
Document escalation criteria
参照のみDefine the scope of first-line response, the condition for handing off to second-line, and the condition for bringing in the person responsible. Time spent hesitating on a judgment call becomes response delay.
Design the on-call structure
参照のみSet the rotation cycle, a fallback contact when someone cannot be reached, and comp time after an overnight response — something people can sustain. A structure that cannot be sustained becomes hollow within a few months.
Add log monitoring
低Detect events that never show up in a metric, such as database error logs, authentication failures, the OOM killer, and disk-related kernel messages.
再起動・サービス影響を伴う変更
Consolidate the monitoring platform
高Consolidating monitoring spread across multiple tools changes the notification path and dashboards. Running old and new in parallel during the migration is necessary, and a monitoring gap during the cutover is the biggest risk.
Introduce an automated recovery action
専門家レビュー必須A mechanism that automatically restarts or fails over based on an alarm will cause an outage on its own in the event of a false positive. If you introduce one, scope its trigger conditions tightly and always provide a manual stop.
!注意事項
- This article gives no numeric targets such as SLA, MTTR, or time-to-detect. These are determined by the target system's requirements and structure, and applying a generic figure has no meaning — define them from your own requirements.
- Thresholds such as `--threshold 80` are only examples to show the syntax, not recommended values. Measure the normal-time distribution (p95, p99) before deciding them.
- More monitoring items is not automatically better. An alert with no response procedure adds to the judgment cost on the ground every time it fires, dulling the overall response as a result.
- `put-metric-alarm` overwrites an existing alarm of the same name without confirmation. Watch for a name collision with an existing alarm.
- Even with all internal metrics normal, a state unusable from the user's perspective can still occur. No internal metric can substitute for synthetic monitoring.
- An automated recovery action stops the service on its own in the event of a false positive. Before introducing one, always design for the impact of a false positive and a way to stop it.
バージョン・環境による違い
これで解決しない場合に確認すること
Test whether notifications actually arrive
Send a test notification and confirm it reaches the recipient, including overnight hours. Even when the configuration is correct, it can be dropped by a filter on the receiving end.
Check for resources that fell through the cracks of monitoring
Periodically check whether newly created instances are included in the monitoring setup. Automating alarm creation at instance-creation time is effective.
Feed past incidents back into the monitoring items
For each incident that occurred, verify whether a given monitoring item would have caught it sooner, and add whatever was missing.
Periodically review how many alerts have fired
If many alerts require no action, review the thresholds or the monitoring items themselves. Use the trend in the count as a metric in its own right.
Check whether the runbook content still matches reality
If the runbook isn't updated after a configuration change, the procedure drifts from reality. Assign ownership for periodic updates.
この文書の根拠と限界
一般的な技術説明
Based on the public specification of Amazon CloudWatch alarms, MySQL status variables, SQL Server dynamic management views (sys.dm_exec_sessions, sys.dm_exec_requests), and general thinking around monitoring design. It includes no numeric targets such as SLA, MTTR, or detection time, and no measurements from any specific environment. Determine thresholds from your own environment's normal-time distribution.
よくある質問
What should be configured for 24/7 monitoring?
Design liveness monitoring, performance monitoring, and log monitoring separately, and assign items to the host layer (CPU, memory, swap, disk usage, disk wait time, network), the database layer (connection count and limit, active sessions, lock waits and blocking, replication lag, log/binlog usage, slow queries, buffer hit ratio, login failures), and the application layer (HTTP status ratio, response time percentiles, queue backlog). Also always add synthetic monitoring of the user-facing path.
How can a situation where the customer notices an incident first be prevented?
No amount of internal metrics can prevent it. Add synthetic monitoring that periodically probes, from outside, the path users actually take (DNS, load balancer, certificate, application, database). Even with every internal metric normal, a failure visible only from the user's side can still occur somewhere along that path.
There are too many alerts and people have stopped looking at them. What should be done?
Review the threshold design. Condition on duration (how many times in a row it was exceeded) rather than a single excursion, and combine it with items judged by deviation from the normal-time distribution. On top of that, adopting a rule of "no runbook, no alert" reduces the number of alerts no one can explain.
What percentage should a threshold be set to?
No generic figure can be given — the normal operating percentage differs completely by environment. First measure the normal-time p95 and p99, then build the condition around the deviation from that and the duration of exceeding the threshold. The `--threshold 80` in the example command is only there to show the syntax.
How should a structure for nights and holidays be built?
Decide and document the on-call rotation cycle, the scope of first-line response, a fallback contact when someone cannot be reached, escalation criteria, and comp time after an overnight response. 24/7 monitoring is not about the tool running — it is about reaching someone who can respond. Periodically review whether the load is sustainable.
Can this be run in production?
The SQL for checking connection count and `describe-alarms` are read-only and can be run in production as well. `put-metric-alarm` creates a new alarm and overwrites one of the same name, so run it only after preparing the notification destination and response procedure.
この文書がカバーする質問
- How to prevent customers from discovering an incident first
- Want to know what metrics to watch for database monitoring
- Too many alerts to handle
- How to build a structure for overnight/holiday incident response
リスク表示の意味
- 参照のみデータと設定を変更しません。
- 低影響は限定的ですが、権限と負荷の確認が必要です。
- 中性能・ロック・コストに影響する可能性があります。
- 高障害・データ損失・復旧作業が発生する可能性があります。
- 専門家レビュー必須本番適用前に別途レビューが必須です。
GIIPの対応範囲
Building a list of monitoring items is itself just a design task that finishes. What's hard about 24/7 monitoring is two things: having someone awake overnight and on holidays, and being able to judge what to do once an alert arrives. At GIIP, an AI agent handles the first-pass triage (cross-checking metrics, reviewing recent change history, identifying the scope of impact) across several databases on AWS and Azure and roughly 30 web services, while a human specialist makes irreversible decisions such as a restart or a failover. The idea is not to assume a human is glued to a screen 24 hours a day, but to keep at least the initial response always running.
執筆・技術検証
GIIP プロダクション運用チーム
大規模Webサービス、SQL Server、Oracle、AWS、Azureの設計・移行・運用に約30年従事。x12largeクラスのAWS RDS for SQL Server環境12セット、約12万テーブルのOracle環境、約3TBのTiDBからAurora MySQLへの移行を経験。現在も複数のクラウドデータベースと約30のWebサービスを、AIエージェントと人間の専門家が継続的に監視・運用しています。
The Difference Between One Large RDS Instance and Several Smaller Instances
A document organizing the technical differences between "one large instance" and "several smaller instances" for RDS sizing, and the CloudWatch metrics you should measure before deciding.
infrastructureWhat's the Difference Between EBS IOPS and Physical Disk IOPS
A document organizing why EBS IOPS cannot be compared directly to physical disk IOPS, based on where the ceiling applies (volume vs. instance) and how to measure it.
sql-serverHow to Check Transaction Log Usage on RDS for SQL Server
A read-only procedure that checks log usage with DBCC SQLPERF(LOGSPACE) and sys.dm_db_log_space_usage, and isolates the reason it is not being released using log_reuse_wait_desc.
aurora-mysqlHow to Check and Configure binlog Retention in Aurora MySQL
Check binlog retention with `mysql.rds_show_configuration` and set it in hours via `mysql.rds_set_configuration`. `binlog_format` is a cluster parameter and changing it requires a restart.
関連サービス
Get a consultation on 24/7 monitoring design and structure
同じ確認を複数の環境で継続する必要がある場合は、運用体制ごと相談できます。
Get a consultation on 24/7 monitoring design and structure