Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 28 — Grafana — Dashboard & Visualization

Đã đọc 0/16 mục · còn khoảng 12 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Mở đầu — vì sao bài này quan trọng

Ở bài trước bạn đã học Prometheus — công cụ chuyên đi thu thập và lưu trữ metrics. Nhưng Prometheus giống như một cái kho dữ liệu khổng lồ: nó có mọi con số bạn cần, nhưng bản thân giao diện của nó (Prometheus Expression Browser) thì thô sơ, chỉ đủ để bạn "gõ query xem thử", chứ không phải nơi để cả team ngồi nhìn hệ thống mỗi ngày. Đây chính là chỗ Grafana bước vào.

Hãy hình dung thế này: Prometheus là cái tủ lạnh chứa nguyên liệu, còn Grafana là cái bàn ăn được bày biện đẹp mắt để mọi người cùng nhìn và ra quyết định. Trong một tổ chức DevOps trưởng thành, gần như mọi thứ liên quan tới "nhìn thấy hệ thống" đều đi qua Grafana: dashboard hiển thị CPU/RAM, biểu đồ số đơn hàng theo phút, cảnh báo khi latency tăng, và cả màn hình lớn treo tường trong phòng vận hành (NOC). Khi một sự cố xảy ra lúc 2 giờ sáng, thứ đầu tiên kỹ sư on-call mở lên thường là một dashboard Grafana.

Điều khiến Grafana đặc biệt quan trọng — và là lý do cả bài này xoay quanh nó — là khả năng multi-source: nó không chỉ đọc từ Prometheus. Bạn có thể cắm Prometheus (metrics), Loki (logs), Tempo/Jaeger (traces), CloudWatch, Elasticsearch, MySQL, PostgreSQL vào cùng một dashboard. Nhờ vậy Grafana trở thành lớp trực quan hóa (visualization layer) thống nhất, đứng trên tất cả các nguồn dữ liệu quan sát của bạn. Học tốt bài này, bạn sẽ biến những con số vô hồn thành câu chuyện mà cả người kỹ thuật lẫn sếp đều hiểu.

Khái niệm cốt lõi

Grafana là gì và không là gì

Grafana không thu thập dữ liệu, không lưu trữ metrics của bạn (ngoài một ít cấu hình nội bộ trong SQLite/MySQL của chính nó). Grafana chỉ làm một việc và làm rất giỏi: truy vấn dữ liệu từ các nguồn khác rồi vẽ ra. Đây là điểm nhiều bạn mới hiểu nhầm — họ tưởng "cài Grafana là có monitoring". Không. Bạn vẫn cần Prometheus (hoặc nguồn khác) làm nơi chứa số liệu; Grafana chỉ là kính hiển vi để nhìn vào kho số đó.

Data Source — trái tim của mô hình multi-source

Mọi thứ trong Grafana bắt đầu từ Data Source (nguồn dữ liệu). Đây là cấu hình kết nối tới nơi chứa dữ liệu: URL của Prometheus, endpoint của Loki, thông tin đăng nhập CloudWatch... Mỗi data source có một "ngôn ngữ truy vấn" riêng:

  • Prometheus dùng PromQL
  • Loki dùng LogQL (rất giống PromQL nhưng cho logs)
  • CloudWatch dùng cú pháp metric của AWS
  • SQL databases (MySQL, PostgreSQL) dùng SQL thuần
Sức mạnh nằm ở chỗ: trong cùng một dashboard, thậm chí cùng một panel, bạn có thể trộn nhiều data source. Ví dụ một panel vẽ latency (từ Prometheus) chồng với sự kiện deploy (từ một bảng MySQL). Đây là thứ Prometheus đơn độc không làm được.

Dashboard, Panel, Query — ba tầng cấu trúc

Cấu trúc của Grafana rất mạch lạc, chia làm ba tầng lồng nhau:

Dashboard là một trang, thường ứng với một hệ thống hoặc một góc nhìn (ví dụ "Payment Service Overview"). Một dashboard chứa nhiều panel.

Panel là một ô hiển thị đơn lẻ — một biểu đồ đường, một con số lớn, một bảng, một gauge. Mỗi panel gắn với một hoặc nhiều query. Grafana có nhiều loại panel:

  • Time series: biểu đồ đường theo thời gian, loại phổ biến nhất
  • Stat: hiển thị một con số lớn (ví dụ "99.95% uptime")
  • Gauge / Bar gauge: đồng hồ đo, tốt cho phần trăm sử dụng
  • Table: bảng, tốt cho danh sách (top 10 endpoint chậm nhất)
  • Heatmap: bản đồ nhiệt, tốt cho phân bố latency
  • Logs: hiển thị dòng log (khi cắm Loki)
Query là câu truy vấn thực tế gửi xuống data source. Ví dụ một panel Time series có thể chạy query PromQL rate(http_requests_total[5m]) để vẽ số request mỗi giây.

Variables — biến để dashboard tái sử dụng được

Đây là tính năng nâng dashboard từ "đồ chơi" lên "công cụ sản xuất". Template variables cho phép bạn tạo ô dropdown ở đầu dashboard, ví dụ chọn $environment (dev/staging/prod) hoặc $service (payment/order/user). Query trong panel dùng biến này: rate(http_requests_total{service="$service"}[5m]). Nhờ vậy, thay vì làm 20 dashboard cho 20 service giống hệt nhau, bạn làm một dashboard và chọn service qua dropdown. Bảo trì cực kỳ nhẹ nhàng.

Alerting — Grafana cũng biết cảnh báo

Từ Grafana 8 trở đi, Grafana có hệ thống Unified Alerting riêng: bạn định nghĩa rule trực tiếp trên query (ví dụ "cảnh báo khi p95 latency > 500ms trong 5 phút"), rồi gửi qua các kênh (contact points) như email, Slack, Telegram, PagerDuty. Lưu ý: chi tiết về triết lý và best practice của alerting sẽ được bàn ở bài riêng — ở đây bạn chỉ cần biết Grafana có sẵn năng lực này, gắn liền với visualization.

Provisioning — dashboard as code

Trong môi trường DevOps nghiêm túc, bạn không click chuột tạo dashboard rồi để đó. Bạn định nghĩa data source và dashboard bằng file YAML/JSON và để Grafana tự nạp khi khởi động (provisioning). Dashboard được lưu dưới dạng JSON, đưa vào Git, review qua pull request như code thật. Đây là tinh thần "everything as code" mà cả khóa học này hướng tới.

Tình huống thực tế

Ví dụ 1 — Tiki và "một dashboard cho tất cả service"

Giả sử đội SRE của một sàn thương mại điện tử lớn ở Việt Nam như Tiki vận hành khoảng 80 microservice. Ban đầu, mỗi team tự tạo dashboard riêng cho service của mình, dẫn tới hơn 300 dashboard rời rạc, mỗi cái một kiểu, không ai nhìn thống nhất được. Khi có sự cố toàn hệ thống, kỹ sư on-call phải mở 10 tab khác nhau.

Giải pháp họ áp dụng là chuẩn hóa bằng một dashboard template dùng variables. Họ tạo một dashboard "Service Golden Signals" với dropdown $service và $environment. Mọi service — vì đều expose metrics theo cùng một chuẩn label — đều hiện đúng trên dashboard này: latency p50/p95/p99, error rate, request rate, saturation. Số dashboard cần bảo trì giảm từ 300 xuống còn khoảng 15 dashboard lõi.

Bài học: đừng nhân bản dashboard. Hãy thiết kế một lần với template variables, và ép các service tuân theo chuẩn đặt tên label chung. Chuẩn hóa metrics ở tầng ứng dụng chính là điều kiện để Grafana phát huy sức mạnh.

Ví dụ 2 — Startup fintech và màn hình NOC treo tường

Một startup fintech ở TP.HCM, khoảng 40 kỹ sư, xử lý thanh toán ví điện tử. Họ treo một TV 55 inch giữa văn phòng, chạy một dashboard Grafana ở chế độ kiosk/playlist (tự động xoay vòng vài dashboard mỗi 30 giây). Dashboard chính hiển thị: số giao dịch thành công mỗi phút (panel Stat cỡ lớn), tỉ lệ giao dịch lỗi (Gauge, chuyển đỏ khi vượt 1%), và biểu đồ latency của cổng thanh toán.

Một lần vào giờ cao điểm trưa, con Gauge tỉ lệ lỗi bất ngờ chuyển từ xanh sang đỏ ở mức 4%. Cả phòng nhìn thấy ngay lập tức mà không cần chờ cảnh báo email. Hóa ra một đối tác ngân hàng bị timeout. Nhờ nhìn thấy sớm, họ chủ động chuyển route sang ngân hàng dự phòng trong vòng 6 phút, tránh được thiệt hại lớn trong giờ vàng.

Bài học: Grafana không chỉ để "điều tra sau sự cố" mà còn tạo văn hóa quan sát chủ động. Một màn hình lớn với vài con số vàng (golden signals) được thiết kế tốt có giá trị hơn hàng chục dashboard rối rắm không ai nhìn.

Ví dụ 3 — Team DevOps trộn metrics và logs trong một màn hình điều tra

Một công ty SaaS ở Singapore phục vụ khách Đông Nam Á dùng Grafana làm màn hình "single pane of glass". Khi API bị chậm, kỹ sư mở một dashboard điều tra có hai vùng: phía trên là panel Time series lấy p99 latency từ Prometheus, phía dưới là panel Logs lấy log lỗi từ Loki, cả hai chia sẻ chung khoảng thời gian và biến $trace_id.

Kỹ sư khoanh vùng đoạn latency tăng vọt trên biểu đồ trên; log tương ứng bên dưới tự lọc theo đúng khung giờ đó và lộ ra hàng loạt lỗi "connection pool exhausted" tới database. Chỉ trong vài phút, từ "biểu đồ chậm" họ đã lần ra "nguyên nhân gốc là hết connection pool" — mà không phải nhảy qua ba công cụ khác nhau.

Bài học: giá trị lớn nhất của Grafana là hợp nhất nhiều nguồn trên một màn hình. Metrics cho bạn biết "có gì đó sai", logs cho bạn biết "sai cái gì". Đặt chúng cạnh nhau trong Grafana rút ngắn thời gian điều tra (MTTR) đáng kể.

Hướng dẫn từng bước

Dưới đây là quy trình dựng một dashboard hữu ích từ đầu, giả định bạn đã có Prometheus chạy sẵn.

Bước 1 — Chạy Grafana. Cách nhanh nhất là Docker:

docker run -d -p 3000:3000 --name grafana grafana/grafana-oss
Mở http://localhost:3000, đăng nhập mặc định admin/admin và đổi mật khẩu ngay.

Bước 2 — Thêm Data Source. Vào Connections → Data sources → Add data source → Prometheus. Điền URL của Prometheus (ví dụ http://prometheus:9090 nếu cùng mạng Docker), bấm Save & test. Thấy chữ xanh "Data source is working" là ổn.

Bước 3 — Tạo Dashboard và Panel đầu tiên. Bấm Dashboards → New → New dashboard → Add visualization, chọn data source Prometheus. Trong ô query, nhập PromQL, ví dụ đo request rate:

sum(rate(http_requests_total[5m])) by (service)
Chọn loại panel Time series ở góc phải, đặt tên panel là "Request Rate per Service", bấm Apply.

Bước 4 — Thêm một panel Stat cho con số quan trọng. Thêm panel mới, dùng query tính tỉ lệ thành công, ví dụ:

sum(rate(http_requests_total{status=~"2.."}[5m])) 
  / sum(rate(http_requests_total[5m])) * 100
Chọn loại Stat, vào tab Thresholds đặt ngưỡng: xanh khi ≥ 99, vàng khi ≥ 95, đỏ khi thấp hơn. Đặt đơn vị là Percent (0-100).

Bước 5 — Thêm Variable để tái sử dụng. Vào Dashboard settings → Variables → Add variable. Chọn type Query, tên service, query lấy danh sách service:

label_values(http_requests_total, service)
Giờ quay lại các panel, sửa query dùng biến: ...{service="$service"}.... Một dropdown chọn service sẽ hiện ở đầu dashboard.

Bước 6 — Lưu và đưa vào Git. Bấm Save dashboard. Sau đó vào Dashboard settings → JSON Model, copy JSON và commit vào repo. Về lâu dài, hãy cấu hình provisioning để Grafana tự nạp file JSON này khi khởi động, biến dashboard thành code được version.

Lỗi thường gặp & mẹo

Lỗi: dùng sai khoảng thời gian trong rate(). Nếu bạn viết rate(metric[5m]) nhưng Prometheus chỉ scrape mỗi 30 giây, bạn vẫn ổn; nhưng nếu viết rate(metric[30s]) với scrape interval 1 phút thì query sẽ trống rỗng vì không đủ điểm dữ liệu. Mẹo: đặt khoảng của rate() ít nhất gấp 4 lần scrape interval.

Lỗi: dashboard nặng, load chậm. Nguyên nhân thường là quá nhiều panel query cùng lúc trên khoảng thời gian dài (30 ngày) với độ phân giải cao. Mẹo: dùng biến $__rate_interval của Grafana thay vì hardcode [5m]; giới hạn số panel mỗi dashboard (khoảng 10–15 là hợp lý); dùng phần "collapse row" để gấp bớt panel ít dùng.

Lỗi: trục Y không có đơn vị, số vô nghĩa. Một panel hiển thị "1073741824" thay vì "1 GB" vì bạn quên đặt Unit. Luôn vào Standard options → Unit đặt đúng đơn vị (bytes, seconds, percent, requests/sec). Đây là chi tiết nhỏ nhưng quyết định dashboard có "đọc được" hay không.

Lỗi: nhầm giữa "no data" và "giá trị 0". Khi một service chết hẳn, metric của nó biến mất và Grafana hiện "No data" — không phải 0. Nhiều người tưởng mọi thứ bình thường vì "không thấy đường đỏ". Mẹo: cấu hình để "No data" cũng kích hoạt cảnh báo, đừng bỏ qua.

Mẹo — đừng tự vẽ lại từ đầu. Grafana có kho dashboard công khai tại grafana.com/dashboards. Với các exporter phổ biến (Node Exporter, MySQL, Nginx, Kubernetes) đã có dashboard chất lượng cao chỉ cần import bằng ID. Bắt đầu từ đó rồi tùy chỉnh sẽ nhanh hơn nhiều.

Mẹo — thiết kế theo "golden signals". Với mỗi service, hãy ưu tiên bốn tín hiệu vàng: Latency, Traffic, Errors, Saturation. Một dashboard sạch với bốn nhóm này hữu ích hơn dashboard nhồi 50 metric linh tinh.

Mẹo — bảo mật. Đừng để mật khẩu admin/admin mặc định; tích hợp Grafana với SSO (Google, GitHub, LDAP) khi triển khai cho team; phân quyền theo Organization và Folder để mỗi team chỉ sửa dashboard của mình.

Bài tập thực hành

  • Dựng môi trường: Chạy Grafana và một Prometheus (có thể dùng Docker Compose gồm Grafana + Prometheus + Node Exporter). Kết nối Prometheus làm data source và xác nhận "working".
  • Import dashboard có sẵn: Vào grafana.com/dashboards tìm dashboard "Node Exporter Full" (ID 1860), import bằng ID, gắn với data source của bạn. Quan sát CPU, RAM, disk của máy.
  • Tự tay dựng dashboard golden signals: Tạo một dashboard mới với ít nhất bốn panel — Request Rate (Time series), Error Rate (Time series), p95 Latency (Time series), Success Rate (Stat có threshold màu). Nếu chưa có ứng dụng thật, dùng metric của chính Prometheus (prometheus_http_requests_total) để tập.
  • Thêm biến: Tạo template variable $instance bằng label_values(up, instance) và sửa các panel để lọc theo instance được chọn. Kiểm tra dropdown hoạt động.
  • Nâng cao — trộn nguồn: Nếu có điều kiện, cài thêm Loki, cắm làm data source thứ hai, và tạo một dashboard điều tra có một panel Time series (Prometheus) phía trên và một panel Logs (Loki) phía dưới chia sẻ chung khung thời gian.
  • As code: Export JSON của dashboard bạn vừa làm, lưu vào một repo Git, và viết vài dòng ghi chú giải thích vì sao "dashboard as code" quan trọng.

Tóm tắt

Grafana là lớp trực quan hóa multi-source đứng trên Prometheus, Loki, Tempo, CloudWatch, Elasticsearch và nhiều nguồn khác — nó không thu thập hay lưu dữ liệu mà chỉ truy vấn rồi vẽ, nhưng làm việc đó xuất sắc và thống nhất. Cấu trúc cốt lõi gồm ba tầng: Data Source → Dashboard → Panel/Query, cùng với Variables để một dashboard phục vụ nhiều service, và khả năng alerting, provisioning để đưa mọi thứ về "as code".

Điều quan trọng nhất rút ra từ ba tình huống thực tế: giá trị của Grafana không nằm ở việc vẽ nhiều biểu đồ, mà ở việc chuẩn hóa cách team nhìn hệ thống (một dashboard template thay vì 300 dashboard rời rạc), tạo văn hóa quan sát chủ động (màn hình NOC treo tường), và rút ngắn thời gian điều tra sự cố bằng cách đặt metrics và logs cạnh nhau. Hãy thiết kế dashboard quanh golden signals, luôn đặt đúng đơn vị, dùng variables, và version dashboard trong Git. Nắm chắc bài này, bạn đã có công cụ để biến kho số liệu vô hồn của Prometheus thành bức tranh mà cả kỹ sư lẫn lãnh đạo đều đọc và hành động được.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi