Tích hợp Nginx VTS Module với Prometheus và Grafana: Giám sát Traffic Chi Tiết Từng Domain

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

2 giờ sáng, server chậm — và câu hỏi “domain nào đang ngốn bandwidth?”

Mình nhớ rõ cái đêm production bắt đầu timeout. Mở Grafana lên, CPU bình thường, RAM còn trống, disk I/O cũng không có gì lạ. Nhưng response time tăng vọt lên 8 giây. Server lúc đó đang host 5 domain khác nhau trên cùng một Nginx, và không có cách nào biết domain nào đang gây ra vấn đề nếu không ngồi grep từng dòng access log trong tình trạng mắt díp lại.

Bài học từ đêm đó: metrics hệ thống không đủ khi bạn cần phân tích traffic theo từng virtual host. stub_status mặc định của Nginx chỉ cho bạn tổng connection — vô nghĩa trong multi-domain setup. Cần có VTS Module.

Nginx VTS Module là gì?

Nginx Virtual Host Traffic Status (VTS) là third-party module cung cấp metrics chi tiết cho từng server block. Thay vì tổng cộng gộp, bạn thấy breakdown theo domain:

  • Request rate và response time per virtual host
  • Bandwidth in/out từng domain
  • HTTP status code distribution (2xx, 4xx, 5xx) per host
  • Upstream response time nếu dùng Nginx làm reverse proxy

VTS expose metrics theo định dạng Prometheus — kết hợp với Prometheus + Grafana tạo thành stack giám sát Nginx hoàn chỉnh. Trước khi có monitoring đúng nghĩa, mình phải SSH vào từng server kiểm tra — bây giờ chỉ cần mở dashboard là thấy hết. Đặc biệt với multi-domain setup, đây là thứ mình ước biết sớm hơn vài năm.

Thực hành: Cài đặt và cấu hình từ đầu

Bước 1: Compile Nginx với VTS Module

VTS không phải built-in module, cần compile từ source. Kiểm tra version Nginx hiện tại trước:

nginx -v
# nginx version: nginx/1.24.0

Cài dependencies:

sudo apt update
sudo apt install -y build-essential libpcre3-dev zlib1g-dev libssl-dev libgd-dev git

Download source Nginx đúng version và clone VTS:

cd /tmp
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -xzf nginx-1.24.0.tar.gz

git clone https://github.com/vozlt/nginx-module-vts.git

Lấy configure arguments của Nginx đang chạy — quan trọng, phải giữ nguyên các module cũ:

nginx -V 2>&1 | grep "configure arguments"

Compile thêm VTS vào (thêm --add-module vào cuối arguments cũ):

cd /tmp/nginx-1.24.0

./configure \
    --with-compat \
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-http_gzip_static_module \
    --add-module=../nginx-module-vts

make
sudo make install

Nếu Nginx cài từ apt, backup binary cũ rồi replace:

sudo cp /usr/sbin/nginx /usr/sbin/nginx.bak
sudo cp /tmp/nginx-1.24.0/objs/nginx /usr/sbin/nginx

# Xác nhận module đã có
nginx -V 2>&1 | grep vts

Bước 2: Cấu hình Nginx expose VTS metrics

Thêm vào nginx.conf trong http block:

http {
    # Bật VTS — bắt buộc phải có
    vhost_traffic_status_zone;

    # Phân tách metrics theo từng virtual host
    vhost_traffic_status_filter_by_host on;

    server {
        listen 9145;  # Port riêng cho internal metrics
        server_name localhost;

        location /metrics {
            vhost_traffic_status_display;
            vhost_traffic_status_display_format prometheus;

            # Chỉ cho phép Prometheus server và localhost
            allow 127.0.0.1;
            allow 10.0.0.0/8;
            deny all;
        }

        location /nginx_status {
            vhost_traffic_status_display;
            vhost_traffic_status_display_format html;
            allow 127.0.0.1;
            deny all;
        }
    }

    # Virtual hosts bình thường
    server {
        listen 80;
        server_name example.com;
        # ... config bình thường
    }

    server {
        listen 80;
        server_name blog.example.com;
        # ... config bình thường
    }
}

Test và reload:

sudo nginx -t
sudo systemctl reload nginx

# Kiểm tra metrics đã expose chưa
curl http://localhost:9145/metrics | head -20

Output đúng sẽ trông như này:

# HELP nginx_vts_info Nginx info
# TYPE nginx_vts_info gauge
nginx_vts_info{hostname="prod-server-01",version="1.24.0"} 1
# HELP nginx_vts_server_bytes_total The request/response bytes
# TYPE nginx_vts_server_bytes_total counter
nginx_vts_server_bytes_total{host="example.com",direction="in"} 1234567
nginx_vts_server_bytes_total{host="example.com",direction="out"} 9876543
nginx_vts_server_bytes_total{host="blog.example.com",direction="in"} 456789

Thấy metrics chia theo từng host label là đúng. Nếu tất cả gom vào *, kiểm tra lại directive vhost_traffic_status_filter_by_host on.

Bước 3: Cấu hình Prometheus scrape VTS

Thêm job mới vào prometheus.yml:

scrape_configs:
  # ... các job cũ giữ nguyên

  - job_name: 'nginx-vts'
    static_configs:
      - targets: ['prod-server-01:9145']
        labels:
          server: 'prod-server-01'
          env: 'production'
    metrics_path: '/metrics'
    scrape_interval: 15s

Reload Prometheus không cần restart:

curl -X POST http://localhost:9090/-/reload

# Hoặc nếu dùng systemd
sudo systemctl reload prometheus

Vào http://prometheus:9090/targets kiểm tra target nginx-vts phải ở trạng thái UP.

Bước 4: Import Grafana Dashboard

Grafana Dashboard ID 14824 là dashboard phổ biến nhất cho Nginx VTS:

  1. Vào Grafana → Dashboards → Import
  2. Nhập ID: 14824 → Load
  3. Chọn Prometheus datasource → Import

Dashboard cho bạn thấy ngay:

  • Requests/second breakdown theo từng domain
  • Bandwidth in/out real-time
  • HTTP 5xx error rate per host — cái này mình nhìn đầu tiên mỗi khi có alert
  • Upstream response time nếu Nginx đang làm reverse proxy cho app server

Bước 5: Alert khi 5xx spike theo domain

Đây là PromQL để phát hiện domain nào đang có lỗi cao — query mình dùng trong production:

# Tỷ lệ 5xx per domain trong 5 phút (alert khi > 5%)
sum by (host) (
  rate(nginx_vts_server_requests_total{code=~"5.."}[5m])
)
/
sum by (host) (
  rate(nginx_vts_server_requests_total[5m])
) > 0.05

# Hoặc đơn giản hơn — rate tuyệt đối
rate(nginx_vts_server_requests_total{code=~"5.."}[5m]) > 0.5

Thêm vào Grafana Alerting với notification channel là Telegram hoặc email — khi 5xx spike, bạn nhận alert ngay thay vì phát hiện lúc khách hàng gọi điện.

Troubleshoot lỗi hay gặp

Metrics endpoint trả về 404

# Kiểm tra module đã compile vào chưa
nginx -V 2>&1 | grep vts

# Kiểm tra config syntax
sudo nginx -t

# Xem error log nếu vẫn 404
sudo tail -f /var/log/nginx/error.log

Tất cả metrics gom vào host “*”

Thiếu vhost_traffic_status_filter_by_host on; trong http block. Directive này phải đặt ở cấp http, không phải trong server block.

Prometheus không scrape được

# Test từ Prometheus server
curl -v http://prod-server-01:9145/metrics

# Kiểm tra firewall
sudo ufw status
sudo iptables -L INPUT -n | grep 9145

# Mở port nếu cần (chỉ cho Prometheus server)
sudo ufw allow from 10.0.1.50 to any port 9145

Kết luận

Sau cái đêm mò mẫm đó, VTS Module trở thành thứ mình cài đầu tiên mỗi khi setup Nginx server mới chạy multi-domain. Khả năng breakdown traffic theo từng host giúp isolate vấn đề trong vài phút thay vì vài tiếng.

Stack Nginx VTS + Prometheus + Grafana đặc biệt hữu ích khi host nhiều service trên một server, hoặc khi cần chứng minh với khách hàng traffic spike đến từ domain nào. Đây là loại visibility mà nhìn access log không thể cho bạn theo real-time.

Một lưu ý bảo mật: endpoint /metrics tiết lộ thông tin traffic patterns khá nhạy cảm. Luôn restrict bằng IP whitelist và cân nhắc đặt sau VPN nội bộ — không để public ra internet.

Share: