# Monitor theo tín hiệu: đếm, kiểm điều kiện và lượt chạy bị treo

> Bắt lỗi im lặng từ error, check-in, span và log đã có: việc xảy ra quá ít hoặc quá nhiều, kết quả sai, lượt chạy đứng yên — xét trên node của anh.

Monitor việc theo lịch bắt được việc **không chạy**. Có những lỗi im lặng hơn: việc vẫn chạy và báo "thành công" nhưng không có bài nào được đăng, model trả về câu rỗng, hoặc worker đã bắt đầu rồi đứng im. **Monitor theo tín hiệu** canh đúng những trường hợp đó, dựa trên lỗi, check-in, span, log và [metrics](https://belvador.dev/vi/docs/otel/metrics) mà app của anh vốn đã gửi.

Mỗi monitor theo tín hiệu được xét **trên node của anh** mỗi 15 giây, trên dữ liệu node đang giữ. Belvador chỉ nhận kết luận (số đếm và ngưỡng, không bao giờ nhận message hay giá trị thuộc tính).

| Loại | Dùng khi | Ví dụ |
|---|---|---|
| **Đếm** | việc phải xảy ra đủ số lần — hoặc không quá nhiều | "ít nhất 1 log `post.published` mỗi 60 phút", "nhiều nhất 50 error event trên `queue=emails` mỗi 5 phút" |
| **Kiểm điều kiện** | kết quả phải đúng, không chỉ "thành công" | "span `gen_ai.chat` phải có `gen_ai.usage.output_tokens > 0`; cảnh báo khi sai 3 lần trong 10 phút" |
| **Hạn chót** | việc đã hẹn giờ phải xong trước hạn | "mỗi bài hẹn giờ phải đăng trước giờ hẹn + 5 phút" — xem [Monitor hạn chót](https://belvador.dev/vi/docs/monitors/deadlines) |
| **Tiến triển** | việc đang chạy không được đứng yên | "lượt import đã bắt đầu phải có tín hiệu sống ít nhất mỗi 10 phút" |
| **Metric** | một con số phải nằm trong giới hạn | "p95 của `http.server.request.duration` trong 5 phút dưới 0,8 giây", "`queue.oldest_age` dưới 600 giây cho từng hàng đợi" |

Tạo ở **Monitor → Tạo monitor**, rồi chọn loại.

## Chọn tín hiệu cần canh (đếm và kiểm điều kiện)

Chọn **tín hiệu** — error event, check-in, span hoặc log — rồi thêm tối đa 5 điều kiện **khớp khi**. Mọi điều kiện đều phải đúng (AND). Tên thuộc tính là tên chuẩn, nên SDK hay OpenTelemetry anh đang dùng chạy được ngay:

- Trường của Sentry: `level`, `release`, `transaction`, `environment`, `exception.type`, `monitor.slug`, `tags.<tên>`
- Thuộc tính OpenTelemetry: `service.name`, `http.response.status_code`, `http.route`, `error.type`, `gen_ai.usage.output_tokens`, `name` của span, `event.name` của log, `severity_text`
- Trường lượt chạy của Belvador: `belvador.run.id`, `belvador.outcome`

Phép so: `=` `≠` `<` `≤` `>` `≥`, **là một trong** (tối đa 20 giá trị), **có giá trị**, **không có**, **bắt đầu bằng**. Giá trị dài tối đa 256 ký tự. Không có biểu thức chính quy: chi phí kiểm một tín hiệu luôn cố định, dữ liệu thế nào cũng vậy.

Monitor **kiểm điều kiện** có thêm tối đa 5 điều kiện **phải đúng**. Tín hiệu khớp mà sai bất kỳ điều kiện nào là một **vi phạm**.

## Khi nào cảnh báo

- **Cửa sổ**: từ 1 đến 1440 phút. Cứ mỗi phút lại có một cửa sổ kết thúc, nên sự cố được thấy trong vòng một phút sau khi cửa sổ đóng.
- **Đếm** cảnh báo khi số đếm **thấp hơn** ngưỡng, **cao hơn** ngưỡng, hoặc **ra ngoài khoảng**.
- **Kiểm điều kiện** cảnh báo khi số vi phạm trong cửa sổ chạm ngưỡng.
- **Khi cả cửa sổ không có tín hiệu khớp**: *tính là 0* (đúng cho "ít nhất N" — im lặng chính là sự cố), *cảnh báo*, *giữ trạng thái trước*, hoặc *coi là ổn*.
- **Ổn lại sau**: cần bao nhiêu cửa sổ xanh liên tiếp để đóng cảnh báo.

Khi node offline hoặc đang bắt kịp, monitor **không bị xét**: nó hiện "chưa biết" thay vì báo động nhầm, và thiếu dữ liệu không bị hiểu thành số 0.

### Xem trước 30 ngày qua

Khi sửa monitor đếm hoặc kiểm điều kiện, khung bên phải chạy lại **cùng quy tắc** trên 30 ngày dữ liệu gần nhất mà node đang giữ và cho biết monitor sẽ cảnh báo bao nhiêu lần. Dùng nó để chọn ngưỡng trước khi có cảnh báo đầu tiên. Bản xem trước được đọc từ node bằng vé ngắn hạn; không có gì được sao chép về Belvador.

## Tiến triển (lượt chạy bị treo)

Một **lượt chạy** bắt đầu bằng check-in `in_progress`, hoặc bằng span/log mang `belvador.run.id`. Mọi tín hiệu sau đó có cùng id là **tín hiệu sống**. Khi lượt đang chạy không gửi gì lâu hơn **coi là treo sau** (1 đến 1440 phút), Belvador cảnh báo `MONITOR_STALLED`. Tín hiệu mới của lượt đó sẽ đóng cảnh báo.

## Monitor metric

Monitor **metric** đọc một [metric](https://belvador.dev/vi/docs/otel/metrics) mà dịch vụ gửi và xét một con số cho mỗi cửa sổ:

- **Metric và phép tổng hợp** — cùng lựa chọn như trang Metrics (`avg`, `sum`, `min`, `max`, `count`, `rate`, `p50`–`p99`), kèm tối đa 5 bộ lọc thuộc tính. Nút **Tạo monitor** trên trang Metrics mang truy vấn đang xem sang.
- **Quy tắc** — giá trị **trên** ngưỡng, **dưới** ngưỡng, hoặc **ngoài** một khoảng, theo đơn vị của metric.
- **Nhóm theo** — tối đa 2 khoá thuộc tính. Mỗi bộ giá trị (ví dụ mỗi `http.route`) được xét và cảnh báo riêng, tối đa 50 nhóm mỗi môi trường. Cảnh báo nêu tên monitor, không bao giờ nêu giá trị của nhóm.
- **Khi cửa sổ không có điểm nào** — *giữ trạng thái trước* (mặc định: exporter im lặng không có nghĩa là đã khỏi), *coi là 0*, *cảnh báo*, hoặc *coi là ổn*.

Điểm đến khoảng mỗi phút một lần, nên một cửa sổ được xét 120 giây sau khi kết thúc, lúc phút cuối đã đủ. Khi chỉnh sửa, khung bên phải vẽ 24 giờ qua của cùng truy vấn, mỗi cửa sổ một điểm, kèm ngưỡng của anh và số cửa sổ lẽ ra đã cảnh báo. Monitor metric cần node chạy agent 0.1.37 trở lên.

## Mức độ và cảnh báo

Mỗi monitor có **mức độ** (critical, high, medium, low) đi kèm mọi cảnh báo. Ai nhận thông báo được đặt ở **Cảnh báo → quy tắc**, mục *Sự cố monitor*; các loại là *số đếm ngoài khoảng*, *kiểm điều kiện sai*, *lỡ hạn chót*, *bị treo* và *metric bất thường*. Cảnh báo chỉ mang tên monitor, project, môi trường, số đếm và ngưỡng — không bao giờ có message, giá trị thuộc tính hay id lượt chạy.

Để tắt tiếng cảnh báo trong lúc deploy đã lên lịch, hãy thêm [khung bảo trì](https://belvador.dev/vi/docs/monitors/maintenance).

## Từ code, API hoặc AI agent

Cùng bộ cài đặt này được nhận qua `POST /v1/monitors` và `PATCH /v1/monitors/<monitor_id>` với đối tượng `settings` (`settings.type` là `count`, `assertion`, `deadline`, `progress` hoặc `metric`), và qua công cụ MCP cấu hình monitor. `GET /v1/monitors/<id>/signal` trả về số đếm theo phút, còn `POST /v1/monitors/backtest` chạy cùng bản xem trước 30 ngày. Xem [tài liệu API](https://belvador.dev/vi/docs/reference/api).
