Lab: Instrument แอป Node.js + Alert
Lab ที่แล้วเราดู metric ของ เครื่อง คราวนี้เราจะ ฝัง metric ในโค้ดแอปเอง (RED metrics ตามบทที่ 22) แล้วตั้ง Alertmanager ให้เด้งเตือนเมื่อ error/latency พุ่ง — ครบวงจร instrument → scrape → alert
ไฟล์พร้อมรันที่
docker/prometheus/lab-metrics-02/— มีแอป Node.js (app/app.js), alert rules (prometheus/rules/), และ Alertmanager config ให้แล้ว
Stack: แอป Node.js (prom-client) + Prometheus (+ rules) + Alertmanager + Grafana
ขั้นที่ 1: ดูโค้ดแอปก่อนรัน
เปิด app/app.js — จุดสำคัญคือ 3 ส่วนของ RED (จากบทที่ 22):
// R + E: นับ request แยกตาม method/route/status
const httpRequests = new client.Counter({
name: "http_requests_total",
labelNames: ["method", "route", "status"], // low-cardinality!
...
});
// D: histogram วัด latency
const httpDuration = new client.Histogram({
name: "http_request_duration_seconds",
buckets: [0.005, 0.01, 0.05, 0.1, 0.3, 0.5, 1, 3, 5],
...
});
แอปมี endpoint จำลองไว้ให้เล่น:
| Endpoint | พฤติกรรม | ใช้ดูอะไร |
|---|---|---|
/work |
เร็ว ปกติ | baseline |
/slow |
ช้า 200–1200ms | latency p95/p99 พุ่ง |
/error |
error 50% | error rate + trigger alert |
/metrics |
endpoint ที่ Prometheus scrape | ดู metric ดิบ |
ขั้นที่ 2: รัน stack
cd docker/prometheus/lab-metrics-02
docker compose up -d --build # --build เพราะต้อง build image ของแอป
docker compose ps
ขั้นที่ 3: ดู metric ดิบที่แอปพ่นออกมา
curl http://localhost:3000/metrics | grep http_requests_total
ตอนแรกอาจว่างเพราะยังไม่มี request — ลองยิงแอปสัก 2-3 ครั้งก่อน:
curl http://localhost:3000/work
curl http://localhost:3000/work
curl http://localhost:3000/metrics | grep http_requests_total
ตอนนี้จะเห็น:
http_requests_total{method="GET",route="/work",status="200"} 2
นี่คือ counter จริงที่คุณสร้างเองในโค้ด! สังเกต label
route="/work"เป็น route pattern ไม่ใช่ raw URL — ตามหลักกัน cardinality explosion จากบทที่ 13
ขั้นที่ 4: สร้าง load เพื่อดู RED เคลื่อนไหว
รันคำสั่งนี้ทิ้งไว้เพื่อยิง request รัวๆ (จำลอง traffic จริง):
# ยิงผสมกัน work/slow/error ทุก 0.2 วินาที (กด Ctrl+C เพื่อหยุด)
while true; do
curl -s localhost:3000/work > /dev/null
curl -s localhost:3000/slow > /dev/null
curl -s localhost:3000/error > /dev/null
sleep 0.2
done
เปิด Prometheus (http://localhost:9090/graph) แล้วดู RED ครบสูตร:
# R — request rate ต่อวินาที
sum(rate(http_requests_total[1m]))
# E — error rate (เราทำเป็น recording rule ไว้แล้ว!)
job:http_error_rate:ratio5m
# D — p95 latency (recording rule)
job:http_p95_latency:seconds
job:http_error_rate:ratio5mคือ recording rule ที่เรานิยามไว้ในprometheus/rules/app-rules.yml— Prometheus คำนวณให้ล่วงหน้า (บทที่ 21) ลองเทียบกับการเขียน query เต็มดู จะเห็นว่าสั้นลงเยอะ
ขั้นที่ 5: ดู alert rules
เปิด Status → Rules ใน Prometheus จะเห็น alert 3 ตัว (HighErrorRate, HighLatencyP95, TargetDown)
เพราะ /error fail 50% (เกิน threshold 5%) และ /slow ช้า (เกิน 500ms) รอสัก 30 วินาที (for: 30s) แล้วดูที่ Alerts tab — alert จะเปลี่ยนจาก PENDING (สีเหลือง) → FIRING (สีแดง)
PENDING = เงื่อนไขเป็นจริงแล้ว แต่ยังไม่ครบเวลา for:
FIRING = เป็นจริงครบเวลาแล้ว → ส่งไป Alertmanager
ขั้น
PENDING → FIRINGคือfor:ในบทที่ 14 ที่ทำงานจริง — มันกัน alert ที่เกิดจาก spike ชั่ววูบไม่ให้ปลุกคนโดยไม่จำเป็น
ขั้นที่ 6: ดู alert ที่ Alertmanager
เปิด http://localhost:9093 — Alertmanager จะแสดง alert ที่ FIRING โดย จัดกลุ่ม ตาม alertname/severity (ตาม group_by ใน config)
ลองสังเกต:
- alert ถูกรวมกลุ่ม ไม่ได้ยิงทีละอันรัวๆ (ลด noise)
HighErrorRateมีseverity: page,HighLatencyP95มีseverity: ticket— คนละความรุนแรง (บทที่ 14)
ใน lab นี้ Alertmanager ยังไม่ต่อปลายทางจริง (Slack/PagerDuty) — ดูวิธีต่อ Slack ได้ใน comment ของ
alertmanager/alertmanager.ymlแค่ใส่ webhook URL จริงก็ส่งเข้า Slack ได้เลย
ขั้นที่ 7: ทดสอบ alert หาย (resolve)
หยุด load generator (Ctrl+C) แล้วรอ — เมื่อ error rate ตกกลับต่ำกว่า 5% ต่อเนื่อง alert จะเปลี่ยนเป็น RESOLVED และหายไปจาก Alertmanager เอง นี่คือ lifecycle ครบวงจรของ alert
ขั้นที่ 8 (ท้าทาย): ทำ RED dashboard ใน Grafana
เปิด Grafana (http://localhost:3001, admin/admin) แล้วสร้าง dashboard 3 panel ตาม RED:
- Rate:
sum(rate(http_requests_total[1m]))— unit: req/s - Errors:
job:http_error_rate:ratio5m— unit: percent (0.0-1.0), threshold แดงที่ 0.05 - Duration:
job:http_p95_latency:seconds— unit: seconds, threshold แดงที่ 0.5
นี่คือ RED dashboard template จากบทที่ 11 & 23 ที่คุณเอาไปใช้กับทุก service ได้
ทำความสะอาด
docker compose down -v
✅ Checklist
- เข้าใจโค้ด instrument (Counter + Histogram) ใน
app.js - เห็น metric ดิบที่
/metricsขยับตาม request - เขียน/ใช้ recording rule สำหรับ error rate + p95
- เห็น alert เปลี่ยน PENDING → FIRING → RESOLVED
- เข้าใจการจัดกลุ่ม + severity ใน Alertmanager
- ทำ RED dashboard เอง
สรุป
คุณเพิ่งทำครบ pipeline ของ metrics pillar: instrument โค้ด → Prometheus scrape → recording/alert rules → Alertmanager → dashboard นี่คือสิ่งที่ทีม production ทำจริงทุกวัน 🎉
จบ Module 2! ต่อไปไป Module 3 — Logs ทบทวน ELK ที่คุณมีอยู่ให้เป็นระบบ แล้วต่อยอด