Hướng dẫn giám sát Windows Server với Prometheus và Windows Exporter: Theo dõi CPU, RAM và Services chi tiết

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

Tại sao cần setup riêng cho Windows Server?

Nếu bạn đã đọc bài cài Prometheus + Grafana trên blog này, phần lớn hướng dẫn xoay quanh Linux với node_exporter. Windows Server là câu chuyện khác — file system khác, service management khác, và quan trọng nhất là Windows Services cần theo dõi riêng biệt.

Mình từng có server Windows chạy IIS bị treo dịch vụ lúc 3 giờ sáng. Không ai biết cho đến khi khách hàng gọi điện. Sau lần đó mới nghiêm túc ngồi setup monitoring cho Windows. Bài này tập trung đúng vào vấn đề đó: CPU, RAM, disk và trạng thái Services — không lan man.

Có những lựa chọn nào để giám sát Windows?

Trước khi cài bất cứ thứ gì, nên biết mình đang có những option nào:

1. Windows Exporter (cho Prometheus)

Fork từ wmi_exporter cũ, hiện là project chính thức của Prometheus community. Export metrics qua HTTP endpoint, Prometheus scrape định kỳ. Chạy như một Windows Service nền, footprint nhỏ — chỉ khoảng 15–20MB RAM.

2. Telegraf + InfluxDB

Agent đa năng của InfluxData, có plugin win_perf_counters dùng Windows Performance Counters gốc. Hỗ trợ Windows tốt, nhưng nặng hơn (~50MB RAM), cần config nhiều hơn và phải thêm InfluxDB hoặc forward về Prometheus qua output plugin.

3. Zabbix Agent

Zabbix có agent Windows riêng với template sẵn khá đầy đủ. Nhưng nếu bạn đang dùng Prometheus làm backend chính, thêm Zabbix vào là phức tạp không cần thiết — hai ecosystem song song, hai chỗ cần maintain.

4. SNMP / WMI trực tiếp

Pull metrics từ Prometheus mà không cài agent. Nghe có vẻ gọn, nhưng latency cao, cấu hình phức tạp và không đủ chi tiết cho application-level monitoring. Thường chỉ dùng cho thiết bị mạng không thể cài agent.

So sánh nhanh

Approach Ưu điểm Nhược điểm
Windows Exporter Native Prometheus, nhẹ (~15MB RAM), metrics phong phú Cần Prometheus sẵn
Telegraf Đa năng, nhiều output plugin Nặng hơn (~50MB), cần config nhiều
Zabbix Agent Template phong phú, UI đẹp Ecosystem riêng, không dùng chung Prometheus
SNMP/WMI Không cần cài agent Latency cao, thiếu chi tiết app-level

Vậy chọn cái nào?

Đang dùng Prometheus + Grafana cho Linux servers? Câu trả lời hầu như luôn là Windows Exporter. Cùng scrape config, cùng Alertmanager, cùng Grafana — chỉ thêm một target mới. Không học thêm stack nào.

Ngoại lệ duy nhất: bạn đang có Zabbix sẵn và Windows Server chỉ là thiểu số → dùng Zabbix Agent cho đồng nhất. Còn lại, bài này đi thẳng vào Windows Exporter.

Hướng dẫn triển khai

Bước 1: Cài đặt Windows Exporter trên Windows Server

Tải bản MSI mới nhất từ GitHub releases của prometheus-community/windows_exporter. Thời điểm viết bài là v0.29.2.

Cài qua PowerShell với quyền Administrator:

# Tải MSI
$version = "0.29.2"
$url = "https://github.com/prometheus-community/windows_exporter/releases/download/v$version/windows_exporter-$version-amd64.msi"
Invoke-WebRequest -Uri $url -OutFile "windows_exporter.msi"

# Cài với collectors cần thiết
msiexec /i windows_exporter.msi `
  ENABLED_COLLECTORS="cpu,memory,logical_disk,net,os,service,system" `
  LISTEN_PORT="9182" /quiet

Cũng có thể cài thủ công qua GUI, chọn port 9182 (default). Sau khi cài xong, Windows Service tên windows_exporter sẽ tự start.

Kiểm tra service đang chạy:

Get-Service windows_exporter
# Status phải là Running

Test metrics endpoint ngay từ server đó:

Invoke-WebRequest -Uri http://localhost:9182/metrics | Select-Object -ExpandProperty Content | Select-String "windows_cpu"

Bước 2: Mở firewall cho Prometheus scrape

New-NetFirewallRule `
  -DisplayName "Windows Exporter" `
  -Direction Inbound `
  -Protocol TCP `
  -LocalPort 9182 `
  -Action Allow

Tốt hơn là giới hạn rule chỉ cho IP của Prometheus server thay vì mở toàn bộ — một dòng thêm -RemoteAddress 192.168.1.50 là đủ.

Bước 3: Thêm target vào Prometheus

Trên Prometheus server (Linux), chỉnh prometheus.yml:

scrape_configs:
  # ... các job Linux hiện có ...

  - job_name: 'windows_servers'
    static_configs:
      - targets:
          - '192.168.1.100:9182'   # Windows Server 1
          - '192.168.1.101:9182'   # Windows Server 2
        labels:
          env: 'production'
          os: 'windows'

Reload Prometheus để áp dụng:

curl -X POST http://localhost:9090/-/reload
# hoặc
systemctl reload prometheus

Vào Prometheus UI → Status → Targets, target windows_servers phải hiện state UP. Nếu thấy DOWN, kiểm tra firewall trước — 9 trong 10 trường hợp là do đó.

Bước 4: Import Grafana Dashboard

Dashboard ID 14694 (Windows Exporter Node) là lựa chọn phổ biến nhất trong community. Import vào Grafana:

  1. Grafana → Dashboards → Import
  2. Nhập ID 14694 → Load
  3. Chọn Prometheus datasource → Import

Dashboard có sẵn panel cho CPU usage, RAM, disk I/O, network throughput. Điều chỉnh variable instance để chọn đúng server cần xem. Nếu có nhiều server, biến này hiện dạng dropdown — khá tiện.

Bước 5: Theo dõi Windows Services cụ thể

Đây là điểm khác biệt lớn nhất so với Linux monitoring. Metric cần dùng là windows_service_state:

# Kiểm tra service có đang running không (1 = running)
windows_service_state{state="running", name="W3SVC"}       # IIS
windows_service_state{state="running", name="MSSQLSERVER"}  # SQL Server
windows_service_state{state="running", name="wuauserv"}     # Windows Update

# Alert khi service bị stop bất ngờ — cách đơn giản, hiệu quả
windows_service_state{name=~"W3SVC|MSSQLSERVER|SQLSERVERAGENT", state="running"} == 0

Thêm panel với query trên vào Grafana, dùng visualization dạng Stat hoặc Table để nhìn trực quan trạng thái từng service một.

Alert Rules thực chiến

Phần này mình tốn thời gian nhất lúc đầu. Alert fatigue không phải khái niệm trừu tượng — mình đã sống qua nó: setup xong, alert bắn liên tục lúc 2 giờ sáng vì threshold không phù hợp workload thực tế. Tắt đi bỏ qua, mất niềm tin vào cả hệ thống. Phải tune đi tune lại nhiều lần mới ổn.

File windows_alerts.yml mình đang dùng:

groups:
  - name: windows_server
    rules:
      # CPU cao liên tục 10 phút — spike ngắn thì bình thường, đừng alert
      - alert: WindowsCPUHigh
        expr: |
          100 - (avg by (instance) (
            rate(windows_cpu_time_total{mode="idle"}[5m])
          ) * 100) > 85
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "CPU cao trên {{ $labels.instance }}"
          description: "CPU usage {{ $value | printf \"%.1f\" }}% trong 10 phút"

      # RAM còn lại dưới 500MB (absolute, không phải %)
      - alert: WindowsLowMemory
        expr: windows_os_physical_memory_free_bytes < 500 * 1024 * 1024
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "RAM thấp trên {{ $labels.instance }}"
          description: "Chỉ còn {{ $value | humanize1024 }}B RAM trống"

      # Disk dưới 10%
      - alert: WindowsDiskLow
        expr: |
          (windows_logical_disk_free_bytes{volume!~"HarddiskVolume.*"}
          / windows_logical_disk_size_bytes) * 100 < 10
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Disk thấp {{ $labels.volume }} trên {{ $labels.instance }}"

      # Service quan trọng bị stop
      - alert: WindowsServiceDown
        expr: |
          windows_service_state{
            name=~"W3SVC|MSSQLSERVER|SQLSERVERAGENT",
            state="running"
          } == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Service {{ $labels.name }} đang dừng trên {{ $labels.instance }}"

Load rule vào Prometheus bằng cách thêm vào prometheus.yml:

rule_files:
  - "/etc/prometheus/rules/windows_alerts.yml"

Mấy điều rút ra sau khi bị alert đánh thức lúc đêm

Kinh nghiệm xương máu, không phải lý thuyết:

  • Dùng for: 10m, không trigger ngay — CPU spike 1 phút là bình thường khi backup chạy hoặc Windows Update. CPU cao 10 phút liên tục mới đáng lo.
  • Bắt đầu với severity warning, không critical — critical chỉ dùng khi thực sự cần thức dậy lúc 3 giờ sáng để fix.
  • Theo dõi 1–2 tuần trước khi bật Alertmanager — xem pattern thực tế của server, đặt threshold dựa trên số thực, không đặt theo cảm tính.
  • Alert theo tên service cụ thể, không alert tất cả stopped services — Windows có hàng chục service không cần running liên tục, alert hết là loạn ngay.

Kiểm tra toàn bộ pipeline

# Từ Prometheus server, test kết nối thủ công
curl http://192.168.1.100:9182/metrics | grep -E "windows_(cpu|memory|service)"

# Query này phải trả về kết quả trong Prometheus UI:
# windows_os_physical_memory_free_bytes{instance="192.168.1.100:9182"}

Metrics xuất hiện trong Prometheus, dashboard Grafana load được data — pipeline đã thông. Từ đây việc còn lại là tune alert threshold cho phù hợp với từng server cụ thể.

Share: