Observability vs Monitoring: ความต่างของ Metrics, Logs, Traces

คำว่า Monitoring และ Observability มักถูกใช้สลับกันในหลายทีม แต่ในทางปฏิบัติแล้วสองแนวคิดนี้ไม่ใช่สิ่งเดียวกัน Monitoring เน้นตอบคำถามที่ถูกคาดเดาไว้ล่วงหน้า เช่น “CPU เกิน 80% ไหม” หรือ “API latency เกิน 500ms หรือเปล่า” ในขณะที่ Observability มุ่งให้เราสามารถตั้งคำถามใหม่ที่ไม่เคยคิดไว้และหาคำตอบจากข้อมูลที่ระบบสร้างขึ้น

บทความนี้จะช่วยคลี่คลายความแตกต่างระหว่างสองแนวคิด ทำความเข้าใจ “สามเสาหลัก” ของ Observability คือ Metrics, Logs และ Traces รวมถึงแนวทางการเลือกใช้เครื่องมือ และวิธีวางโครงสร้าง telemetry pipeline ให้ทีมสามารถ debug ปัญหาที่ซับซ้อนใน distributed system ได้

Monitoring คืออะไร

Monitoring คือการเฝ้าระวังระบบโดยการเก็บตัวชี้วัดที่ถูกกำหนดล่วงหน้า แล้วเปรียบเทียบกับ threshold หรือ baseline เพื่อแจ้งเตือนเมื่อมีความผิดปกติ สิ่งที่ Monitoring ทำได้ดีคือ: (1) บอกว่า “มีปัญหาเกิดขึ้นหรือไม่” (2) ให้ภาพรวมสุขภาพของระบบในระดับ dashboard (3) กระตุ้น alert เมื่อ SLI ถูกละเมิด

ข้อจำกัดของ Monitoring อยู่ที่ “ถ้าเราไม่ได้ตั้งใจเก็บข้อมูลไว้ล่วงหน้า เราจะไม่มีคำตอบ” เช่น ถ้า alert บอกว่า p99 latency พุ่ง แต่ไม่รู้ว่า endpoint ไหนเป็นต้นเหตุ, user กลุ่มไหนได้รับผลกระทบ, หรือเกิดจาก downstream service ตัวใด — ข้อมูลเหล่านั้นต้องถูกวาง label หรือ tag ไว้ก่อนเกิดปัญหา ถ้าไม่ได้วาง จะ “ตาบอด” ทันที

Observability คืออะไร

คำว่า Observability ถูกหยิบยืมมาจากทฤษฎี Control Theory โดยนิยามว่า “ความสามารถในการอนุมานสถานะภายในของระบบจากข้อมูลที่ระบบส่งออกมา” สำหรับวงการซอฟต์แวร์ หมายถึง ระบบที่สามารถให้คำตอบของคำถามใหม่ ๆ โดยไม่ต้อง deploy code ใหม่ก่อน

ในทางปฏิบัติ Observability ประกอบด้วยข้อมูล 3 ประเภทหลัก (three pillars) — Metrics, Logs และ Traces — ซึ่งแต่ละประเภทตอบคำถามต่างกัน เมื่อใช้ร่วมกันจะทำให้เกิดความสามารถในการ “debug ระบบที่ไม่เคยเห็นมาก่อน” ได้อย่างมีประสิทธิภาพ

ความแตกต่างที่แท้จริงของทั้งสอง

มิติMonitoringObservability
คำถามที่ตอบ“มีปัญหาหรือไม่”“ทำไมถึงเกิดปัญหา”
ข้อมูลที่เก็บKnown metrics (กำหนดไว้ล่วงหน้า)High-cardinality events, traces, logs
วิธีใช้Dashboard + AlertQuery + Exploration
จุดอ่อนไม่ตอบคำถามใหม่เก็บข้อมูลเยอะ ต้นทุนสูง
ใช้เมื่อDetect ปัญหาDebug ปัญหา

ในระบบจริง ทั้งสองแนวคิดควรทำงานร่วมกัน Monitoring เป็นด่านแรกที่ตรวจจับและแจ้งเตือน ส่วน Observability เข้ามาเสริมเมื่อวิศวกรต้อง drill-down หาสาเหตุ ข้อผิดพลาดที่พบบ่อยคือ ทีมพยายาม “ใช้ Monitoring แทน Observability” โดยเพิ่ม label จนระบบ time-series ล่ม หรือกลับกันคือ “ใช้ Logs เป็น Metric” ซึ่งแพงและช้าในการ query

Pillar #1 — Metrics

Metrics คือตัวเลขที่ถูกเก็บเป็น time series มีคุณสมบัติที่สำคัญคือ: ขนาดเล็ก, aggregate ได้, ค้นหาเร็ว เหมาะกับการตอบคำถามภาพรวมระดับระบบ เช่น “มี request กี่ตัวต่อวินาที”, “ใน 1 ชม.ที่ผ่านมามี error ทั้งหมดเท่าไร”

จุดแข็งของ Metrics คือ storage และ query ประสิทธิภาพสูง Prometheus สามารถเก็บ time series นับสิบล้านและ query ย้อน 15 วันได้ในระดับวินาที แต่จุดอ่อนคือ cardinality — ถ้าใส่ label ที่มีค่าแปรผันสูง (เช่น user_id) จำนวน time series จะระเบิด และทำให้ระบบล่มได้ Metrics จึงเหมาะกับข้อมูลที่ enumerate ได้เท่านั้น

  • Counter: ตัวเลขที่เพิ่มเท่านั้น เช่น request count, error count
  • Gauge: ค่าที่ขึ้นและลงได้ เช่น memory usage, in-flight requests
  • Histogram: การกระจายตัวของค่า เช่น request duration buckets
  • Summary: percentile ที่คำนวณฝั่ง client

Pillar #2 — Logs

Logs คือเหตุการณ์ที่ถูกบันทึกพร้อม timestamp และข้อความอธิบาย (อาจเป็น plain text หรือ structured JSON) จุดแข็งคือ รายละเอียดสูง สามารถบรรจุข้อมูล context เยอะได้ เช่น stacktrace, request body, user email

Best practice สมัยใหม่คือใช้ structured logging (JSON หรือ key-value) แทน plain text เพราะจะถูก index ได้แม่นยำกว่าและ query ได้เร็วกว่า เครื่องมือที่นิยมคือ Loki, Elasticsearch, ClickHouse ตัวอย่าง JSON log ที่ดี:

{
  "timestamp": "2026-04-18T03:14:15.123Z",
  "level": "error",
  "service": "checkout",
  "trace_id": "abc123",
  "span_id": "def456",
  "user_id": "u_98765",
  "message": "payment gateway timeout",
  "payment_method": "credit_card",
  "duration_ms": 5012
}

ข้อแนะนำสำคัญคือ ให้ log ทุก event ที่สำคัญพร้อม trace_id และ span_id เพื่อให้สามารถเชื่อมโยงกับ Traces ได้ในภายหลัง การ log มากเกินไปหรือน้อยเกินไปล้วนมีต้นทุน — log มากทำให้ storage แพง, log น้อยทำให้ debug ไม่ได้ ทีมควรตั้งระดับ log (DEBUG, INFO, WARN, ERROR) ให้เหมาะกับสภาพแวดล้อม

Pillar #3 — Traces

Distributed Tracing คือการติดตาม request หนึ่งตัวที่วิ่งผ่านหลาย service เพื่อดูว่าแต่ละ service ใช้เวลาเท่าไร เชื่อมต่อกันอย่างไร และเกิดปัญหาที่จุดใด ต่างจาก Metrics ที่ aggregate ข้อมูล Traces เก็บรายละเอียดระดับ request เดี่ยว ๆ ทำให้เหมาะกับการ debug ปัญหา latency ใน microservices

โครงสร้างของ Trace ประกอบด้วย “span” หลายตัว โดย span คือช่วงเวลาของงานหนึ่งชิ้น (เช่น HTTP call, DB query) แต่ละ span มี parent span ทำให้เรียงต่อกันเป็น tree สุดท้ายจะเห็นเป็น “flame graph” ที่แสดงว่าเวลาถูกใช้ไปกับส่วนไหนของ request

เครื่องมือที่นิยมคือ Jaeger, Tempo, Zipkin ซึ่งรับ data ในรูปแบบ OpenTelemetry (มาตรฐานกลาง) การ instrument ระบบให้ส่ง trace มักใช้ OpenTelemetry SDK — ในหลายภาษา (Python, Go, Node.js, Java) สามารถเปิด auto-instrumentation ได้ทันทีโดยไม่ต้องแก้โค้ดมาก

High-Cardinality Events — เสาที่สี่ที่ถูกพูดถึง

ระยะหลังมีแนวคิด “wide events” หรือ “high-cardinality events” ที่เสนอว่า pillar ทั้ง 3 ควรถูกรวมเป็น “event หนึ่ง” ที่มี attribute เยอะ ๆ เช่น request หนึ่งครั้งบันทึกเป็น 1 event ที่มี field 50-100 ตัว ครอบคลุมทั้ง duration, user_id, feature_flag_state, request_shape

เครื่องมือประเภทนี้เช่น Honeycomb, Axiom, OpenObserve เน้นการ query แบบ ad-hoc บน event data โดยสามารถ group by label ใด ๆ ก็ได้ ซึ่งต่างจาก Prometheus ที่ต้องกำหนด label ไว้ก่อน — แลกกับค่า ingestion และ storage ที่แพงกว่า

การเชื่อมโยง 3 Pillars เข้าด้วยกัน

พลังจริงของ Observability เกิดเมื่อ 3 pillars ถูกเชื่อมโยงกันด้วย correlation ID — ตัวอย่างเช่น เมื่อ alert ยิงว่า p99 latency พุ่ง วิศวกรสามารถ:

  1. ดู Metric เพื่อยืนยันว่า latency พุ่งจริง และระบุช่วงเวลา
  2. Query Traces ในช่วงเวลานั้นที่มี duration สูงผิดปกติ เพื่อหา slow request ตัวอย่าง
  3. เปิด Trace หนึ่งตัวดู span breakdown ว่าเวลาหายไปใน service ไหน
  4. Copy trace_id ไป query Logs ใน service ที่ต้องสงสัยเพื่อดู context
  5. หา root cause แล้วกลับไปตั้ง metric หรือ alert ใหม่เพื่อ detect ปัญหาในอนาคต

การเชื่อมโยงแบบนี้ต้องอาศัย trace_id propagation ให้ถูกต้องตั้งแต่ edge ของระบบ (เช่น HTTP ingress) ผ่านทุก service จนถึง database layer — ใช้ OpenTelemetry Context Propagation และตั้งค่าให้ log format มีฟิลด์ trace_id เสมอ

OpenTelemetry — มาตรฐานเปิดที่กลายเป็น default

OpenTelemetry (OTel) เป็นโปรเจกต์ในกลุ่ม CNCF ที่รวม OpenTracing + OpenCensus เข้าด้วยกัน ปัจจุบันเป็นมาตรฐาน vendor-neutral สำหรับ telemetry ทั้ง 3 pillars มี SDK รองรับ 10+ ภาษา และ backend รองรับหลายร้อยตัว

ข้อดีของการใช้ OTel คือการที่ “instrument ครั้งเดียว ใช้ได้กับทุก backend” — ถ้าวันนี้ใช้ Jaeger สำหรับ trace พรุ่งนี้อยากเปลี่ยนเป็น Tempo ก็ไม่ต้องแก้โค้ด แค่เปลี่ยน OTel Collector config ทีมที่เริ่มใหม่ในวันนี้แนะนำให้เริ่มจาก OTel ทันที แทนที่จะเลือก vendor-specific SDK

ตัวอย่าง instrument Python ด้วย OTel

from opentelemetry import trace, metrics
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace.export import BatchSpanProcessor

# Setup tracing
provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(provider)

tracer = trace.get_tracer(__name__)
meter = metrics.get_meter(__name__)

request_counter = meter.create_counter(
    name="http_requests_total",
    description="Total HTTP requests"
)

@app.route("/checkout")
def checkout():
    with tracer.start_as_current_span("checkout") as span:
        span.set_attribute("user.id", user_id)
        request_counter.add(1, {"endpoint": "/checkout"})
        result = process_payment()
        return result

Telemetry Pipeline — สถาปัตยกรรมที่ควรรู้

Telemetry Pipeline มาตรฐานประกอบด้วย 3 ชั้นคือ

  • Instrumentation: ในแต่ละ service ใช้ SDK (OTel, Prometheus client) สร้าง metrics/logs/traces
  • Collector / Agent: ตัวกลางที่รับ data จากทุก service แล้ว process + forward เช่น OTel Collector, Fluent Bit, Vector
  • Backend: ระบบเก็บและ query เช่น Prometheus + Loki + Tempo + Grafana stack หรือ SaaS อย่าง Datadog, Honeycomb

การมีชั้น Collector คั่นกลางช่วยให้สามารถ: (1) sample data เพื่อลดต้นทุน (2) redact ข้อมูลที่ sensitive ก่อนส่งออก (3) เปลี่ยน backend ได้โดยไม่แตะ application code การใช้ OTel Collector ในบทบาทนี้เป็นแนวทางที่ scale ได้ดีในระบบใหญ่

เมื่อไรควรลงทุนใน Observability

ไม่ใช่ทุกระบบต้องการ Observability เต็มรูปแบบ หากคุณมี monolith เดียวที่รัน 2-3 instance และ SLO ไม่เข้มงวด Monitoring ปกติก็เพียงพอ แต่ถ้าระบบของคุณมี microservices 20+ ตัว, request หนึ่งครั้งต้องผ่าน 5-10 hop, หรือปัญหาในการ debug ใช้เวลาเกิน 1 ชั่วโมงต่อเหตุการณ์ นั่นคือสัญญาณว่าควรลงทุนใน Observability

ROI ของ Observability มาจาก 3 ทาง: (1) ลด Mean Time To Repair (MTTR) เพราะหา root cause ได้เร็ว (2) ลด blast radius ของ incident เพราะเห็นภาพรวม dependency (3) เพิ่มความมั่นใจในการ deploy เพราะ canary release สามารถ verified ได้จาก trace-level data ไม่ใช่แค่ error rate

Common Anti-patterns

  • ใช้ Metrics แทน Logs: เก็บทุก event เป็น Counter ด้วย label คอลัมน์ละเอียด → cardinality explosion
  • ใช้ Logs แทน Metrics: query aggregated metric จาก log ทุกครั้ง → ช้าและแพง
  • Trace ทุก request 100%: ต้นทุน storage สูงมาก — ใช้ tail sampling หรือ head sampling ตามลักษณะระบบ
  • ไม่ propagate trace_id ระหว่าง service: แยก trace ขาดกลาง debug ไม่ได้
  • ไม่มี correlation ID ใน log: log เยอะแต่ไม่เชื่อมกับ trace หรือ metric
  • ลงทุน Observability ก่อนมี Monitoring ที่ดี: ยังตอบไม่ได้ว่ามีปัญหาหรือไม่ แล้วจะ debug อะไร

กรณีศึกษา: Debug Latency ด้วย 3 Pillars

สมมติว่าทีมได้รับ alert ว่า checkout p99 latency พุ่งจาก 800ms เป็น 4s เวลา 14:30 น. วิศวกรเริ่มจาก metric เพื่อยืนยันช่วงเวลา พบว่า error rate ยังปกติ แต่ latency สูงเฉพาะ route /cart/submit จึง query trace ใน Jaeger ในช่วงเวลานั้น filter duration > 3s และเลือก trace หนึ่งตัว

Trace แสดงว่า span inventory-service:reserve ใช้เวลา 3.5s จากทั้งหมด 4s วิศวกร copy trace_id ไป query Loki ในช่วง service นั้น พบ log “database connection pool exhausted, waiting 3200ms” ซึ่งชี้ไปที่ connection leak หลังการ deploy ครั้งล่าสุด — กระบวนการทั้งหมดใช้เวลา 10 นาที แทนที่จะต้องไล่ดู dashboard ทีละตัวเป็นชั่วโมง

สรุป

Monitoring และ Observability เป็นสองแนวคิดที่เสริมกัน ไม่ใช่แทนกัน Monitoring ตอบ “มีปัญหาหรือไม่” ผ่าน dashboard และ alert ในขณะที่ Observability ตอบ “ทำไมถึงเกิดปัญหา” ผ่านการ query และ exploration บนข้อมูลที่ละเอียด ระบบที่ดีควรมีทั้งสอง โดยใช้ Metrics เป็นด่านแรกสำหรับ detect, Logs และ Traces สำหรับ investigate

การเริ่มต้นควรลงทุนใน OpenTelemetry เป็นมาตรฐานกลาง ให้ทุก service ส่งข้อมูลในรูปแบบเดียวกัน แล้วใช้ collector layer เพื่อความยืดหยุ่นในการเปลี่ยน backend สุดท้ายอย่าลืมว่า pillars ทั้งสามต้องถูกเชื่อมโยงด้วย correlation ID — มิเช่นนั้นก็เป็นเพียง silo ของข้อมูลที่แยกกันอยู่