จากโพสต์ที่แล้วเราเรียนรู้ IaC — ใช้ Terraform สร้าง infrastructure และ Ansible ตั้งค่า server อัตโนมัติ
แต่หลังจาก deploy ขึ้น production แล้ว... จะรู้ได้ยังไงว่า app ทำงานปกติ? Server จะล่มตอนไหน? User กำลังเจอ error อะไร? 🔍
นี่คือที่มาของ Monitoring & Observability — ระบบที่ทำให้เรา "มองเห็น" ทุกอย่างที่เกิดขึ้นข้างใน เหมือน DevOps Engineer ที่นั่งจ้องจอ dashboard ตลอดเวลา 🐕🦺📊
Monitoring vs Observability — ต่างกันยังไง?
หลายคนใช้สองคำนี้แทนกัน แต่จริงๆ ต่างกัน — Monitoring คือ "ดูว่าระบบยังทำงานปกติไหม" (CPU สูงไหม? disk เต็มไหม? error rate เพิ่มไหม?) เป็นการถามคำถามที่ "รู้อยู่แล้ว" ส่วน Observability คือ "สามารถเข้าใจได้ว่าระบบเป็นยังไงจากข้อมูลที่ส่งออกมา" — ตอบคำถามที่ "ยังไม่เคยถาม" ได้ เหมาะกับ microservices ที่ complex และ failure modes คาดเดาไม่ได้:
| Monitoring | Observability |
|---|---|
| ตอบว่า "มีปัญหามั้ย?" | ตอบว่า "ทำไมถึงมีปัญหา?" |
| ตรวจสิ่งที่เรา รู้ล่วงหน้า | หาสิ่งที่เรา ไม่เคยคิดถึง |
| Dashboard + Alerts | Explore + Drill-down + Correlate |
| CPU สูง → แจ้งเตือน | ทำไม CPU สูง? → trace → พบ query ช้า |
💡 จำง่ายๆ: Monitoring = ติดกล้องวงจรปิด | Observability = มีนักสืบวิเคราะห์ภาพ
3 Pillars of Observability
ระบบ Observability ที่ดีต้องมีข้อมูล 3 ประเภทที่ทำงานเสริมกัน — Metrics บอกว่า "มีปัญหาไหม" (ตัวเลข), Logs บอกว่า "เกิดอะไรขึ้น" (events), Traces บอกว่า "ช้าตรงไหน" (request flow) ขาดอันใดอันหนึ่งก็ debug ยาก:
Pillar 1: Metrics — ตัวเลขที่ต้องจับตา
Metrics คือตัวเลขที่วัดได้ตามเวลา (time-series data) — CPU usage 72%, response time 230ms, error rate 0.5% เหมาะกับ alerting (แจ้งเตือนเมื่อเกินเกณฑ์) และ trending (ดู pattern ระยะยาว) Metrics แบ่งเป็น 3 ระดับ:
System Metrics
System metrics วัดสุขภาพของ infrastructure — CPU, Memory, Disk, Network ทุก server ต้องมี เป็นตัวบอกว่า "เครื่องจะล่มเมื่อไร":
- CPU Usage — เครื่องทำงานหนักแค่ไหน
- Memory Usage — RAM เหลือเท่าไหร่
- Disk I/O — อ่าน/เขียน disk เร็วแค่ไหน
- Network I/O — bandwidth ใช้ไปเท่าไหร่
Application Metrics (RED Method)
RED Method (Rate, Errors, Duration) คือ metrics ที่วัดจากมุมผู้ใช้ — request มาเท่าไร? error กี่ %? ตอบช้าแค่ไหน? สำคัญกว่า system metrics เพราะบอกได้ว่า "user experience ดีไหม":
- Rate — จำนวน request/sec
- Errors — เปอร์เซ็นต์ error (5xx)
- Duration — response time (p50, p95, p99)
Business Metrics
Business metrics เชื่อม technical data กับ business impact — ยอดสั่งซื้อต่อนาที, signup rate, cart abandonment rate ช่วยตอบคำถามเช่น "ระบบช้าขึ้น 200ms ส่งผลกระทบต่อยอดขายไหม?":
- Active Users — คนใช้งานอยู่กี่คน
- Orders/min — คำสั่งซื้อต่อนาที
- Revenue — รายได้ real-time
💡 RED Method: ใช้กับ services (Rate, Errors, Duration)
USE Method: ใช้กับ resources (Utilization, Saturation, Errors)
Prometheus + Grafana — Metrics Stack ยอดนิยม
Prometheus เป็น metrics database (TSDB) ที่เก็บข้อมูลแบบ time-series — ใช้ "pull model" คือ Prometheus ดึงข้อมูลจาก targets (servers, apps) ทุก 15 วินาที ส่วน Grafana เป็น dashboard tool ที่แสดง metrics เป็นกราฟสวยๆ ทั้งคู่เป็น open-source, CNCF graduated projects, และเป็น industry standard:
ตั้งค่า Prometheus
ไฟล์ prometheus.yml:
global:
scrape_interval: 15s # ดึง metrics ทุก 15 วินาที
scrape_configs:
# Monitor ตัว Prometheus เอง
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# Monitor Node (เครื่อง server)
- job_name: 'node'
static_configs:
- targets:
- 'server1:9100'
- 'server2:9100'
- 'server3:9100'
# Monitor App
- job_name: 'myapp'
metrics_path: '/metrics'
static_configs:
- targets: ['app:3000']
Docker Compose สำหรับ Monitoring Stack
Setup monitoring stack ได้ง่ายด้วย Docker Compose — Prometheus + Grafana + Node Exporter (system metrics) + cAdvisor (container metrics) พร้อมใช้งานในไม่กี่นาที:
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
grafana:
image: grafana/grafana:latest
ports:
- "3001:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=secret
volumes:
- grafana_data:/var/lib/grafana
node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
volumes:
prometheus_data:
grafana_data:
# รัน monitoring stack
docker compose up -d
# เข้า Prometheus: http://localhost:9090
# เข้า Grafana: http://localhost:3001 (admin/secret)
PromQL — Query ข้อมูลจาก Prometheus
PromQL คือ query language ของ Prometheus — ใช้คำนวณ metrics ที่ต้องการ เช่น error rate ใน 5 นาที, 95th percentile latency, CPU usage เฉลี่ย เรียนรู้ PromQL เป็นทักษะสำคัญสำหรับ DevOps:
# CPU usage เฉลี่ย 5 นาที
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Request rate ต่อวินาที
rate(http_requests_total[5m])
# Error rate (%)
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100
# 95th percentile response time
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
# Memory usage (%)
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
Pillar 2: Logs — บันทึกเหตุการณ์
Logs คือบันทึกเหตุการณ์ที่เกิดขึ้นในระบบ — "user X login สำเร็จ", "payment failed: insufficient funds", "database connection timeout" Metrics บอกว่า "มีปัญหา" แต่ Logs บอกว่า "เกิดอะไรขึ้นจริงๆ" สำคัญมากตอน debug
Structured Logging — ดีกว่า plain text!
แทนที่จะ log แบบ plain text ("User john logged in") ให้ใช้ structured logging (JSON format) — ทำให้ search, filter, aggregate ได้ง่าย ถามว่า "error ทั้งหมดของ user X ใน 1 ชั่วโมงที่แล้ว" ตอบได้ทันที:
// ❌ Bad — ยากต่อการ parse
console.log("User login failed for user123");
// ✅ Good — structured JSON
logger.error({
event: "login_failed",
userId: "user123",
reason: "invalid_password",
ip: "203.0.113.50",
timestamp: "2026-03-07T09:00:00Z"
});
Log Levels
Log levels ช่วยแยกความสำคัญ — production ควร log แค่ INFO ขึ้นไป (ไม่ต้อง DEBUG เพราะ volume สูงมาก) เมื่อมีปัญหาค่อยเปิด DEBUG ชั่วคราว:
| Level | ใช้เมื่อ | ตัวอย่าง |
|---|---|---|
| ERROR | เกิดข้อผิดพลาดจริง | Database connection failed |
| WARN | อาจมีปัญหาในอนาคต | Disk usage > 80% |
| INFO | เหตุการณ์ปกติที่สำคัญ | Server started on port 3000 |
DEBUG |
รายละเอียดสำหรับ debug | Query result: 42 rows |
ELK Stack — Centralized Logging
เมื่อมีหลาย servers/containers การ SSH เข้าไปดู log ทีละเครื่องไม่ work — ต้องมี centralized logging ที่รวม logs ทั้งหมดมาที่เดียว ELK Stack (Elasticsearch + Logstash + Kibana) เป็น solution ยอดนิยม:
ทางเลือกที่เบากว่า: Loki + Promtail + Grafana (ใช้ Grafana เดิมได้เลย!)
# Loki + Promtail Docker Compose
services:
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
promtail:
image: grafana/promtail:latest
volumes:
- /var/log:/var/log:ro
- ./promtail.yml:/etc/promtail/config.yml
Pillar 3: Traces — ติดตาม Request
เมื่อ 1 request ต้องผ่านหลาย services (microservices) เราจะรู้ได้ยังไงว่า ช้าตรงไหน?
Trace ช่วยให้เห็นว่า Payment Service ใช้เวลา 850ms — นั่นคือ bottleneck!
เครื่องมือ Tracing
เครื่องมือ tracing หลักๆ — Jaeger (CNCF, open-source, ใช้กับ Kubernetes ดี), Zipkin (โดย Twitter, lightweight), OpenTelemetry (มาตรฐานใหม่ที่รวม metrics+logs+traces เป็น vendor-neutral SDK):
- Jaeger — open-source, จาก Uber
- Zipkin — open-source, จาก Twitter
- OpenTelemetry — standard ใหม่ (รวม metrics + logs + traces)
- Datadog APM / New Relic — commercial (ง่ายแต่แพง)
// OpenTelemetry ตัวอย่าง (Node.js)
const { trace } = require('@opentelemetry/api');
const tracer = trace.getTracer('my-service');
app.get('/api/checkout', async (req, res) => {
const span = tracer.startSpan('checkout');
try {
// แต่ละขั้นตอนมี child span
const userSpan = tracer.startSpan('get-user', { parent: span });
const user = await getUser(req.userId);
userSpan.end();
const paySpan = tracer.startSpan('process-payment', { parent: span });
await processPayment(user, req.amount);
paySpan.end();
res.json({ status: 'success' });
} catch (err) {
span.setStatus({ code: 2, message: err.message });
res.status(500).json({ error: err.message });
} finally {
span.end();
}
});
Alerting — แจ้งเตือนก่อนพัง
Dashboard สวยแค่ไหนก็ไม่ช่วย ถ้าไม่มีใครดู — ต้องมี Alert!
Alert Rules (Prometheus)
Alert rules กำหนดว่า "เมื่อ condition X เป็นจริงนาน Y นาที → แจ้งเตือน" สิ่งสำคัญคือ for duration ป้องกัน false alarms จาก spikes ชั่วคราว และ labels/annotations ช่วยให้ on-call team เข้าใจปัญหาเร็ว:
# alert-rules.yml
groups:
- name: critical
rules:
# Server down
- alert: InstanceDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "{{ $labels.instance }} is down!"
# CPU สูงเกิน 90% นาน 5 นาที
- alert: HighCPU
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
for: 5m
labels:
severity: warning
annotations:
summary: "CPU > 90% on {{ $labels.instance }}"
# Error rate สูงเกิน 5%
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100 > 5
for: 2m
labels:
severity: critical
annotations:
summary: "Error rate > 5% on {{ $labels.job }}"
# Disk เหลือน้อยกว่า 10%
- alert: DiskSpaceLow
expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100 < 10
for: 5m
labels:
severity: warning
annotations:
summary: "Disk < 10% on {{ $labels.instance }}"
Alert ส่งไปไหน? (Alertmanager)
Alertmanager รับ alerts จาก Prometheus แล้วส่งต่อไปยัง channels ที่เหมาะสม — Slack, PagerDuty, email, webhook รองรับ grouping (รวม alerts เดียวกัน), silencing (ปิดเสียงชั่วคราว), และ routing (critical → PagerDuty, warning → Slack):
# alertmanager.yml
route:
receiver: 'team-slack'
routes:
- match:
severity: critical
receiver: 'pagerduty' # Critical → ปลุกคนมาแก้!
- match:
severity: warning
receiver: 'team-slack' # Warning → แจ้งใน Slack
receivers:
- name: 'team-slack'
slack_configs:
- api_url: 'https://hooks.slack.com/services/xxx'
channel: '#alerts'
title: '🚨 {{ .GroupLabels.alertname }}'
text: '{{ .CommonAnnotations.summary }}'
- name: 'pagerduty'
pagerduty_configs:
- service_key: 'your-pagerduty-key'
🐕 Alert Fatigue: อย่าตั้ง alert ทุกอย่าง! ถ้าแจ้งเตือนเยอะเกิน คนจะเพิกเฉย → Critical = ต้อง action ทันที | Warning = ดูภายในวัน | Info = ดูเมื่อว่าง
Monitoring Stack ยอดนิยม
มี monitoring tools มากมาย — ตารางด้านล่างเปรียบเทียบ stack ยอดนิยมทั้ง open-source และ commercial ช่วยเลือกตามความต้องการ (budget, scale, complexity):
| Stack | ส่วนประกอบ | จุดเด่น |
|---|---|---|
| PLG | Prometheus + Loki + Grafana | Open-source, K8s friendly, ครบ 3 pillars |
| ELK | Elasticsearch + Logstash + Kibana | Log search ดีมาก, enterprise |
| TIG | Telegraf + InfluxDB + Grafana | IoT/time-series ดี |
| Datadog | All-in-one SaaS | ง่ายสุด แต่แพง |
| New Relic | All-in-one SaaS | APM ดี, free tier |
4 Golden Signals (Google SRE)
4 Golden Signals จาก Google SRE Book — ถ้า monitor ได้แค่ 4 อย่าง ให้เลือก 4 ตัวนี้ ครอบคลุม user experience ทั้งหมด Latency บอกประสบการณ์, Traffic บอก demand, Errors บอกคุณภาพ, Saturation บอกขีดจำกัด:
- Latency — ใช้เวลาตอบนานแค่ไหน? (p50, p95, p99)
- Traffic — มี request เข้ามากี่ครั้ง/วินาที?
- Errors — กี่ % ที่ error? (HTTP 5xx)
- Saturation — ระบบเต็มแค่ไหน? (CPU, memory, disk, queue)
💡 SLO Tip: กำหนด SLO (Service Level Objective) เช่น "99.9% uptime" หรือ "p95 latency < 200ms" แล้ว monitor ว่าทำได้จริงมั้ย — อันนี้คือ SLI (Service Level Indicator)
สรุป
Monitoring & Observability เป็นสิ่งที่ต้องมี ไม่ใช่ "มีก็ดี" — ถ้าไม่มี ก็เหมือนขับรถโดยไม่มี dashboard ไม่รู้ว่าน้ำมันจะหมดเมื่อไร เครื่องยนต์ร้อนแค่ไหน เริ่มจาก metrics + alerting ก่อน (Prometheus + Grafana) แล้วเพิ่ม logs และ traces เมื่อระบบซับซ้อนขึ้น:
- Monitoring = "มีปัญหามั้ย?" | Observability = "ทำไมถึงมีปัญหา?"
- 3 Pillars = Metrics (ตัวเลข) + Logs (บันทึก) + Traces (ติดตาม request)
- Prometheus + Grafana = metrics stack ยอดนิยม ใช้ PromQL query
- Loki / ELK = centralized logging — รวม log จากทุก server มาที่เดียว
- Jaeger / OpenTelemetry = distributed tracing หา bottleneck ใน microservices
- Alerting = แจ้งเตือนผ่าน Slack/PagerDuty — ระวัง alert fatigue!
- 4 Golden Signals = Latency, Traffic, Errors, Saturation 📊🐕