# Quản lý SLO bằng tệp OpenSLO

> Xuất SLO ra YAML OpenSLO v1, giữ trong Git và nhập lại: các trường được hỗ trợ, annotation của Belvador, kiểm tra trước và lưu cả tệp một lần.

[OpenSLO](https://openslo.com) là định dạng YAML mở cho SLO. Belvador xuất và nhập một phần của **OpenSLO v1**, nên bạn có thể giữ định nghĩa SLO trong Git, duyệt thay đổi qua pull request và tạo lại ở workspace khác.

## Xuất

Mở một SLO và chọn **Xuất OpenSLO**. Tệp trông như sau:

```yaml
apiVersion: openslo/v1
kind: SLO
metadata:
  name: checkout-api-availability
  displayName: "Checkout API khả dụng"
  annotations:
    "belvador.dev/source": uptime
    "belvador.dev/source-ref": "{\"id\":\"<uptime-check-id>\"}"
    "belvador.dev/sli": availability
    "belvador.dev/alert-policy": preset_default
spec:
  budgetingMethod: Timeslices
  timeWindow:
    - duration: 30d
      isRolling: true
  objectives:
    - target: 0.999
```

`metadata.name` là định danh của SLO trong workspace; nhập tệp có cùng tên sẽ cập nhật SLO đó. Nguồn được chọn bằng annotation của Belvador, vì truy vấn metric của OpenSLO mô tả các hệ thống metric mà Belvador không dùng.

## Nhập

Mở **SLO → Nhập OpenSLO** và chọn tệp.

1. **Kiểm tra tệp** đọc mọi tài liệu và liệt kê, với từng SLO, sẽ là **mới** hay **cập nhật** — hoặc mọi vấn đề kèm số thứ tự tài liệu và đường dẫn trường. Chưa có gì được lưu.
2. **Nhập** lưu cả tệp trong một bước. Nếu có bất kỳ SLO nào bị từ chối — ví dụ một check không thuộc workspace này, một nguồn cần **Cho phép nguồn công khai**, hoặc vượt giới hạn gói — thì **không** SLO nào trong tệp được lưu.

Tệp tối đa 64 KB với tối đa 50 SLO. YAML được đọc an toàn: tag tuỳ biến bị từ chối.

SLO đã nhập **do tệp quản lý**: nút **Sửa** bị khoá và trang hiện **Do tệp OpenSLO quản lý**. Hãy sửa tệp rồi nhập lại. Tạm dừng, tắt tiếng và xoá vẫn dùng được trên trang SLO. Nhập tệp có `metadata.name` trùng với một SLO tạo trong Belvador sẽ chuyển SLO đó sang do tệp quản lý.

## Các trường được hỗ trợ

| Trường | Quy tắc |
|---|---|
| `apiVersion` | `openslo/v1` |
| `kind` | `SLO`; tài liệu `Service` trong cùng tệp được chấp nhận và bỏ qua |
| `metadata.name` | bắt buộc; chữ thường, chữ số và `-`, tối đa 63 ký tự, không trùng trong tệp |
| `metadata.displayName` | tên SLO hiển thị trong Belvador (tối đa 120 ký tự); không có thì dùng `metadata.name` |
| `metadata.labels` | được chấp nhận, không dùng |
| `spec.description` | không bắt buộc |
| `spec.service` | được chấp nhận, không dùng |
| `spec.indicator` | `ratioMetric` nội tuyến, không bắt buộc; được chấp nhận, không dùng — annotation nguồn quyết định thứ được đếm |
| `spec.timeWindow` | đúng một cửa sổ trượt: `7d`, `28d` hoặc `30d` |
| `spec.budgetingMethod` | `Timeslices` cho kiểm tra uptime, `Occurrences` cho monitor, heartbeat và span |
| `spec.objectives` | đúng một, với `target` từ 90 % đến 99.99 % viết dạng tỉ lệ (`0.999`) |

## Annotation của Belvador

| Annotation | Giá trị |
|---|---|
| `belvador.dev/source` | `uptime`, `monitor`, `heartbeat` hoặc `spans` |
| `belvador.dev/source-ref` | JSON: `{"id":"<id check hoặc monitor>"}`; monitor có thể thêm `"environment"`; span dùng `{"projectId":7,"service":"api","operation":"GET /api/orders","environment":"production"}` (operation và environment không bắt buộc) |
| `belvador.dev/sli` | `availability` (mặc định) hoặc `latency` |
| `belvador.dev/latency-threshold-ms` | bắt buộc khi dùng `latency`: 1–60000 |
| `belvador.dev/alert-policy` | `preset_default` (mặc định), `page_only`, `ticket_only` hoặc `off` |
| `belvador.dev/allow-public-sources` | `"true"` để đếm dữ liệu gửi bằng khoá công khai |

## Những gì bị từ chối

Belvador không bao giờ âm thầm bỏ một trường. Mọi thứ ngoài phần được hỗ trợ đều bị từ chối với `OPENSLO_UNSUPPORTED_FIELD` kèm đường dẫn trường — ví dụ `spec.indicatorRef`, nhiều objective, `isRolling: false`, cửa sổ theo lịch, `thresholdMetric`, và các tài liệu `AlertPolicy`, `AlertCondition` hay `SLI`. Cảnh báo được đặt bằng annotation `alert-policy` và [quy tắc cảnh báo](https://belvador.dev/vi/docs/slos/alerts).
