Xây dựng nền tảng giám sát toàn diện với Prometheus, Grafana và Loki
Trong môi trường vận hành hệ thống hiện đại, việc giám sát (monitoring) chỉ dừng lại ở các chỉ số metric chưa đủ để đảm bảo tính sẵn sàng cao. Một kiến trúc giám sát chuyên nghiệp cần kết hợp chặt chẽ giữa việc thu thập số liệu thống kê từ hệ thống và khả năng truy vết nhật ký (logging) chi tiết. Bài viết này sẽ hướng dẫn bạn xây dựng một hệ thống giám sát tích hợp ba thành phần cốt lõi: Prometheus để thu thập metric, Grafana để trực quan hóa dữ liệu và Loki để lưu trữ, tìm kiếm log, tạo thành một giải pháp giám sát thống nhất, nhẹ nhàng nhưng cực kỳ mạnh mẽ.
Kiến trúc tổng quan và lợi ích của việc tích hợp
Trước khi đi vào chi tiết kỹ thuật, ta cần hiểu rõ vai trò của từng thành phần trong hệ sinh thái này. Prometheus hoạt động như một cơ sở dữ liệu chuỗi thời gian, liên tục kéo (pull) dữ liệu từ các mục tiêu giám sát. Tuy nhiên, khi một cảnh báo kích hoạt, metric chỉ cho ta biết "cái gì" đang sai (ví dụ: CPU 90%), nhưng không cho biết "tại sao" nó sai. Lúc này, Log đóng vai trò then chốt. Loki, được phát triển bởi Grafana Labs, được thiết kế với triết lý khác biệt: nó không lưu trữ dữ liệu dưới dạng các trường đã được phân tích sẵn (như Elasticsearch) mà lưu trữ dưới dạng văn bản thô, chỉ trích xuất các trường khi người dùng cần tìm kiếm. Điều này giúp Loki có chi phí lưu trữ thấp hơn rất nhiều so với các giải pháp truyền thống, đồng thời tận dụng sức mạnh của Grafana để hiển thị cả Metric và Log trên cùng một bảng điều khiển (Dashboard), cho phép kỹ sư chuyển đổi tức thì giữa biểu đồ xu hướng và dòng nhật ký sự cố.
Bước 1: Cấu hình Prometheus để thu thập dữ liệu
Đầu tiên, ta cần khởi tạo Prometheus để nó có thể phát hiện và thu thập metric từ các dịch vụ trong cụm. Việc cấu hình file prometheus.yml là bước quan trọng nhất để xác định phạm vi giám sát. Chúng ta sẽ định nghĩa một job để quét các target có nhãn đặc biệt. Dưới đây là một cấu hình mẫu đơn giản nhưng đầy đủ, bao gồm việc giám sát chính nó (node exporter) và một ứng dụng web giả định.
Trong file cấu hình, ta sử dụng cơ chế static_configs để chỉ định địa chỉ IP của các server cần giám sát. Việc thêm labels là cực kỳ quan trọng vì nó giúp bạn phân nhóm dữ liệu khi truy vấn. Ví dụ, ta có thể đánh nhãn env: production hoặc service: api-gateway để sau này dễ dàng lọc trong Grafana. Hãy lưu ý rằng Prometheus không có cơ chế lưu trữ lâu dài mặc định, do đó cấu hình này chủ yếu tập trung vào việc thu thập dữ liệu thời gian thực để phân tích xu hướng ngắn hạn hoặc làm đầu vào cho các hệ thống lưu trữ lâu dài khác.
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'node_exporter'
static_configs:
- targets: ['192.168.1.10:9100']
labels:
environment: 'production'
node_type: 'server'
- job_name: 'application'
static_configs:
- targets: ['192.168.1.10:8080']
labels:
service: 'backend-api'
environment: 'production'
Sau khi đã cấu hình xong, ta cần khởi động lại Prometheus để áp dụng các thay đổi. Lệnh khởi động cần đảm bảo chỉ định đúng đường dẫn đến file cấu hình vừa tạo.
prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --web.listen-address=0.0.0.0:9090
Tiếp theo, hãy kiểm tra trang quản trị của Prometheus tại địa chỉ http://192.168.1.10:9090/targets để đảm bảo các target đều ở trạng thái UP. Nếu thấy trạng thái DOWN, bạn cần kiểm tra lại firewall hoặc đảm bảo dịch vụ target đang chạy và expose đúng port.
Bước 2: Triển khai Loki và cấu hình nguồn dữ liệu
Sau khi có Prometheus, bước tiếp theo là triển khai Loki để xử lý phần Logging. Khác với Prometheus, Loki không tự động thu thập log từ máy chủ. Thay vào đó, chúng ta cần một tác nhân (agent) để đọc log file từ hệ thống và đẩy về Loki. Tác nhân tiêu chuẩn và phổ biến nhất hiện nay là Promtail. Promtail đóng vai trò như một cầu nối, đọc các file log trên máy chủ, thêm các metadata (như tên host, container name) và gửi chúng về Loki dưới dạng luồng (stream).
Để Promtail hoạt động hiệu quả, ta cần cấu hình file promtail.yml. Trong file này, ta sẽ định nghĩa các job để đọc log từ các file cụ thể, chẳng hạn như /var/log/syslog cho hệ thống hoặc /var/log/nginx/access.log cho web server. Quan trọng hơn, ta cần cấu hình relabel_config để đảm bảo các log này có thể được liên kết với các metric trong Prometheus thông qua các label chung.
scrape_configs:
- job_name: 'system-logs'
static_configs:
- targets:
- localhost
labels:
job: 'varlogs'
__path__: '/var/log/*log'
- job_name: 'application-logs'
static_configs:
- targets:
- localhost
labels:
job: 'app-logs'
__path__: '/var/log/app/*.log'
Để Promtail gửi dữ liệu về đúng instance Loki, ta cần chỉ định địa chỉ endpoint trong phần clients của cấu hình. Hãy nhớ rằng Loki thường chạy trên cổng 3100. Việc cấu hình đúng phần này sẽ đảm bảo dữ liệu log không bị thất lạc trong quá trình truyền tải.
clients:
- url: http://192.168.1.10:3100/loki/api/v1/push
Khi đã triển khai cả Prometheus và Loki (cùng Promtail), hệ thống của bạn đã sẵn sàng dữ liệu. Tuy nhiên, dữ liệu thô chỉ có giá trị khi nó được trình bày dưới dạng trực quan. Đây là lúc Grafana vào cuộc để tổng hợp và làm đẹp các thông tin này.
Bước 3: Tích hợp dữ liệu vào Grafana và tạo Dashboard
Grafana đóng vai trò là lớp giao diện người dùng duy nhất cho toàn bộ hệ thống. Nhiệm vụ của chúng ta là thêm (add) nguồn dữ liệu Prometheus và Loki vào Grafana. Khi đăng nhập vào Grafana, bạn sẽ truy cập vào phần Configuration -> Data Sources. Ở đây, bạn lần lượt tạo một nguồn mới cho Prometheus bằng cách chỉ định URL là địa chỉ endpoint của Prometheus, và một nguồn mới cho Loki tương tự. Điều đặc biệt của việc này là cả hai nguồn đều có thể được gọi và hiển thị trên cùng một trang dashboard.
Sau khi cấu hình xong các Data Source, ta sẽ tạo một Dashboard mới. Trong môi trường production, một dashboard tốt thường bao gồm các panel hiển thị tài nguyên hệ thống (CPU, RAM, Disk I/O) từ Prometheus và các panel hiển thị lỗi (Error logs) từ Loki. Điểm mạnh nhất của sự tích hợp này nằm ở tính năng Unified Querying. Bạn có thể tạo một panel biểu đồ hiển thị lượng Request trên giây (RPS) từ Prometheus, và ngay bên dưới là một panel log từ Loki, nhưng được lọc (filter) chỉ hiển thị các log tương ứng với cùng khoảng thời gian hoặc cùng label của biểu đồ trên.
Để thực hiện điều này, trong biểu thức truy vấn (Query) của Prometheus, bạn sử dụng PromQL. Ví dụ để đếm số request: sum(rate(http_requests_total[5m])). Còn trong phần truy vấn Log của Loki, bạn sử dụng LogQL để lọc các log có chứa từ khóa lỗi, ví dụ: {job="app-logs"} | level="error". Điều này giúp kỹ sư có cái nhìn toàn diện: khi thấy biểu đồ RPS tăng đột biến và đi kèm với việc log lỗi tràn ngập, bạn có thể ngay lập tức xác định nguyên nhân là do một bản phát hành mới gây ra lỗi hoặc do traffic tấn công, thay vì phải lục lọi qua nhiều công cụ khác nhau.
Kết luận và khuyến nghị mở rộng
Việc kết hợp Prometheus, Loki và Grafana tạo nên một "Tam giác vàng" trong giám sát hiện đại, cân bằng giữa hiệu năng, chi phí và khả năng phân tích sâu. Bằng cách sử dụng kiến trúc này, bạn không chỉ đơn thuần là theo dõi hệ thống mà còn tạo ra một nền tảng dữ liệu vững chắc cho các hoạt động DevOps. Để hệ thống hoàn thiện hơn, bạn nên cân nhắc thêm Alertmanager để gửi cảnh báo qua Slack hoặc email khi các chỉ số vượt ngưỡng, và sử dụng các plugin như Grafana OnCall để quản lý ca trực. Hãy bắt đầu triển khai theo các bước trên, từ cấu hình cơ bản đến tùy biến nâng cao, để tối ưu hóa quy trình vận hành của tổ chức.