# Metrics bằng OpenTelemetry

> Bật metrics OTLP, những loại được lưu, xem theo phép tổng hợp, bộ lọc và nhóm, giới hạn chuỗi giữ chi phí dễ đoán, quyền riêng tư và cảnh báo theo metric.

Traces cho thấy một request, logs cho thấy code đã ghi gì. **Metrics** cho thấy một con số theo thời gian: số request mỗi giây, bộ nhớ đang dùng, số job đang chờ trong hàng đợi, số kết nối còn trống trong pool. Belvador nhận metrics từ SDK OpenTelemetry chuẩn và Collector qua OTLP/HTTP, lưu một điểm mỗi phút trên node của chính bạn, rồi cho bạn vẽ biểu đồ và đặt cảnh báo.

Metrics **mặc định tắt**. Chúng tốn request và có hạn mức tháng riêng, nên bạn bật ở chỗ nào cần.

## Bật metrics

1. **Ingest key.** Ở **Cài đặt project → Ingest key**, tích **Metrics** cho khoá mà dịch vụ đang dùng (hoặc tạo khoá mới có quyền này). Khoá không có quyền này nhận `403`.
2. **Exporter.** Trong [bộ biến chuẩn](https://belvador.dev/vi/docs/otel/quickstart#2-dat-cac-bien-chuan), bật exporter metric:

```bash
export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.belvador.dev/otlp/<project-id>
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer%20<your-ingest-key>
export OTEL_TRACES_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=otlp
export OTEL_METRIC_EXPORT_INTERVAL=60000
export OTEL_SERVICE_NAME=my-service
export OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production
```

Xuất mỗi phút một lần (60 giây): Belvador giữ một điểm mỗi phút, xuất dày hơn chỉ thêm request. Cả hai kiểu temporality đều được — cumulative (mặc định của mọi SDK) và delta.

3. **Node của bạn** lưu metrics từ agent 0.1.37 trở lên; node tự cập nhật. Trước đó, metrics chờ ở edge, được mã hoá bằng khoá của node, và được giao sau khi cập nhật.

> **Đã kiểm ngày 2026-10-27** với otelcol-contrib 0.163.1, telemetrygen v0.163.0: traces đạt, logs đạt, metrics đạt.

Lượt chạy Collector gửi một metric cho mỗi loại bên dưới rồi đọc lại từ node. SDK OpenTelemetry gửi cùng định dạng OTLP, nhưng Belvador chưa chạy exporter metric của chúng, nên chúng chưa được đánh dấu đã kiểm cho metrics. Công thức cho metrics máy chủ, hàng đợi, nghiệp vụ và Supabase: [Công thức metrics](https://belvador.dev/vi/docs/otel/metrics-recipes).

## Những gì được lưu

| Loại OTLP | Lưu thành | Instrument thường gặp |
|---|---|---|
| Gauge | một mức | `ObservableGauge`, `system.cpu.load_average.1m` |
| Sum, đơn điệu tăng | bộ đếm (phần tăng) | `Counter`, `system.network.io`, `app.signups` |
| Sum, không đơn điệu | một mức (cumulative) hoặc phần tăng (delta) | `UpDownCounter`, `system.memory.usage` |
| Histogram | phân bố kèm các bucket | `Histogram`, `http.server.request.duration` |
| Exponential histogram | phân bố kèm các bucket | SDK cấu hình bucket cơ số 2 |

Điểm **Summary** không được lưu; chúng được đếm là *Loại metric không hỗ trợ* (mọi SDK hiện nay xuất histogram thay thế). Bộ đếm cumulative được đổi thành phần tăng mỗi phút trên node; bộ đếm khởi động lại (sau một lần deploy) đếm tiếp từ giá trị mới thay vì hiện một cú giảm âm.

## Xem metrics

Trang **Metrics** liệt kê các metric project đã gửi, kèm loại, đơn vị và số chuỗi. Chọn một metric, rồi:

- **Phép tổng hợp** — `avg`, `sum`, `min`, `max`, `count`, `rate` (mỗi giây, cho bộ đếm và histogram), hoặc `p50`/`p90`/`p95`/`p99` (histogram). Bộ đếm mở với rate, histogram với p95, mức với trung bình.
- **Bộ lọc** — tối đa 5 điều kiện thuộc tính, giống ở Traces và Logs.
- **Nhóm theo** — tối đa 2 khoá thuộc tính; mỗi bộ giá trị là một đường trên biểu đồ (vẽ 50 nhóm đầu).
- **Bước** — từ một điểm mỗi phút tới một điểm mỗi ngày. Một truy vấn bao tối đa 7 ngày và 10,000 điểm.

Điểm histogram có **exemplar** khi SDK ghi chúng: trace của một request trong bucket đó. Bấm vào để mở trace.

## Giới hạn giữ chi phí dễ đoán

Một **chuỗi** (series) là một tên metric với một bộ giá trị thuộc tính. Số chuỗi mới là thứ tốn đĩa và bộ nhớ, nên node giới hạn nó:

| | Gói mặc định |
|---|---|
| Chuỗi đang hoạt động mỗi node (thấy trong 24 giờ qua) | 10,000 |
| Tên metric mỗi node | 1,000 |
| Thuộc tính mỗi chuỗi | 32, giá trị tối đa 256 ký tự |
| Giữ trong | 14 ngày, một điểm mỗi phút |
| Lượng mỗi tháng | 2 GB (thân request đã nén), tách riêng với traces và logs |

Điểm của chuỗi **mới** vượt giới hạn không được lưu và được đếm là *Vượt giới hạn chuỗi*; chuỗi đã có vẫn chạy bình thường, và trang Metrics nêu tên các metric chạm giới hạn. Nguyên nhân thường gặp là một thuộc tính có giá trị không giới hạn — user id, mã đơn hàng, URL đầy đủ. Để chúng ở span và log, còn metric chỉ dùng thuộc tính ít giá trị (`http.route`, không phải URL).

Trang Metrics cho thấy node đang giữ bao nhiêu chuỗi và tên so với giới hạn; thời gian lưu và lượng mỗi tháng nằm ở **Cài đặt project → Traces, logs và metrics đã nhận**.

## Quyền riêng tư

Thuộc tính metric đi qua cùng [quy tắc quyền riêng tư](https://belvador.dev/vi/docs/otel/privacy) với thuộc tính span **trước khi** tạo chuỗi: thuộc tính bị bỏ không bao giờ thành một phần của chuỗi, thuộc tính bị băm thì nhóm theo giá trị băm. Giá trị chỉ nằm trên node của bạn. Cơ sở dữ liệu của Belvador chỉ nhận số đếm và dung lượng mỗi ngày, không bao giờ nhận tên, giá trị hay giá trị thuộc tính.

## Cảnh báo theo metric

Tạo monitor **Metric** ở **Monitor → Tạo monitor**, hoặc bấm **Tạo monitor** trên trang Metrics để mang truy vấn đang xem sang. Monitor tổng hợp một metric trong một cửa sổ (ví dụ *p95 của `http.server.request.duration` trong 5 phút trên 0,8 giây*) và cảnh báo khi vượt trên, dưới hoặc ra ngoài một khoảng. Khi có **nhóm theo**, mỗi bộ giá trị được xét riêng, nên một route chậm cảnh báo mà không kéo theo các route khác. Xem [Monitor theo tín hiệu](https://belvador.dev/vi/docs/monitors/signals#monitor-metric).

## Từ API hoặc AI agent

`GET /v1/metrics/names`, `GET /v1/metrics/series` và `GET /v1/metrics/query` đọc cùng dữ liệu với token có `metrics:read`; tool MCP `query_metrics` liệt kê metric khi không có tên và truy vấn một metric khi có tên. Xem [tham chiếu API](https://belvador.dev/vi/docs/reference/api) và [MCP](https://belvador.dev/vi/docs/mcp).

## Những gì không có

- **Không có metrics từ trình duyệt.** Ingest key là bí mật; web vitals sẽ đến sau qua SDK trình duyệt, không qua OTLP.
- **Không có endpoint Prometheus.** Prometheus và các nguồn khác được [Collector](https://belvador.dev/vi/docs/otel/metrics-recipes#metrics-supabase) đọc rồi chuyển tiếp dạng OTLP.
- **Không lưu dài hạn.** Điểm được giữ theo thời gian lưu của gói ở độ phân giải một phút; không có thu gọn dữ liệu để giữ nhiều năm.
