Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 38 — Observability — Logs, Metrics, Traces

Technical BA Masterclass Bài 38/60

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn là Technical BA của một ví điện tử ở Việt Nam. 9 giờ sáng thứ Hai, bộ phận chăm sóc khách hàng báo: "Có khách than nạp tiền bị trừ mà không thấy số dư tăng." Câu hỏi đầu tiên của ai cũng là: "Chuyện gì đã xảy ra?" Và đây chính là khoảnh khắc phân biệt một hệ thống quan sát được (observable) với một hệ thống "hộp đen" mù mịt.

Nếu hệ thống của bạn có observability tốt, trong vòng vài phút bạn truy ra được: giao dịch ID TX-88213 đã gọi sang cổng thanh toán lúc 9:02, nhận phản hồi thành công, nhưng bước cập nhật số dư bị timeout vì service wallet-ledger đang quá tải. Nếu không có observability, bạn sẽ ngồi đoán mò, mở từng server SSH vào xem, và mất hàng giờ — trong khi tiền của khách vẫn "treo".

Nhiều người nhầm observability với monitoring (giám sát). Monitoring trả lời câu hỏi "Hệ thống có khỏe không?" — nó dựa trên những thứ bạn biết trước để cảnh báo. Observability trả lời câu hỏi sâu hơn: "Tại sao hệ thống lại hành xử như vậy?" — kể cả với những lỗi bạn chưa từng lường trước. Đây là sự khác biệt giữa "đèn báo động đỏ" và "khả năng tự điều tra".

Với vai trò Technical BA, bạn không phải là người dựng hệ thống logging hay cấu hình Grafana. Nhưng bạn là người viết spec quyết định: sự kiện nào cần ghi log, chỉ số nào cần đo, và khi nào thì báo động. Một spec observability tốt giúp đội vận hành ngủ ngon; một spec tồi khiến cả công ty thức trắng đêm khi sự cố xảy ra mà không ai biết "mò" từ đâu. Bài này dạy bạn ba trụ cột — Logs, Metrics, Traces — đủ sâu để bạn viết được requirement chuẩn và đối thoại sòng phẳng với đội kỹ thuật.

Khái niệm cốt lõi

Observability (khả năng quan sát) là mức độ mà bạn có thể suy luận trạng thái bên trong của một hệ thống chỉ bằng cách nhìn vào dữ liệu nó phát ra. Cộng đồng kỹ thuật quy ước có ba trụ cột (three pillars): Logs, Metrics, và Traces. Mỗi trụ cột trả lời một loại câu hỏi khác nhau và chúng bổ sung cho nhau.

Trụ cột 1 — Logs (Nhật ký sự kiện)

Log là bản ghi của một sự kiện cụ thể đã xảy ra tại một thời điểm. Nó trả lời câu hỏi: "Chuyện gì đã xảy ra ở đây, lúc này?"

Điểm mấu chốt mà một Technical BA cần nắm: structured logging (log có cấu trúc). Ngày xưa người ta ghi log dạng văn bản tự do, ví dụ "User dkhang failed to login at 10:30". Kiểu này con người đọc được nhưng máy không thể truy vấn hàng triệu dòng. Log hiện đại được ghi dưới dạng JSON có cấu trúc để có thể lọc, tìm kiếm, gom nhóm:

{
  "timestamp": "2026-05-11T10:30:00Z",
  "level": "ERROR",
  "service": "auth-service",
  "trace_id": "a3f8b2c1-9d4e-4f7a-bc12-8e6d5f3a2b1c",
  "user_id": "dkhang",
  "event": "login_failed",
  "reason": "invalid_otp",
  "ip": "113.161.45.22",
  "duration_ms": 230
}

Có cấu trúc thì bạn mới hỏi được những câu kiểu: "Cho tôi tất cả login_failed với reason = invalid_otp trong 1 giờ qua, gom theo ip" — để phát hiện tấn công dò OTP.

Các mức độ log (log levels) cần biết: DEBUG (chi tiết khi dev), INFO (sự kiện bình thường, ví dụ "đơn hàng đã tạo"), WARN (bất thường nhưng chưa lỗi), ERROR (thao tác thất bại), FATAL/CRITICAL (hệ thống sập). Trong spec, bạn nên nêu rõ sự kiện nghiệp vụ nào ghi ở level nào.

Logs mạnh ở chi tiết, nhưng yếu ở chỗ: tốn dung lượng, đắt khi lưu trữ dài hạn, và nếu ghi quá nhiều sẽ thành "nhiễu" che mất tín hiệu quan trọng.

Trụ cột 2 — Metrics (Số đo)

Metric là một con số được đo theo thời gian, đã được tổng hợp sẵn. Nó trả lời câu hỏi: "Hệ thống đang khỏe ở mức nào, xu hướng ra sao?"

Ví dụ: số request mỗi giây, tỷ lệ lỗi (error rate), độ trễ p95 (95% request nhanh hơn ngưỡng này), tỷ lệ CPU, số đơn hàng tạo mỗi phút. Khác với log — mỗi sự kiện một dòng — metric chỉ lưu con số tổng hợp theo khoảng thời gian, nên rất rẻ để lưu trữ và rất nhanh để vẽ biểu đồ, cảnh báo.

Technical BA nên thuộc lòng khung "Golden Signals" của Google SRE — bốn tín hiệu vàng để theo dõi bất kỳ service nào:

  • Latency (độ trễ): mất bao lâu để xử lý một request. Lưu ý tách riêng độ trễ của request thành công và thất bại.
  • Traffic (lưu lượng): hệ thống đang chịu tải bao nhiêu, ví dụ request/giây.
  • Errors (lỗi): tỷ lệ request thất bại.
  • Saturation (độ bão hòa): tài nguyên đang đầy đến đâu (RAM, CPU, hàng đợi).
Điểm yếu của metrics: nó cho bạn biết "có vấn đề" nhưng không nói "tại sao". Error rate vọt lên 8% — metric báo động, nhưng để biết vì sao lỗi thì bạn phải sang logs và traces.

Trụ cột 3 — Traces (Dấu vết phân tán)

Trace theo dõi hành trình của một request duy nhất khi nó đi xuyên qua nhiều service. Nó trả lời câu hỏi: "Request này đã đi qua đâu, ở chặng nào chậm/lỗi?"

Trong kiến trúc microservices, một thao tác "đặt hàng" có thể chạm vào api-gatewayorder-serviceinventory-servicepayment-servicenotification-service. Mỗi chặng là một span, và toàn bộ chuỗi span chia sẻ chung một trace_id. Nhờ trace, bạn thấy được biểu đồ dạng thác (waterfall): chặng payment-service ngốn 1.800ms trong tổng 2.100ms — thủ phạm rõ ràng.

Mấu chốt kỹ thuật là context propagation (truyền ngữ cảnh): trace_id phải được chuyền qua mỗi lần gọi service (thường qua HTTP header, theo chuẩn W3C Trace Context). Đây là lý do trong spec bạn nên yêu cầu mọi log đều đính kèm trace_id — để nối được ba trụ cột với nhau.

Tóm tắt mối quan hệ: Metrics cho bạn biết vấn đề. Traces cho bạn biết ở đâu trong hệ thống. Logs cho bạn biết chính xác cái gì đã xảy ra ở điểm đó.

Tình huống thực tế

Ví dụ 1 — Sàn TMĐT giờ flash sale, error rate tăng đột biến

Một sàn thương mại điện tử (gọi là ShopViet) chạy flash sale lúc 12 giờ trưa. Đúng 12:00, biểu đồ metric error rate của checkout-service nhảy từ 0.5% lên 12%. Đội on-call nhận cảnh báo (alert) cấu hình theo Golden Signal "Errors".

Bước điều tra: metric chỉ ra service nào lỗi nhưng không nói lý do. Họ mở traces của các request lỗi, thấy 90% trace đều "đứng" ở span gọi sang inventory-service với trạng thái timeout sau 3.000ms. Sang logs của inventory-service, thấy hàng loạt dòng level: ERROR, event: db_connection_pool_exhausted — hết kết nối tới database vì lượng truy vấn tồn kho tăng vọt.

Bài học rút ra: Cả ba trụ cột phối hợp mới chẩn đoán được. Metric phát hiện (12% lỗi), trace khoanh vùng (inventory-service), log chỉ đích danh nguyên nhân (cạn connection pool). Nếu chỉ có một trong ba, đội kỹ thuật sẽ mất hàng giờ. Với vai BA, đây là minh chứng tại sao spec phải yêu cầu cả ba, và đặc biệt yêu cầu trace_id xuyên suốt để nhảy từ trace sang log trong một cú click.

Ví dụ 2 — Ngân hàng số và bài học "log thiếu thì như mù"

Một ngân hàng số tại Đông Nam Á triển khai tính năng chuyển khoản liên ngân hàng qua hệ thống bù trừ. Trong giai đoạn đầu, BA chỉ yêu cầu log ở mức "giao dịch thành công / thất bại". Khi một giao dịch 50 triệu đồng bị "treo" — tiền đã trừ ở ngân hàng gửi nhưng chưa ghi có ở ngân hàng nhận — đội vận hành mở log lên và chỉ thấy đúng một dòng: transaction_failed. Không có trace_id, không có mã phản hồi từ hệ thống bù trừ, không có timestamp từng bước.

Hệ quả: họ phải gọi điện cho hệ thống đối tác, đối chiếu thủ công, mất gần hai ngày mới gỡ được. Sau sự cố, BA viết lại spec logging: mỗi giao dịch phải ghi log ở từng trạng thái (initiated → sent_to_clearing → ack_received → settled), kèm trace_id, mã phản hồi đối tác, và masking (che) số tài khoản để tuân thủ bảo mật.

Bài học rút ra: Observability không phải thứ "thêm sau". Quyết định ghi log gì là quyết định nghiệp vụ mà BA phải tham gia ngay từ giai đoạn thiết kế. Một log "thông minh" cần đủ ngữ cảnh để tái dựng lại câu chuyện mà không cần hỏi ai khác.

Ví dụ 3 — Startup giao đồ ăn và chi phí log "phình to"

Một startup giao đồ ăn cấu hình ghi log ở mức DEBUG cho toàn bộ hệ thống production để "cho chắc". Sau ba tháng, hóa đơn của nền tảng quản lý log (kiểu Datadog/ELK) lên tới hơn 200 triệu đồng/tháng, trong khi 95% log là dòng DEBUG vô dụng mà không ai từng đọc. Tệ hơn, khi sự cố thật xảy ra, các dòng ERROR quan trọng bị chôn vùi giữa biển log DEBUG, khiến việc tìm kiếm chậm chạp.

Đội kỹ thuật cùng BA rà soát, hạ level mặc định xuống INFO, thêm cơ chế sampling (lấy mẫu) cho traces — chỉ giữ 100% trace lỗi và 5% trace thành công — và đặt thời gian lưu trữ (retention) khác nhau: log ERROR giữ 90 ngày, INFO giữ 14 ngày. Chi phí giảm hai phần ba mà chất lượng điều tra sự cố lại tăng.

Bài học rút ra: Observability có chi phí thật. BA giỏi không yêu cầu "ghi tất cả mọi thứ" mà cân bằng giữa giá trị điều tra và chi phí lưu trữ, thông qua các quyết định về log level, sampling và retention — và đưa những con số này vào spec.

Hướng dẫn từng bước

Đây là quy trình một Technical BA xây dựng phần observability cho một tính năng mới:

  • Xác định "luồng nghiệp vụ quan trọng" (critical user journeys). Liệt kê các hành trình mà nếu hỏng sẽ ảnh hưởng trực tiếp tới khách hàng hoặc tiền bạc: đăng nhập, thanh toán, đặt hàng. Đây là nơi observability phải đầu tư nhất.
  • Định nghĩa các sự kiện cần log. Với mỗi luồng, liệt kê những điểm cần ghi nhật ký và level tương ứng. Ví dụ cho thanh toán: payment_initiated (INFO), gateway_called (INFO), gateway_timeout (ERROR), payment_settled (INFO). Quy định trường bắt buộc: timestamp, level, service, trace_id, mã định danh nghiệp vụ.
  • Chọn metrics theo Golden Signals. Với mỗi service quan trọng, định nghĩa rõ: đo latency ở phân vị nào (p95, p99), error rate tính thế nào, traffic đo bằng đơn vị gì. Viết thành bảng để đội kỹ thuật cấu hình.
  • Yêu cầu tracing xuyên suốt. Đưa vào spec yêu cầu: mọi request phải có trace_id được khởi tạo ở điểm vào (gateway) và truyền qua mọi service. Mọi log phải đính kèm trace_id này.
  • Định nghĩa ngưỡng cảnh báo (alerting thresholds). Đây là phần BA thường bỏ sót. Ví dụ: "Cảnh báo P1 khi error rate của checkout > 5% trong 5 phút liên tục" hay "Cảnh báo P2 khi latency p95 > 800ms". Mỗi cảnh báo phải gắn với một mức ưu tiên và một quy trình xử lý.
  • Quy định masking và tuân thủ. Liệt kê các trường nhạy cảm (số thẻ, số CMND/CCCD, mật khẩu, OTP) tuyệt đối không được ghi vào log, hoặc phải che (masking). Đây là yêu cầu pháp lý, không phải tùy chọn.
  • Định nghĩa retention và sampling. Nêu rõ thời gian lưu của từng loại dữ liệu và tỷ lệ lấy mẫu trace, để cân bằng chi phí.

Lỗi thường gặp & mẹo

Lỗi: Nhầm observability với chỉ là dashboard đẹp. Một màn hình Grafana lung linh không có nghĩa là hệ thống quan sát được. Nếu dashboard chỉ hiện những thứ bạn đã biết trước, bạn vẫn "mù" trước lỗi lạ. Observability thật sự cho phép bạn đặt câu hỏi mới mà không cần deploy lại code.

Lỗi: Log không có trace_id. Đây là sai lầm phổ biến nhất và đắt giá nhất. Không có sợi chỉ chung nối log — trace — metric, bạn có ba kho dữ liệu rời rạc không ghép được. Mẹo: yêu cầu trace_id là trường bắt buộc trong mọi structured log ngay từ spec đầu tiên.

Lỗi: Ghi dữ liệu nhạy cảm vào log. Vô tình log số thẻ tín dụng hay mật khẩu là vi phạm nghiêm trọng PCI-DSS và lộ dữ liệu cá nhân. Mẹo: luôn có một mục "trường cấm log" trong spec.

Lỗi: Cảnh báo quá nhiều gây "alert fatigue". Khi đội on-call nhận 200 cảnh báo mỗi ngày, họ sẽ tắt thông báo và bỏ lỡ cái thật sự quan trọng. Mẹo: cảnh báo phải hành động được (actionable) — mỗi alert phải tương ứng với việc cần ai đó làm ngay; nếu không thì hạ thành chỉ số theo dõi, đừng báo động.

Mẹo: Phân biệt sự kiện kỹ thuật và sự kiện nghiệp vụ. BA có lợi thế độc nhất là hiểu nghiệp vụ. Hãy yêu cầu log cả những "business event" như "khách hủy đơn sau khi thanh toán" — vì đôi khi vấn đề không phải lỗi kỹ thuật mà là hành vi bất thường về nghiệp vụ.

Mẹo: Dùng correlation_id ở tầng nghiệp vụ. Ngoài trace_id kỹ thuật, hãy đính kèm mã đơn hàng hay mã giao dịch để CSKH tra cứu được theo ngôn ngữ khách hàng.

Bài tập thực hành

Bạn là Technical BA cho tính năng "Nạp tiền vào ví điện tử" của một fintech Việt Nam. Luồng gồm: người dùng chọn số tiền → gọi cổng thanh toán (VNPay/Momo giả định) → nhận callback kết quả → cập nhật số dư ví → gửi thông báo.

  • Logs: Liệt kê tối thiểu 6 sự kiện cần ghi log trong luồng này, mỗi sự kiện gán một log level và nêu các trường bắt buộc đi kèm. Chỉ rõ ít nhất 2 trường tuyệt đối không được log.
  • Metrics: Áp dụng khung Golden Signals, định nghĩa 4 metric cụ thể cho wallet-topup-service kèm đơn vị đo và phân vị (nếu là latency).
  • Traces: Vẽ phác (bằng chữ) chuỗi span của một giao dịch nạp tiền và chỉ ra span nào bạn nghi ngờ là điểm nghẽn tiềm tàng nhất, giải thích vì sao.
  • Alerting: Viết 2 quy tắc cảnh báo (gồm điều kiện, ngưỡng, khoảng thời gian, mức ưu tiên) mà bạn sẽ đưa vào spec.
  • Mở rộng: Đề xuất một chính sách retention và sampling hợp lý, giải thích lựa chọn của bạn dựa trên cân bằng chi phí và giá trị điều tra.
Hãy viết thành một bảng requirement ngắn như khi bàn giao cho đội kỹ thuật. Đây chính là dạng tài liệu bạn sẽ tạo ra trong công việc thật.

Tóm tắt

Observability là khả năng suy ra trạng thái bên trong hệ thống từ dữ liệu nó phát ra — sâu hơn monitoring vì nó giúp bạn điều tra cả những lỗi chưa lường trước. Ba trụ cột bổ sung cho nhau: Logs kể chính xác chuyện gì đã xảy ra tại một điểm, Metrics cho biết hệ thống khỏe ở mức nào và có vấn đề không, Traces chỉ ra request đi qua đâu và nghẽn ở chặng nào. Sợi chỉ trace_id chung là thứ nối ba trụ cột thành một bức tranh điều tra liền mạch.

Với vai trò Technical BA, bạn không cấu hình công cụ nhưng bạn định hình spec: sự kiện nào log ở level nào, metric nào theo Golden Signals, ngưỡng cảnh báo ra sao, trường nào cấm log để tuân thủ, và retention/sampling thế nào để kiểm soát chi phí. Như ba ví dụ đã cho thấy — từ ShopViet truy lỗi flash sale, ngân hàng số mắc kẹt vì log thiếu, đến startup giao đồ ăn cháy túi vì log thừa — observability là một quyết định nghiệp vụ phải có mặt từ đầu, không phải miếng vá dán sau khi sự cố nổ ra. Một Technical BA viết được spec observability tốt chính là người đảm bảo rằng khi sự cố đến — và nó sẽ đến — cả đội có đủ dữ liệu để trả lời câu hỏi quan trọng nhất: "Chuyện gì đã thực sự xảy ra?"