Observability 1 — Metrics, Logs, Traces & Golden Signals

13 thg 7, 2026 2 lượt xem
#observability
#metrics
#monitoring
#devops
#sre

Từ "hệ thống có chạy không" đến "vì sao nó chậm"

Ở một team dữ liệu ngân hàng như NCB, một giao dịch chuyển khoản không đi qua một chỗ. Nó xuất phát từ app mobile → API gateway → service xác thực → core banking → hàng đợi message → pipeline ghi nhận vào data warehouse → job đối soát cuối ngày. Khi khách hàng phàn nàn "app quay mãi không xong", câu hỏi không còn là hệ thống có sống không — mọi service đều "sống" — mà là nghẽn ở đâu, vì sao, ai bị ảnh hưởng.

Đây là ranh giới giữa hai tư duy thường bị dùng lẫn: monitoringobservability. Series này đi sâu vào cách xây dựng năng lực quan sát hệ thống bằng bộ công cụ Prometheus + Grafana, nhưng trước khi chạm vào công cụ, bài đầu tiên xây nền khái niệm: ba trụ cột dữ liệu, cách chọn tín hiệu đáng đo, và cách biến chúng thành mục tiêu chất lượng dịch vụ (SLO) — thứ quyết định khi nào máy nên đánh thức bạn lúc 2 giờ sáng.

Monitoring khác Observability như thế nào

Hai từ này khác nhau về bản chất câu hỏi chúng trả lời, không phải về công cụ.

Monitoring là theo dõi những thứ bạn đã biết trước là quan trọng: CPU, RAM, tỷ lệ HTTP 500, độ trễ trung bình. Bạn định nghĩa sẵn câu hỏi, dựng dashboard và alert để trả lời. Monitoring nói cho bạn biết: "Có gì đó đang sai." Nó xử lý known-unknowns — những trục trặc bạn đã lường trước (đĩa đầy, service chết, hàng đợi ùn).

Observability là khả năng suy luận trạng thái bên trong của hệ thống chỉ qua dữ liệu nó phát ra (telemetry), kể cả với câu hỏi bạn chưa từng nghĩ tới lúc thiết kế. Nó trả lời: "Vì sao đúng nhóm khách hàng ở chi nhánh miền Trung, dùng app phiên bản 4.2, trong khung 11h–12h lại timeout khi truy vấn số dư?" Bạn không thể dựng sẵn dashboard cho mọi tổ hợp như vậy. Observability xử lý unknown-unknowns.

Một câu tóm gọn của cộng đồng SRE: monitoring cho bạn biết hệ thống có vấn đề; observability cho bạn hiểu vì sao — mà không cần deploy lại code để thêm log. Monitoring là tập con của observability. Bạn không "chọn một trong hai": bạn dựng monitoring cho những gì đã biết, và đầu tư đủ độ giàu telemetry (chiều dữ liệu, label, trace) để điều tra những gì chưa biết.

Điểm mấu chốt: observability là thuộc tính của hệ thống, không phải một sản phẩm bạn mua. Một hệ khó quan sát dù có mua công cụ đắt tiền vẫn khó quan sát, nếu code không phát ra tín hiệu đủ giàu.

Ba trụ cột: Metrics, Logs, Traces

Observability được xây trên ba loại telemetry bổ trợ nhau. Không loại nào tự nó đủ.

Ba loại này tạo một quy trình điều tra tự nhiên: metric phát hiện có bất thường, trace khoanh vùng chậm/lỗi ở service nào, log giải thích chính xác chuyện gì xảy ra ở dòng đó.

Metrics — số theo thời gian

Metric là các giá trị số được đo và tổng hợp theo chuỗi thời gian (time series): số request/giây, độ trễ p99, phần trăm CPU, độ dài hàng đợi. Mỗi điểm dữ liệu rất nhỏ (một con số + timestamp + vài label), nên metric cực rẻ để lưu và truy vấn ngay cả ở tần suất cao, trong thời gian dài.

  • Mạnh: rẻ, tổng hợp tốt, lý tưởng cho dashboard xu hướng và cảnh báo. Trả lời câu hỏi "bao nhiêu / nhanh cỡ nào" trong thời gian thực.
  • Yếu: mất chi tiết. Metric nói "5% request lỗi" nhưng không nói request nào, của ai, vì sao. Bị giới hạn cardinality: nếu gắn label có quá nhiều giá trị (ví dụ user_id, transaction_id), số chuỗi thời gian bùng nổ và làm sập hệ đo.
  • Khi nào dùng: làm xương sống cho monitoring và alerting. Đây là nơi Prometheus tỏa sáng (xem obs-02-prometheus-arch).

Logs — sự kiện chi tiết

Log là bản ghi rời rạc của các sự kiện: một dòng text hoặc một object JSON có cấu trúc, kèm timestamp, mức độ (INFO/WARN/ERROR) và ngữ cảnh. "Đã ghi nhận giao dịch #A93 số tiền 5.000.000 từ tài khoản X, mất 320ms."

  • Mạnh: giàu ngữ cảnh nhất. Là nguồn chân lý khi cần biết chính xác điều gì xảy ra với một sự kiện cụ thể. Không ngại cardinality — bạn có thể log bất kỳ id nào.
  • Yếu: tốn lưu trữ nhất, khó tổng hợp thành xu hướng, và ở quy mô lớn thì tìm kiếm chậm/đắt nếu không đánh index tốt. Log không cấu trúc (text tự do) rất khó truy vấn.
  • Khi nào dùng: điều tra sâu sau khi metric/trace đã khoanh vùng. Log nên có cấu trúc (structured logging, thường JSON) để máy phân tích được. Ở NCB, log thường được nạp vào Elasticsearch để tìm kiếm và phân tích — xem es-05-indexing-ingest. Trong series này ta sẽ dùng Loki (nhẹ hơn, gắn với Grafana) ở obs-07-logs-traces.

Traces — dấu vết request qua nhiều service

Trace ghi lại hành trình của một request khi nó đi xuyên qua nhiều service. Mỗi chặng là một span (có tên, thời gian bắt đầu, thời lượng, và các thuộc tính); các span nối với nhau bằng một trace_id chung, tạo thành cây thể hiện quan hệ cha–con.

  • Mạnh: cho thấy độ trễ dồn ở đâu trong một chuỗi gọi phân tán. Trả lời "request này mất 3 giây, phần lớn thời gian nằm ở đâu?" — điều mà metric và log rời rạc không làm được.
  • Yếu: hạ tầng phức tạp (cần truyền trace_id xuyên service — context propagation), thường phải lấy mẫu (sampling) vì lưu 100% trace ở lưu lượng cao là quá đắt.
  • Khi nào dùng: hệ microservices/phân tán, khi cần hiểu tương tác giữa các service. Ta sẽ dùng Tempoobs-07-logs-traces.

Bảng so sánh nhanh:

Tiêu chíMetricsLogsTraces
Đơn vị dữ liệusố + label theo thời giansự kiện (dòng/JSON)span nối theo trace_id
Chi phí lưu trữrất thấpcaotrung bình–cao (thường sampling)
Cardinality cao✗ nguy hiểm✓ thoải mái✓ ổn
Dùng để cảnh báo★★★
Điều tra ngữ cảnh★★★★★ (định vị)
Câu hỏi trả lờibao nhiêu / nhanh cỡ nàochính xác chuyện gìchậm/lỗi ở đâu

Chọn tín hiệu nào để đo: 4 Golden Signals, RED, USE

Vấn đề không phải là đo được gì — bạn có thể đo hàng nghìn chỉ số. Vấn đề là đo cái gì cho đáng. Đo quá nhiều thì nhiễu (noise) che mất tín hiệu; đo sai thì mù đúng chỗ cần thấy. Ngành có ba khuôn mẫu (framework) đã được kiểm chứng để chọn tín hiệu.

4 Golden Signals (Google SRE)

Cuốn Site Reliability Engineering của Google đề xuất: nếu chỉ được đo bốn thứ cho một dịch vụ hướng người dùng, hãy đo:

  1. Latency (độ trễ): thời gian phục vụ một request. Bắt buộc tách riêng độ trễ của request thành công và request lỗi — một lỗi trả về nhanh có thể làm đẹp giả tạo con số trung bình. Luôn nhìn phân vị (p50, p95, p99), đừng chỉ nhìn trung bình.
  2. Traffic (lưu lượng): mức nhu cầu lên hệ thống — request/giây, giao dịch/phút, số kết nối đồng thời.
  3. Errors (lỗi): tỷ lệ request thất bại — cả lỗi rõ ràng (HTTP 500) lẫn lỗi ngầm (trả 200 nhưng nội dung sai) và lỗi theo chính sách (quá chậm so với SLA cũng tính là lỗi).
  4. Saturation (mức bão hòa): hệ thống "đầy" tới đâu — tài nguyên bị ép nhất còn bao nhiêu dư địa (RAM, IO đĩa, độ dài hàng đợi). Saturation thường là chỉ báo sớm của sự cố sắp tới.

RED — cho service

RED (Tom Wilkie) là phiên bản gọn cho từng dịch vụ, đặc biệt hợp với microservices và Prometheus:

  • Rate — số request/giây.
  • Errors — số request lỗi/giây (hoặc tỷ lệ lỗi).
  • Duration — phân bố thời gian xử lý request.

RED chính là ba trong bốn golden signal, nhìn từ góc "một service đang phục vụ request". Rất dễ chuẩn hóa: mọi service đo cùng ba chỉ số này thì dashboard và alert đồng nhất toàn hệ thống.

USE — cho tài nguyên

USE (Brendan Gregg) hướng vào tài nguyên hạ tầng (CPU, đĩa, network, pool kết nối), bổ khuyết cho RED:

  • Utilization — % thời gian tài nguyên bận.
  • Saturation — mức công việc bị xếp hàng chờ vì tài nguyên không kịp (độ dài queue).
  • Errors — số lỗi của tài nguyên (đĩa lỗi đọc, gói tin rớt).

Cách phối hợp thực tế: dùng RED để nhìn từ góc dịch vụ (trải nghiệm người dùng), dùng USE để nhìn từ góc tài nguyên (nguyên nhân hạ tầng). Khi RED báo Duration tăng, USE thường chỉ ra tài nguyên nào đang bão hòa gây ra điều đó.

FrameworkĐối tượngChỉ sốCâu hỏi chính
Golden Signalsdịch vụ người dùngLatency, Traffic, Errors, SaturationNgười dùng có đang khổ không?
REDmỗi microserviceRate, Errors, DurationService này phục vụ tốt không?
USEmỗi tài nguyênUtilization, Saturation, ErrorsTài nguyên nào sắp cạn?

SLI, SLO, SLA & Error Budget — nền cho cảnh báo có ý nghĩa

Đo được tín hiệu mới là một nửa. Nửa còn lại là biến tín hiệu thành mục tiêu để biết khi nào cần lo lắng. Đây là chuỗi khái niệm cốt lõi của SRE.

  • SLI (Service Level Indicator)thước đo định lượng chất lượng dịch vụ, tính từ metric. Ví dụ: "tỷ lệ request truy vấn số dư trả về < 300ms và mã 2xx". SLI là một con số, thường biểu diễn dạng phần trăm request "tốt" trên tổng.
  • SLO (Service Level Objective)mục tiêu nội bộ cho SLI trong một cửa sổ thời gian. Ví dụ: "99,9% request truy vấn số dư đạt SLI trên, tính trong 30 ngày trượt". SLO là lời hứa của team với chính mình.
  • SLA (Service Level Agreement)cam kết hợp đồng với bên ngoài (khách hàng, đối tác), kèm hậu quả nếu vi phạm (bồi thường, phạt). SLA luôn lỏng hơn SLO: nếu SLA hứa 99,9% thì SLO nội bộ nên đặt cao hơn (ví dụ 99,95%) để có biên an toàn phát hiện sớm trước khi vi phạm cam kết.

Error budget (ngân sách lỗi) là hệ quả trực tiếp và mạnh mẽ nhất của SLO. Nếu SLO là 99,9% trong 30 ngày, thì bạn được phép "lỗi" 0,1% — đó chính là ngân sách. Với ~43.200 phút mỗi 30 ngày, 0,1% tương đương khoảng 43 phút downtime/tháng cho phép.

Error budget biến độ tin cậy từ khẩu hiệu mơ hồ ("phải luôn ổn định") thành con số có thể quản trị:

  • Còn nhiều budget → team được phép mạo hiểm: deploy nhanh, thử tính năng mới.
  • Cạn budget → đóng băng thay đổi rủi ro, dồn lực vào ổn định. Đây là công cụ trọng tài khách quan giữa team phát triển (muốn ship nhanh) và team vận hành (muốn ổn định).

Và đây là chìa khóa cho cảnh báo (alerting) tử tế: thay vì bắn alert mỗi khi một lỗi lẻ xuất hiện (gây mệt mỏi, "alert fatigue"), ta cảnh báo dựa trên tốc độ tiêu hao error budget (burn rate). Nếu budget đang cháy nhanh gấp 14 lần bình thường, nghĩa là sẽ hết sạch trong vài giờ → đánh thức người trực. Nếu chỉ hơi tăng → tạo ticket xử lý trong giờ hành chính. Bài obs-06-alerting đi sâu phần này.

Vì sao dashboard đẹp chưa đủ

Một cạm bẫy phổ biến: team dựng một dashboard Grafana rực rỡ 40 biểu đồ, rồi tự tin là "đã có observability". Nhưng dashboard đẹp có ba giới hạn:

  1. Không ai nhìn màn hình 24/7. Dashboard chỉ hữu ích khi có người đang nhìn. Sự cố lúc 3h sáng cần alert chủ động đẩy tới người trực, không phải một biểu đồ chờ ai đó tình cờ mở ra.
  2. 40 biểu đồ = không biểu đồ nào. Quá nhiều panel làm loãng sự chú ý. Dashboard tốt bám theo golden signals / RED, ưu tiên vài chỉ số thực sự phản ánh trải nghiệm người dùng.
  3. Dashboard trả lời câu hỏi đã biết. Nó là monitoring. Khi gặp unknown-unknown, bạn cần khả năng khoan sâu tùy biến (truy vấn PromQL mới, lọc log theo trace_id, mở trace) — tức năng lực observability thật sự, không phải panel dựng sẵn.

Kết luận: dashboard + alert dựa trên SLO + khả năng điều tra ad-hoc, cả ba đi cùng nhau mới thành observability. Dashboard mà không có alert đúng thì chỉ là trang trí.

Stack chúng ta sẽ đi sâu

Series này dựng một stack observability mã nguồn mở, phổ biến và chạy tốt cả on-premise (quan trọng với ngân hàng vì lý do tuân thủ, dữ liệu nhạy cảm không ra ngoài):

  • Prometheus — thu thập và lưu trữ metrics theo mô hình pull, với ngôn ngữ truy vấn PromQL mạnh. Đây là trái tim của monitoring. Kiến trúc: obs-02-prometheus-arch; PromQL: obs-03-promql; cách gắn đo vào ứng dụng (instrumentation): obs-04-instrumentation.
  • Grafana — lớp trực quan hóa: dashboard, khám phá dữ liệu, cắm được nhiều nguồn (Prometheus, Loki, Tempo). Xem obs-05-grafana.
  • Loki + Tempo — lưu logs và traces, tích hợp chặt với Grafana để nhảy từ metric → log → trace liền mạch. Xem obs-07-logs-traces.
  • Alertmanager — định tuyến, gom nhóm, và làm im (silence) cảnh báo. Xem obs-06-alerting.

Cuối series, obs-08-production-banking ghép tất cả vào bối cảnh vận hành thật ở ngân hàng. Bài tổng quan DevOps liên quan: devops-07-observabilitydevops-08-security-sre.

Use case thực tế

Bối cảnh: Team dữ liệu NCB vận hành API tra cứu số dư phục vụ app mobile. Giờ cao điểm (11h–13h) API xử lý ~1.200 request/giây. Business yêu cầu trải nghiệm: khách bấm "xem số dư" phải hiện kết quả gần như tức thì.

Thiết lập theo khuôn mẫu đã học:

  1. Chọn SLI (RED): SLI chính = tỷ lệ request truy vấn số dư trả về mã 2xx và độ trễ < 300ms. Đây là Errors + Duration của RED gộp lại thành một chỉ số "request tốt".
  2. Đặt SLO: 99,9% request "tốt" trong cửa sổ 30 ngày trượt. Vì cam kết nội bộ với khối vận hành (SLA lỏng hơn ở mức 99,5%), SLO cao hơn để có biên an toàn.
  3. Error budget: 0,1% của 30 ngày ≈ 43 phút ngân sách lỗi/tháng.
  4. Đo: service expose metric latency (histogram) và tổng request theo mã trạng thái; Prometheus scrape mỗi 15 giây. USE bổ sung: theo dõi độ dài connection pool tới core banking (saturation).

Diễn biến một sự cố thật (minh họa số liệu): 11h20, một chỉ mục (index) trong DB core banking bị phân mảnh sau đợt nạp dữ liệu đêm. Chuỗi phát hiện–điều tra:

  • Metric (phát hiện): p99 latency của API nhảy từ 180ms lên 900ms; tỷ lệ "request tốt" tụt còn 92%. Burn rate cho thấy budget 43 phút sẽ cháy hết trong ~2,5 giờ → alert mức nghiêm trọng đẩy tới người trực.
  • Trace (khoanh vùng): mở một trace mẫu chậm — 780ms trong tổng 900ms nằm ở span gọi core banking; các span khác bình thường. Loại trừ được API gateway và tầng xác thực.
  • Log (nguyên nhân gốc): lọc log service theo trace_id, thấy dòng WARN "query số dư vượt ngưỡng 500ms" kèm câu truy vấn cụ thể quét toàn bảng thay vì dùng index.
  • Xử lý: DBA rebuild index; p99 về 190ms sau 8 phút. Tổng thời gian tiêu tốn budget: ~18/43 phút. Vẫn trong ngân sách → không cần đóng băng deploy, nhưng tạo action item ngăn phân mảnh sau job nạp đêm.

Toàn bộ hành trình đi đúng theo mạch metric → trace → log của ba trụ cột, và quyết định "có báo động hay không" dựa trên burn rate của error budget — không phải cảm tính.

Ghi nhớ

  • Monitoring trả lời "hệ thống vấn đề không" (known-unknowns); observability trả lời "vì sao có vấn đề" (unknown-unknowns) qua dữ liệu hệ thống phát ra. Monitoring là tập con; observability là thuộc tính của hệ thống, không mua được bằng công cụ.
  • Ba trụ cột: metrics (số theo thời gian — rẻ, tổng hợp, để cảnh báo), logs (sự kiện chi tiết — giàu ngữ cảnh, để điều tra), traces (dấu vết một request qua nhiều service — để khoanh vùng độ trễ). Quy trình điều tra tự nhiên: metric → trace → log.
  • Cẩn thận cardinality của metric: đừng gắn label có quá nhiều giá trị (user_id, transaction_id) — sẽ làm nổ số chuỗi thời gian.
  • Chọn tín hiệu theo khuôn mẫu: 4 Golden Signals (Latency, Traffic, Errors, Saturation) cho dịch vụ người dùng; RED (Rate, Errors, Duration) cho mỗi service; USE (Utilization, Saturation, Errors) cho tài nguyên. RED nhìn từ dịch vụ, USE nhìn từ hạ tầng — dùng cả hai.
  • Latency phải tách request thành công và lỗi, và luôn nhìn phân vị (p95/p99) thay vì trung bình.
  • SLI (thước đo) → SLO (mục tiêu nội bộ) → SLA (cam kết hợp đồng, lỏng hơn SLO). Error budget = phần được phép lỗi; biến độ tin cậy thành con số quản trị được và là nền cho alert theo burn rate thay vì alert từng lỗi lẻ.
  • Dashboard đẹp chưa đủ: cần alert chủ động (không ai nhìn màn hình 24/7), bám vài chỉ số cốt lõi, và giữ khả năng điều tra ad-hoc. Dashboard không có alert đúng chỉ là trang trí.
  • Stack của series: Prometheus (metrics + PromQL), Grafana (trực quan), Loki/Tempo (logs/traces), Alertmanager (cảnh báo) — chạy được on-premise, phù hợp yêu cầu tuân thủ của ngân hàng. Log quy mô lớn có thể nạp vào Elasticsearch (es-05-indexing-ingest).

Bài viết liên quan

Continuous Integration/Delivery/Deployment, cấu trúc pipeline, ví dụ GitHub Actions và chiến lược release.

13 thg 7, 2026 4

Container vs máy ảo, image/layer, Dockerfile, volume, network, Docker Compose và best practices.

13 thg 7, 2026 3

Vì sao cần orchestration; Pod, Deployment, Service, Ingress; scaling, self-healing và cấu hình.

13 thg 7, 2026 3

Bản chất DevOps: phá bỏ rào cản Dev–Ops, vòng lặp vô tận, CALMS, và vì sao tự động hoá.

13 thg 7, 2026 3