Sổ tay kỹ thuật

Grafana – biến dashboard, repeat panel và transformations

how-to#grafana#prometheus#influxdb· cập nhật 2026-11-06

Dùng khi cần dropdown chọn thiết bị/interface (biến phụ thuộc nhau), tự nhân panel theo biến và xử lý kết quả query bằng transformations.

Sửa trang này
Mục lục

Tóm tắt: Tạo biến device (query variable lấy giá trị label source), rồi biến interface lọc theo $device (chained variable). Panel dùng $device / $interface trong query; bật Repeat để mỗi thiết bị một panel hoặc một row. Transformations (Reduce, Join, Organize fields...) xử lý dữ liệu sau khi query về, không cần sửa query.

Luồng hoạt động

flowchart LR DS[Datasource] -->|"label_values(..., source)"| V1["Biến device"] V1 -->|"lọc theo $device"| V2["Biến interface"] V1 --> Q["Query panel"] V2 --> Q Q --> T["Transformations"] T --> P["Panel (repeat theo device)"]

Cấu hình

Query variable

Dashboard settings → Variables → New variable → Type Query.

Datasource Biến device Biến interface (phụ thuộc device)
Prometheus label_values(interfaces_in_octets, source) label_values(interfaces_in_octets{source=~"$device"}, name)
InfluxDB (Flux) schema.tagValues(bucket: "telemetry", tag: "source") xem đoạn Flux dưới
ClickHouse SELECT DISTINCT source FROM telemetry.interfaces WHERE time > now() - INTERVAL 1 DAY SELECT DISTINCT name FROM telemetry.interfaces WHERE source IN (${device:singlequote}) AND time > now() - INTERVAL 1 DAY
import "influxdata/influxdb/schema"
 
schema.tagValues(
  bucket: "telemetry",
  tag: "name",
  predicate: (r) => r._measurement == "interfaces" and contains(value: r.source, set: ${device:json}),
  start: -1d,
)

Hàm khác cho Prometheus: label_names(), metrics(interfaces_.*), query_result(topk(10, rate(interfaces_in_octets[5m]))) (kèm Regex để cắt lấy label).

Tuỳ chọn quan trọng của biến:

Tuỳ chọn Ý nghĩa
Refresh = On dashboard load / On time range change Lúc nào chạy lại query lấy danh sách giá trị
Multi-value Cho chọn nhiều giá trị
Include All + Custom all value .* Với Prometheus/Loki, All thành .* thay vì liệt kê hết giá trị (query ngắn hơn)
Regex Lọc/cắt giá trị, ví dụ /^(pe|p)\d+-.*/; nhóm tên (?<text>...) và (?<value>...) tách nhãn hiển thị và giá trị thật
Sort Alphabetical, Numerical...

Biến khác: Custom (liệt kê tay hni,hcm,dng), Constant, Interval (1m,5m,1h), Ad hoc filters (tự thêm điều kiện label cho mọi query Prometheus/Loki).

Dùng biến trong query

sum by (source, name) (rate(interfaces_in_octets{source=~"$device", name=~"$interface"}[$__rate_interval])) * 8

Biến nhiều giá trị phải dùng =~ (Grafana nối thành a|b|c). Định dạng khác theo cú pháp ${var:format}:

Cú pháp Kết quả với pe1, pe2 Dùng cho
${device:regex} pe1|pe2 (escape ký tự regex) PromQL, LogQL
${device:pipe} pe1|pe2 Regex không cần escape
${device:singlequote} 'pe1','pe2' SQL IN (...)
${device:sqlstring} 'pe1','pe2' (escape ') SQL
${device:json} ["pe1","pe2"] Flux contains(set: ...)
${device:csv} pe1,pe2 API, URL
${device:raw} không escape Khi datasource tự xử lý

Biến có sẵn: $__interval, $__rate_interval (Prometheus, nên dùng trong rate()), $__range, $__from / $__to, $__dashboard. ClickHouse/SQL có macro $__timeFilter(cột).

Repeat panel và repeat row

  • Panel: Edit panel → Panel options → Repeat options → Repeat by variable = device, Repeat direction = Horizontal (kèm Max per row) hoặc Vertical. Trong query dùng source="$device": mỗi bản sao nhận một giá trị.
  • Row: thêm row, đặt panel vào row, ở Row options chọn Repeat for = device. Cả row (nhiều panel) được nhân theo từng thiết bị.
  • Biến phải bật Multi-value hoặc Include All, nếu không chỉ có một bản.

Trong JSON model:

{
  "type": "timeseries",
  "title": "Traffic $device",
  "repeat": "device",
  "repeatDirection": "h",
  "maxPerRow": 3
}

Transformations hay dùng

Transformation Dùng để
Reduce (Series to rows) Mỗi series thành một dòng Max/Mean/Last, làm bảng tổng hợp interface
Labels to fields Đưa label source, name thành cột của bảng
Join by field (OUTER/INNER) Ghép kết quả nhiều query theo cột chung, ví dụ bps vào và bps ra
Organize fields by name Ẩn, đổi tên, sắp xếp lại cột
Rename fields by regex Rút gọn tên series dài
Filter data by values Chỉ giữ dòng thoả điều kiện (bps > 0)
Add field from calculation Tính cột mới (Binary operation: in + out)
Sort by / Limit Top-N phía Grafana
Config from query results Lấy ngưỡng/max từ một query khác (vd speed interface)

Transformations chạy trong trình duyệt: dữ liệu lớn thì nên tính ở query (topk, GROUP BY) thay vì dồn về Grafana.

Lỗi thường gặp

Triệu chứng Nguyên nhân Cách xử lý
Dropdown rỗng Query variable sai, hoặc time range của biến không có dữ liệu Bấm Run query trong trang biến xem preview; kiểm tra tên metric/label
Chọn nhiều giá trị thì query lỗi Dùng = với biến multi-value Dùng =~"$device", SQL dùng IN (${device:singlequote})
Biến interface không đổi khi đổi device Query con không tham chiếu $device Thêm $device vào query; Grafana chỉ chạy lại biến phụ thuộc
All làm query rất dài, chậm Không đặt Custom all value Đặt .* (PromQL/LogQL)
Repeat chỉ ra một panel Biến không Multi-value / không chọn All Bật Multi-value, chọn nhiều giá trị
Import dashboard sang Grafana khác báo datasource not found Query gán cứng uid datasource của môi trường cũ Dùng biến kiểu Data source hoặc cố định uid, xem Grafana provisioning
Flux báo lỗi kiểu ở contains(set: ...) Biến không bật Multi-value nên ${device:json} ra chuỗi, không phải mảng Bật Multi-value, hoặc dùng r.source == "${device}"

Tham khảo