# 🚨 Alert không gây mệt mỏi

By Better Wise

3 giờ sáng, điện thoại rung. Màn hình hiện: "CPU 82%". Bạn mở laptop, hệ thống vẫn chạy bình thường. Hai mươi phút sau lại rung: "CPU 79%". Đến lần thứ năm thì bạn tắt thông báo. Từ đêm đó, alert không còn giá trị gì nữa.

Ở module trước, bạn đã có metric (latency, error rate) và một dashboard vài chỉ số đáng nhìn mỗi ngày. Alert là bước biến những con số đó thành tiếng gọi đúng lúc, đúng người. Sau bài này, bạn có thể:

- Phân biệt alert theo triệu chứng người dùng và alert theo nguyên chân kỹ thuật bên trong
- Viết điều kiện alert gồm ngưỡng và thời lượng `for` đủ dài
- Nhận ra dấu hiệu alert fatigue và cách cắt bớt
- Kiểm tra một alert có đủ thông tin để hành động lúc nửa đêm không

## Alert nên bắt đầu từ triệu chứng người dùng

Người dùng không cảm nhận được CPU. Họ cảm nhận được: bấm nút thanh toán mà quay mãi, đăng nhập báo lỗi, trang mở chậm. Đó là **triệu chứng**. CPU, memory, số pod restart, dung lượng disk là **nguyên nhân**, và phần lớn nguyên nhân không ảnh hưởng gì tới người dùng.

Quy tắc đơn giản: page cho triệu chứng, xem dashboard cho nguyên nhân.

| Tín hiệu | Xử lý |
| --- | --- |
| Error rate 5xx > 2% trong 5 phút | Page |
| p95 latency trang chủ > 1 giây trong 10 phút | Page |
| Đăng nhập thất bại > 10% trong 3 phút | Page |
| CPU 85% | Dashboard |
| Một pod restart 2 lần | Dashboard |
| Disk 70% | Dashboard |

```mermaid
flowchart TD
    User["👤<br/>Người dùng gặp lỗi"] --> Metric["📈<br/>Metric triệu chứng vượt ngưỡng"]
    Metric --> Dur{"⏱️<br/>Đúng liên tục đủ for?"}
    Dur -- Chưa --> Wait["Chờ tiếp"]
    Dur -- Rồi --> Alert["🚨<br/>Page on-call"]
    Alert --> Runbook["📘<br/>Runbook và dashboard"]
```

**Bài tập 1.** Trong bốn alert sau, cái nào nên page, cái nào chỉ để trên dashboard?

1. Bộ nhớ của một worker chạm 78%
2. Tỷ lệ lỗi thanh toán tăng lên 6% trong 5 phút
3. Hàng đợi email có 2 job bị retry
4. p95 latency trang chủ là 2,5 giây trong 10 phút

**Xem gợi ý đáp án**

Page: (2) và (4), vì người dùng đang bị ảnh hưởng trực tiếp. Dashboard: (1) và (3), vì đó là nguyên chân hoặc sự kiện nhỏ, chưa chắc ai cảm nhận được. Riêng (2) nên là alert nghiêm trọng nhất trong bốn cái.

## Ngưỡng và thời lượng: cho alert thời gian để chắc chắn

Alert có hai tham số: **ngưỡng** (metric vượt bao nhiêu) và **thời lượng** (phải đúng liên tục bao lâu). Thiếu thời lượng, bạn có một cái chuông báo mỗi lần đường latency nhấp nhô, hiện tượng này gọi là **flapping**.

> **Warning:** 
> Đặt `for` quá ngắn biến alert thành máy đếm nhiễu. Một spike 30 giây thường không phải sự cố, và alert tự hết trước khi bạn kịp mở laptop còn tệ hơn không có alert.

Cách chọn nhanh: lỗi nghiêm trọng như thanh toán, đăng nhập thì `for` 3 đến 5 phút; lỗi nhẹ hoặc cảnh báo sớm thì 10 đến 15 phút, hoặc chỉ để trên dashboard.

| Triệu chứng | Ngưỡng | Thời lượng |
| --- | --- | --- |
| 5xx error rate | > 2% | 5 phút |
| p95 latency trang chủ | > 1 giây | 10 phút |
| Đăng nhập thất bại | > 10% | 3 phút |
| Job nền thất bại | > 5% | 15 phút |

**Bài tập 2.** Viết điều kiện alert cho luồng checkout, biết rằng bình thường tỷ lệ lỗi là 0,3% và mỗi giờ có khoảng 400 lượt thanh toán.

**Xem gợi ý đáp án**

Một đáp án hợp lý: "Tỷ lệ lỗi checkout > 2%, giữ liên tục 5 phút". Ngưỡng 2% cao hơn đường cơ sở 0,3% đủ xa để không rung khi có một hai giao dịch lỗi, nhưng vẫn thấp hơn mức người dùng bắt đầu bỏ đi. 5 phút đủ để loại spike tự hết. Đừng đặt ngưỡng 0,5%, vì gần như đêm nào cũng vượt.

## Alert fatigue: khi thông báo nhiều hơn việc làm

Alert fatigue không phải là "người trực lười". Nó là phản ứng bình thường khi bị gọi sai quá nhiều lần: bạn bắt đầu bỏ qua, tắt tiếng, hoặc nhìn alert rồi tự nhủ "chắc lại CPU". Và đúng đêm có sự cố thật, bạn đọc nó như mọi thông báo nhiễu khác. **Alert chỉ có giá trị khi nó dẫn tới một hành động.**

Cách cắt nhiễu, làm theo thứ tự:

1. Mỗi alert phải có hành động: không ai biết phải làm gì thì đó là dashboard, không phải page.
2. Gộp alert cùng gốc: 20 alert "pod lỗi" của cùng một service là một sự cố, hãy alert theo tỷ lệ.
3. Chỉ giữ hai mức: page và không page. Quá nhiều severity thì không ai nhớ mức nào cần dậy.
4. Rà soát hàng tuần: alert nào 30 ngày không dẫn tới hành động thì xoá hoặc hạ xuống dashboard.

**Bài tập 3.** Một alert tên `HighCPU`, bắn khi CPU > 70% trong 1 phút, gửi vào kênh chat chung, không có runbook. Hãy sửa ba điểm.

**Xem gợi ý đáp án**

(1) Đổi từ nguyên chân sang triệu chứng, ví dụ error rate hoặc latency của service đó, hoặc nếu vẫn giữ CPU thì hạ xuống dashboard. (2) Tăng thời lượng lên 10 đến 15 phút. (3) Thêm runbook, owner và dashboard link, và chỉ gửi cho người trực thay vì cả công ty.

## Một alert đủ tốt để hành động lúc 3 giờ sáng

**Alert tồi**

Tên: `HighCPU`
Điều kiện: CPU > 70% trong 1 phút
Hành động khi nhận: không rõ
Kênh: chat chung của cả công ty
Kết quả: mọi người tắt thông báo sau hai tuần

**Alert tốt**

Tên: `TyLeLoiThanhToanCao`
Điều kiện: error rate của checkout > 2%, giữ liên tục 5 phút
Severity: page
Runbook: /runbooks/checkout-errors
Dashboard: /d/checkout
Owner: team payments
Kết quả: người trực biết mở đâu, gọi ai, làm gì

Điền nhanh để nhớ:

Alert tốt bắt đầu từ _____ chứ không phải nguyên nhân kỹ thuật bên trong.
Tham số for quyết định _____.
Ngưỡng nên neo vào _____, không phải con số cảm tính.
_____ là khi quá nhiều thông báo khiến người on-call bỏ qua cả alert thật.
Alert không dẫn tới _____ thì nên đưa lên dashboard thay vì page.
Chỉ nên page cho sự cố _____.

### Thẻ ôn tập

Front: Alert nên dựa trên cái gì?
Back: Triệu chứng người dùng cảm nhận, ví dụ error rate cao hoặc latency tăng, không dựa trên nguyên nhân như CPU.

Front: Tham số for trong alert dùng để làm gì?
Back: Quy định điều kiện phải đúng liên tục bao lâu trước khi alert bắn.

Front: Vì sao alert CPU 85% thường không nên page?
Back: CPU cao chưa chắc người dùng bị ảnh hưởng, nó là nguyên nhân và phù hợp để xem trên dashboard.

Front: Ngưỡng (threshold) là gì?
Back: Giá trị mà metric phải vượt qua thì alert mới được xét tới.

Front: Flapping là gì?
Back: Metric nhấp nhô quanh ngưỡng khiến alert bắn rồi tự hết liên tục.

Front: Alert fatigue là gì?
Back: Quá nhiều alert khiến người on-call bỏ qua, tắt thông báo hoặc phản ứng chậm với sự cố thật.

Front: Dấu hiệu rõ nhất của một alert vô dụng?
Back: Không ai làm gì sau khi nhận, hoặc alert tự hết trước khi có người xem.

Front: Một alert tốt cần tối thiểu thông tin nào?
Back: Tên nói triệu chứng, điều kiện kèm thời lượng, severity, runbook, dashboard và owner.

Front: Alert 'chỉ để biết' nên đặt ở đâu?
Back: Trên dashboard, không page.

Front: Vì sao nên gộp alert cùng gốc?
Back: Nhiều alert giống nhau từ một service thực chất chỉ là một sự cố, gộp lạithành một alert theo service để người trực không bị ngập.

## Chốt lại và bước tiếp theo

Ba câu để mang đi on-call:

- Alert là để gọi người dậy, không phải để kể chuyện. Chỉ những gì đang ảnh hưởng người dùng mới đáng page.
- Mọi alert đều cần đủ ba phần: ngưỡng, thời lượng, và hành động. Thiếu một trong ba thì đó là alert chưa xong.
- Trước khi bật alert, tự hỏi: "Nếu cái này bắn lúc 3 giờ sáng, mình có dậy không?" Nếu câu trả lời là không, hạ nó xuống dashboard.

Một alert tốt là alert mà người trực đọc xong biết làm gì ngay, và mỗi tuần chỉ bắn vài lần. Bạn không cần nhiều alert, bạn cần đúng alert.

Bài tiếp theo sẽ đi sâu hơn một tầng: khi alert đã chỉ đúng "người dùng đang chậm ở luồng thanh toán", làm sao biết chậm ở bước nào trong chuỗi gọi giữa các service. Đó là lúc **tracing ở mức khái niệm** phát huy tác dụng, và nó nối rất tự nhiên với runbook bạn vừa viết.

---

## Contents

Part of [🔭 Observability cho người mới: log, metric và cảnh báo](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao.md)

- **📝 Log có cấu trúc và log level**
  - [🧱 Structured logging: log có cấu trúc và các field cần có](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/structured-logging-va-cac-field-can-co.md)
  - [🎚️ Log level: chọn đúng mức để không ngập log](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/log-level-chon-dung-muc.md) (sign-in required)
  - [🚫 Log gì và không log gì](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/log-gi-va-khong-log-gi.md)
  - [✅ Checkpoint: Log có cấu trúc và log level](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/checkpoint-log-co-cau-truc-va-log-level.md)
- **📊 Metric cơ bản và dashboard**
  - [⏱️ Metric cơ bản: latency và error rate](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/metric-co-ban-latency-va-error-rate.md)
  - [🖥️ Dashboard: vài chỉ số đáng nhìn mỗi ngày](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/dashboard-vai-chi-so-dang-nhin.md)
  - [✅ Checkpoint: Metric cơ bản và dashboard](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/checkpoint-metric-co-ban-va-dashboard.md)
- **🔔 Alert ít nhiễu, tracing và nhờ AI thêm log**
  - [🚨 Alert không gây mệt mỏi](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/alert-khong-gay-met-moi.md) — this lesson
  - [🧵 Tracing ở mức khái niệm](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/tracing-o-muc-khai-niem.md)
  - [🤖 Nhờ AI thêm log đúng chỗ](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/nho-ai-them-log-dung-cho.md) (premium content)
  - [✅ Checkpoint: Alert, tracing và AI hỗ trợ](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/checkpoint-alert-tracing-va-ai-ho-tro.md) (premium content)
- [Course cheatsheet](https://everwise.study/courses/observability-cho-nguoi-moi-log-metric-va-canh-bao/cheatsheet.md) (premium content)
