---
title: "Observability: Logs vs. Metrics vs. Tracing - Mô hình tư duy 'Bộ dụng cụ Bác sĩ'"
description: "App chậm. Tại DB? Queue? Mạng? Hướng dẫn chuyên sâu về ba trụ cột observability và cách chúng phối hợp với nhau."
pubDate: "2023-05-25"
lang: "vi"
slug: "observability-logs-metrics-tracing"
url: "https://hoangyell.com/vi/observability-logs-metrics-tracing/"
author: "HoangYell"
translation_en: "https://hoangyell.com/observability-logs-metrics-tracing/"
categories: ["System Design"]
tags: ["devops", "observability", "monitoring", "python"]
heroImage: "https://raw.githubusercontent.com/HoangGeek/store/main/webp/photo-1551288049-bebda4e38f71.webp"
---

App production của bạn đang chậm. User phàn nàn. Sếp nhắn Slack.

Bạn SSH vào server và... nhìn chằm chằm vào màn hình.

Không có observability, debug production giống như bác sĩ chẩn đoán bệnh nhân mà không được nhìn, sờ, hay nói chuyện với họ. Bài viết này trao cho bạn bộ dụng cụ của Bác sĩ.

***

## Phần 1: Nền tảng (Mô hình tư duy)

### Bộ dụng cụ Bác sĩ

Bác sĩ có ba loại dụng cụ cho các câu hỏi khác nhau:

*   **Ống nghe (Logs)**: "Để tôi NGHE bệnh nhân đang nói gì từng giây một." Sự kiện thô. Có timestamp. Chi tiết. Ồn ào.
*   **Bảng theo dõi sinh hiệu (Metrics)**: "Để tôi KIỂM TRA các con số quan trọng: nhịp tim, huyết áp, nhiệt độ." Đã tổng hợp. Là số. Tốt cho dashboard.
*   **X-Quang (Tracing)**: "Để tôi NHÌN THẤY bên trong và theo dõi đúng vấn đề này qua từng cơ quan." Luồng request đầu cuối xuyên suốt các service.

| Trụ cột | Câu hỏi trả lời | Đơn vị | Công cụ |
|:---|:---|:---|:---|
| **Logs** | "Chính xác chuyện gì đã xảy ra?" | Text events | Datadog, Loki, ELK Stack |
| **Metrics** | "Hệ thống đang như thế nào *nói chung*?" | Số liệu theo thời gian | Prometheus, Grafana, Datadog |
| **Tracing** | "*Request này* bị chậm ở đâu?" | Spans + Traces | Jaeger, Zipkin, OpenTelemetry |

```markdy
scene type=layers width=1150 height=650
theme: light=doodle dark=nebula

service Tracing "1. Distributed Tracing (Span yêu cầu đầu-cuối & OpenTelemetry)"
service Metrics "2. Metrics Tổng hợp (Bộ đếm thời gian thực & Prometheus)"
service Logs "3. Logs Có cấu trúc (Dòng sự kiện JSON & Bối cảnh chẩn đoán)"

beat pillars "Tam giác Chẩn đoán Vấn đề Production" {
  show $nodes stagger=60ms
  glow Tracing "Định vị nút thắt độ trễ xuyên suốt các service (X-Quang)"
}

player:
    playback:
      loop true
    controls:
      speed true
      speeds "0.25"
      fullscreen true
      gif true
      theme true
    interaction:
      zoom true
      pan true
      click_to_play true
      double_click_to_reset true
      keyboard false
    chrome:
      badge true
      progress none
```

***

## Phần 2: Điều tra (Đi sâu từng Trụ cột)

### 1. Logs - "Nhật ký của Bệnh nhân"

Log là bản ghi có timestamp về những gì đã xảy ra. Kỷ luật quan trọng nhất: **structured logging** (log có cấu trúc).

```python
# ❌ TỆ: Không có cấu trúc (khó query)
print(f"Lỗi xử lý đơn hàng cho user {user_id}")

# ✅ TỐT: JSON có cấu trúc (có thể tìm kiếm, lọc)
import structlog
log = structlog.get_logger()

log.error(
    "order_processing_failed",
    user_id=user_id,
    order_id=order_id,
    reason=str(e),
    duration_ms=123
)
# Output: {"event": "order_processing_failed", "user_id": 42, "order_id": 999, ...}
```

**Log Levels** (Dùng đúng!):
*   `DEBUG`: Chi tiết tỉ mỉ cho dev. **Tắt ở production**.
*   `INFO`: Hoạt động bình thường. "User 42 đăng nhập."
*   `WARNING`: Có thể sắp có chuyện. "Ổ đĩa đầy 80%."
*   `ERROR`: Thứ gì đó thất bại. "Thanh toán thất bại cho đơn 999."
*   `CRITICAL`: App đang hấp hối. Người trực on-call thức dậy.

### 2. Metrics - "Bảng Sinh hiệu"

Metrics cho bạn biết **xu hướng thay đổi theo thời gian**. Bốn Tín hiệu Vàng (Google SRE):

*   **Latency**: Request mất bao lâu? (p50, p95, p99)
*   **Traffic**: Bao nhiêu request mỗi giây?
*   **Errors**: Bao nhiêu % request thất bại?
*   **Saturation**: Hệ thống đầy bao nhiêu? (CPU %, RAM %, độ sâu Queue)

```python
# Dùng Prometheus với Python
from prometheus_client import Counter, Histogram

REQUEST_LATENCY = Histogram("api_request_duration_seconds", "Độ trễ API")
ERROR_COUNT = Counter("api_errors_total", "Tổng lỗi API", ["endpoint"])

@REQUEST_LATENCY.time()  # Tự động đo thời gian hàm
def process_order(order_id):
    try:
        ...
    except Exception:
        ERROR_COUNT.labels(endpoint="/orders").inc()
```

### 3. Tracing - "Phim X-Quang"

Trong hệ thống microservices, một request user có thể đi qua 7 service. Nếu mất 2 giây, **2 giây đó ở đâu?**

Tracing trả lời bằng **Biểu đồ Thác nước (Waterfall)**:
```
Request: GET /checkout (2.0s tổng)
├── Auth Service (0.05s) ✅
├── Cart Service (0.08s) ✅
├── Inventory Service (1.6s) ← 🔴 NÚT CỔ CHAI
│   └── DB Query: SELECT ... (1.55s)  ← THỨ THỰC SỰ CHẬM
└── Payment Service (0.27s) ✅
```

**OpenTelemetry** là chuẩn mở. Viết một lần, gửi đến backend nào cũng được (Jaeger, Datadog,...):

```python
from opentelemetry import trace

tracer = trace.get_tracer(__name__)

def checkout(user_id):
    with tracer.start_as_current_span("checkout") as span:
        span.set_attribute("user.id", user_id)
        
        with tracer.start_as_current_span("fetch_cart"):
            cart = get_cart(user_id)  # Span này sẽ là con của span cha
        
        with tracer.start_as_current_span("process_payment"):
            charge(cart.total)
```

***

## Phần 3: Chẩn đoán (Dùng Công cụ Nào?)

| Vấn đề | Nhìn vào đâu trước? | Tại sao |
|:---|:---|:---|
| "Lỗi 500 cho user 42" | **Logs** | Tìm thông báo lỗi và stack trace chính xác. |
| "API chậm từ 3 giờ chiều" | **Metrics** | Tìm đỉnh P95 latency trên dashboard. |
| "Request này mất 2s" | **Tracing** | Xem Waterfall và tìm service nào chậm. |
| "Server bị sập" | **Metrics** | Alert CPU/Memory kích hoạt trước khi crash. |

***

## Phần 4: Giải pháp (Bộ Alerting)

Bạn không thể ngồi nhìn dashboard 24/7. Bạn cần **alerts**.

**Alert tốt**: "P99 latency vượt 2 giây trong 5 phút." (Cụ thể, có thể hành động).
**Alert tệ**: "CPU trên 50%." (Mơ hồ, báo liên tục, gây alert fatigue).

```yaml
# Prometheus alerting rule
groups:
- name: api_alerts
  rules:
  - alert: HighLatencyP99
    # Báo alert nếu P99 latency > 2s trong 5 phút
    expr: histogram_quantile(0.99, api_request_duration_seconds_bucket) > 2
    for: 5m
    annotations:
      summary: "P99 latency của API đang ở mức nghiêm trọng"
```

***

## Mô hình tư duy chốt hạ

```
Logs    -> Nhật ký Bệnh nhân. "Chuyện gì xảy ra? Khi nào? Chi tiết thế nào?"
Metrics -> Bảng Sinh hiệu. "Hệ thống đang biến đổi theo hướng nào?"
Tracing -> Phim X-Quang. "Request CỤ THỂ NÀY bị lỗi ở đâu?"

Dùng Logs để hiểu sự kiện.
Dùng Metrics để build dashboard và alert.
Dùng Tracing để debug giao dịch phân tán chậm.
```

Bạn cần cả ba. Log không có Metrics là bay mù. Metrics không có Tracing là biết mình bệnh nhưng không biết tại sao.
