Based on the SOA-C02 exam guideReport an error
Redraw Week 2 picture in one sheet. When 3am alert arrives, what to check in what order? Bill suddenly $10,000 higher, where to start digging? "Some users slow," which query to run? Every CloudWatch tool ultimately answers these three questions.
If Week 2 is "data collection," Week 3 is "alerting and visualization," then Week 4+ automation/DR/cost management builds on top. As review week, today's focus: not re-explain concepts, but why designed this way and how broken in practice, bundled by case study, standard, and theory for depth.
CloudWatch started 2009 as simple metric service showing EC2 CPU, network, disk I/O. Then layered: Alarms (2010), Custom Metrics (2011), CloudWatch Logs (2014) most critical to operators, then Logs Insights (2018), EMF·Anomaly Detection (2019), Metric Stream (2021), Cross-Account Observability (2022) accumulated in time strata.
CloudWatch is not one coherently designed system but federation of tools on different data models. Metrics = time-series DB, Logs = append-only storage, Insights = distributed query engine on top, EMF = bridge between both. Scenario questions are hard because "is this data on metrics plane or logs plane?" determines answer.
💡 Related theory: "Three Pillars of Observability" — Metrics (aggregated numbers), Logs (discrete events), Traces (distributed paths). Peter Bourgon 2017 framing became OpenTelemetry standard (CNCF, 2019) foundation. CloudWatch Metrics = first, Logs = second, X-Ray = third pillar. EMF is bridge filling first and second with single log line, so "zero-cost metrics+logs unified" points to EMF.
🔍 Deeper context: "Metrics or logs" essence is cardinality. Metrics pre-define dimension combinations; low cardinality essential for cost/speed. Logs ingest all events; infinite cardinality acceptable but pay per-query scan cost. Hence rule: "high-cardinality (user_id, request_id, trace_id) as logs; low-cardinality (service, env, region) as metrics." This one line threads half of Week 2 — Metric Filter dimensions, EMF dimension vs metadata, Custom Metric cardinality explosion all variations.
(Namespace, MetricName, Dimensions, Timestamp, Value, Unit). One dimension set = one metric. Watch cardinality explosion.StorageResolution=1.parse/bin(). Billed by GB scanned.DefaultValue: 0 required.Review essence: not individual tools but incident response order. SOA-C02 scenarios almost always one of these three flows.
Scenario A — 3am alert ("service dying"): ① Metrics plane: which metric (CPU/Memory/5xx/Latency) alarmed? Anomaly band or fixed threshold → false positive? → ② Same timestamp Log Group via Logs Insights filter @message like /ERROR|Exception|timeout/ | stats count(*) by bin(1m) identify error spike timing → ③ X-Ray ServiceMap: which downstream (RDS/external API/lock contention) slow?
Scenario B — Bill explosion: Cost Explorer decompose CloudWatch sub-items → Logs Ingestion surge (VPC Flow Logs/debug, most common) / Storage surge (Never Expire accumulation) / Metrics surge (cardinality explosion) / API (per-request PutMetricData → EMF migration) / Insights scan (filter-less wide query) — identify which.
Scenario C — "Some users slow": Average lies → p99 Extended Statistic reveals long tail → metrics track p99 trend → logs filter duration > 1000 | stats count() by uri, user_id (user_id log field not dimension — shines here).
📚 Case study: February 28, 2017 AWS S3 us-east-1 major outage (4 hours) taught monitoring truth. Service Health Dashboard hosted in same-region S3; when outage hit, couldn't even turn dashboard red. Lesson: monitoring systems must separate fault domain from monitored systems. Critical alarms' SNS, dashboards in different account/region standard, why Cross-Region·Cross-Account Observability critical.
⚠️ Pitfall: Scenario A jumping straight to console graphs is antipattern. Metrics answer what (symptom), logs answer why (cause), traces answer where (location). Skipping order lands "graph is red but don't know why." Exam "what to check next for root cause" almost always means "descend one plane deeper."
| Item | Metric Filter | EMF | PutMetricData | Anomaly Detection |
|---|---|---|---|---|
| Publish time | Auto on log match | Auto on log output | Direct API call | Add to existing metric |
| Latency | ~30s-1min | ~1-2min | Near instant | Same as source |
| API call cost | Free | Free | $0.01 per 1,000 calls | Free |
| Metric storage cost | $0.30/metric | $0.30/metric | $0.30/metric | $0.30 + learning |
| Code change | N (existing logs) | Y (application) | Y | N |
| Apply to past data | N (forward-only) | N | N | △ (for learning) |
| When to use | Legacy app, can't modify | New code, unified | Immediate alarm, external | Time-pattern metrics |
| Item | CloudWatch Logs | CloudTrail Logs |
|---|---|---|
| Purpose | Application/system logs | AWS API call audit |
| Retention | 1d-10y or perpetual | Management Event 90d free; S3 perpetual |
| Cost | Ingestion $0.76/GB + Storage | Management Event free (first trail), Data Event separate |
| Analysis | Logs Insights / Subscription / Metric Filter | CloudTrail Lake / Athena |
| Real-time | Subscription Filter (seconds) | EventBridge (minutes) |
| Item | Basic | Detailed | CloudWatch Agent |
|---|---|---|---|
| Interval | 5min | 1min | 60s or 1s |
| Cost | Free | $2.10/month/instance | $0.30/metric/month |
| CPU/Network/Disk I/O | ✅ | ✅ | (duplicate) |
| Memory / Disk Usage / Swap | ❌ | ❌ | ✅ |
| Log collection | ❌ | ❌ | ✅ (syslog/journald) |
| Enable | Auto | Manual (tag) | Manual (SSM deploy) |
| Concept | CloudWatch | Prometheus | Datadog |
|---|---|---|---|
| Metric identification | Namespace + Dimensions | metric + labels | metric + tags |
| Cardinality explosion | dimension explosion → $0.30×N | label explosion → TSDB OOM | tag explosion → billing |
| Down-sampling | 1s→60s→5min→1hr | recording rules + Thanos | rollup interval |
| Dynamic baseline | Anomaly Detection (STL/ARIMA) | External tool | Watchdog (ML) |
| pull vs push | push (PutMetricData) | pull (scrape) | push (agent) |
🔍 Deeper context: Prometheus worst-case scenario identical to CloudWatch cardinality explosion — add
user_idorrequest_pathas label, cardinality explodes in memory, server dies OOM. CloudWatch explodes bill not memory, but root identical. Both violate "label/dimension must be finite enum" principle. See "per-user/per-request" → metric dimension nearly always wrong — AWS-specific trap but universal time-series monitoring principle.
Bill (B) most frequent SOA-C02 scenario. CloudWatch costs leak five ways: Logs Ingestion ($0.76/GB) + Logs Storage ($0.033/GB·month) + Metrics ($0.30 each) + API ($0.01 per 1k calls) + Insights scan ($0.005/GB). Key: each path unit cost differs 30x to hundreds x.
| Data destination | Unit price | Note |
|---|---|---|
| CW Logs Ingestion | $0.76/GB | Most expensive. Once in, can't unsee |
| CW Logs Storage | $0.033/GB·month | Never Expire = perpetual accumulation |
| S3 Standard | $0.023/GB·month | Storage at 1/1.4 cost |
| S3 Glacier Deep Archive | $0.00099/GB·month | Storage at 1/33 cost |
| Logs Insights / Athena scan | $0.005/GB | filter, partitioning minimize scan |
Two operator standard decisions emerge:
📚 Case study: Early 2020s fintech/gaming companies hit "all VPC Flow Logs to CloudWatch Logs" → multi-thousand dollar bills. Flow Log generates tens-hundreds GB/day per ENI; most no alarms, just accumulation → $0.76/GB Ingestion compounds. Fix: (a) destination S3, (b) real-time security needs (REJECT surge) sample to CloudWatch, (c) rest S3 + Athena. 70-90% savings common.
⚠️ Pitfall: "Shorter retention reduces cost" half-true. Shortening reduces Storage only; already-incurred Ingestion ($0.76/GB) uncoverable. High-volume log problem → reduce incoming volume (destination change, log level, sampling), not retention. "Ingestion cost explosion" scenario with "reduce retention" as option → trap answer.
Review most-common misconception: "EC2 memory from Detailed Monitoring." Detailed only shortens 5min→1min interval, doesn't add metric types.
Root cause: measurement location. EC2 CPU, network, disk I/O measured at hypervisor level (Nitro System) (CPUUtilization, NetworkIn/Out, EBS Read/WriteOps). Even hung guest OS, hypervisor sees vCPU scheduling and block I/O → measurement continues. But memory usage, disk usage (df), swap = guest OS page table, filesystem metadata — hypervisor can't see (mem_used_percent, disk_used_percent, swap_used_percent → Agent required). If visible, violates virtualization isolation.
🔍 Deeper context: This boundary = IaaS vs PaaS/FaaS responsibility split. Lambda, Fargate include memory as standard metric — AWS operates guest OS, can expose OS internals. "Is memory metric standard" = who owns OS? result. Hence "EC2 memory" → Agent, "Lambda/Fargate memory" → standard metric (or REPORT
maxMemoryUsed).
⚠️ Pitfall: "Memory-based Auto Scaling won't work" scenario. ASG Target Tracking supports standard metrics (CPU, ALBRequestCountPerTarget) by default; memory not standard. Fix: Agent publishes
mem_used_percentas custom metric, then custom metric target tracking or step scaling. No Agent = no memory scaling possible.
Scenario C essence: statistic choice. Why average dangerous, nail theoretically.
Latency distribution not normal but long right tail (heavy-tail). Mostly fast but GC pause, lock contention, cold cache, network retransmit make few requests 5-50x slower. Average pulled by majority hides long tail.
💡 Related theory: Gil Tene "How NOT to Measure Latency" (Strange Loop 2015) required. (1) Average, std-dev meaningless for latency (not normal distribution), (2) Coordinated Omission: load test tool waits slow response, misses requests during that time, worst periods vanish from measurement — systematic error. "10 of 1000 take 5sec" only shows p99; average (200ms) never reveals.
💡 Related theory: Dean & Barroso "The Tail at Scale" (CACM, 2013) — one request fan-out to 100 services, each p99 = 1%, odds at least one slow = 1-(0.99)^100 ≈ 63%. Scale increases, tail becomes normal experience — why p99 monitoring mandatory in microservices mathematically.
⚠️ Pitfall: SLO defined "average < 300ms" = practically no SLO. Average completely hides 1% 5-second responses. Standard: "p99 < N ms" and alarm statistics must match SLO percentile. Alarm Average, SLO p99 → quiet alarm but SLO violation paradox. CloudWatch ExtendedStatistic supports p50-p99.9.
Metric Filter applies patterns only to newly arriving logs (forward-only). Yesterday's errors don't catch by today's filter. Not bug, architectural result.
🔍 Deeper context: Metric Filter evaluates patterns during log stream processing time (ingestion). Logs Insights queries stored logs post-hoc batch. Difference = forward-only vs historical query essence, past requires Insights aggregation. Stream vs batch = classic data engineering dichotomy (Lambda Architecture, Kleppmann Designing Data-Intensive Applications); CloudWatch provides both.
⚠️ Pitfall: Without
DefaultValue, pattern-no-match emits no data point (not 0, missing). Alarm stays INSUFFICIENT_DATA; error 0 means no evaluation.DefaultValue: 0ensures "no match = 0" published normally. Half of "Metric Filter alarm won't trigger" is this trap.
Fixed thresholds generate false positives on time-pattern metrics. Anomaly Detection learns pattern, builds dynamic band.
💡 Related theory: CloudWatch Anomaly Detection uses STL (Seasonal-Trend decomposition using LOESS) (Cleveland et al., 1990, Journal of Official Statistics) and ARIMA family, decomposing time-series into trend, seasonality, residual. Same family: Facebook Prophet (2017), Twitter AnomalyDetection (S-H-ESD, 2015), LinkedIn Luminol, Netflix Surus. Core: "what normal value Tuesday 2pm" learned per weekday/hour; metric deviating ±N std-dev from expected → anomaly.
⚠️ Pitfall: Anomaly Detection has cold-start. Needs min 2 days, reliably 2 weeks data for meaningful band. Immediate new-metric application makes band abnormally wide or narrow, alarms worthless. "New service enabled, alarms exploded / never triggered" both stem from data immaturity; answer "enable after data accumulation." Same cold-start issue as ML recommenders.
filter in Logs Insights has both cost/speed effects?DefaultValue prevents alarm silence?Click a choice to reveal the answer and explanation.
Question 1
EC2 Auto Scaling Group configured for CPU > 70% scale-out, but traffic surge causes 5-min response delay. Biggest cause and fix?
Question 2
CloudWatch Logs cost 5x in 3 months. Operator must first check?
Question 3
Track Lambda cold start frequency. Most appropriate Logs Insights query?
Question 4
Track per-user API calls. Most cost-efficient, scalable pattern?
Question 5
Company extracting API 5xx from ALB Access Logs for alarm. Most suitable flow?
Question 6
New microservice EMF adoption without code modification. Correct EMF usage?
Question 7
Anomaly Detection alarm set; 5 days no trigger. Likely cause?
Question 8
Cross-account: 50 accounts' ERROR logs real-time analyze central. Most suitable?
Question 9
Company needs ERROR count metric, can't modify Lambda code. Suitable method?
Question 10
Response time SLO defined p99 < 1sec. Best alarm statistic?
Question 11
Large VPC sent all Flow Logs to CloudWatch Logs; bill >$20k/month. Most effective cost cut?
Question 12
Company needs 7-year audit log retention, minimize cost. Standard pattern?
Week 3 monitoring deep-dive — Alarms, Dashboards, Agent, Synthetics·RUM·X-Ray.
Week 2 = "data collection"; Week 3 = "alerting, visualization." Most SOA-C02 scenarios here. Today's metrics/logs plane split, cost five paths, p99 priority become Week 3 alarm/dashboard design foundation.