Gatus: Giám sát endpoint, website và API tự động với Status Page và cảnh báo Telegram

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

Vấn đề với monitoring truyền thống

Prometheus + Grafana rất mạnh cho metrics server, nhưng khi chỉ cần biết “website có đang lên không?” hay “API có trả về 200 không?” — dựng cả một stack như vậy là quá tốn công. Trước khi dùng Gatus, mình SSH vào từng server kiểm tra thủ công. Bây giờ mở dashboard là thấy hết — trạng thái từng endpoint, lịch sử uptime, response time.

Gatus giải quyết đúng một bài toán: health check endpoint đơn giản, có Status Page đẹp, gửi cảnh báo Telegram khi có sự cố. Không cần database, không cần agent cài trên server, toàn bộ cấu hình là một file YAML.

Gatus là gì và tại sao chọn nó?

Về mặt kỹ thuật, Gatus là một binary Go duy nhất — deploy xong là chạy ngay, không cần runtime hay dependency nào thêm. Footprint cực nhẹ: RAM tiêu thụ thường dưới 20MB, startup dưới 1 giây. Tool hỗ trợ bốn loại check:

  • HTTP/HTTPS — kiểm tra status code, body, response time
  • TCP — kiểm tra port có mở không (database, Redis, v.v.)
  • DNS — kiểm tra domain có resolve đúng không
  • ICMP (ping) — kiểm tra host có reachable không

So với Zabbix hay Netdata, Gatus không giám sát CPU/RAM/disk — đó là việc của các tool khác. Gatus tập trung hoàn toàn vào “dịch vụ này có hoạt động đúng không?” — một góc nhìn bổ sung, không thay thế, cho hệ thống monitoring đã có.

Thứ mình thích nhất ở Gatus: Status Page tích hợp sẵn, không cần cài thêm plugin hay dịch vụ nào. Khách hàng hỏi “website bị gì vậy?” — share link status page là xong, không phải giải thích dài dòng qua chat.

Cài đặt Gatus bằng Docker Compose

Docker là cách nhanh nhất để bắt đầu. Tạo thư mục làm việc:

mkdir -p ~/gatus && cd ~/gatus
touch config.yaml docker-compose.yml

Nội dung file docker-compose.yml:

version: "3.8"
services:
  gatus:
    image: twinproduction/gatus:stable
    container_name: gatus
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - ./config.yaml:/config/config.yaml
    environment:
      - GATUS_CONFIG_PATH=/config/config.yaml

Khởi động container:

docker compose up -d
docker compose logs -f gatus

Nếu không dùng Docker, build từ source cũng được:

git clone https://github.com/TwiN/gatus.git
cd gatus
go build -o gatus .
./gatus --config config.yaml

Cấu hình chi tiết

Cấu trúc cơ bản của config.yaml

web:
  port: 8080
  # Tùy chọn: đặt base-path nếu dùng reverse proxy subdirectory
  # base-path: /status

storage:
  type: sqlite          # Lưu lịch sử uptime vào SQLite (thư mục /data)
  path: /data/gatus.db

alerting:
  telegram:
    token: "1234567890:ABCdef..."  # Bot token từ @BotFather
    id: "-100123456789"            # Chat ID (group dùng số âm)
    default-alert:
      enabled: true
      failure-threshold: 3         # Cảnh báo sau 3 lần check liên tiếp thất bại
      success-threshold: 2         # Thông báo recovered sau 2 lần check thành công
      send-on-resolved: true       # Gửi tin khi dịch vụ phục hồi

endpoints:
  - name: "Website itfromzero.com"
    url: "https://itfromzero.com"
    interval: 5m
    conditions:
      - "[STATUS] == 200"
      - "[RESPONSE_TIME] < 3000"   # Response time < 3 giây
    alerts:
      - type: telegram

Giám sát nhiều loại endpoint

endpoints:
  # HTTP endpoint với kiểm tra body
  - name: "API Health Check"
    url: "https://api.example.com/health"
    interval: 2m
    conditions:
      - "[STATUS] == 200"
      - "[BODY] == {\"status\":\"ok\"}"   # Body phải chứa JSON này
      - "[RESPONSE_TIME] < 1000"
    alerts:
      - type: telegram
        failure-threshold: 2          # Override: cảnh báo sau 2 lần thất bại

  # TCP — kiểm tra port database
  - name: "PostgreSQL Port"
    url: "tcp://db.internal:5432"
    interval: 1m
    conditions:
      - "[CONNECTED] == true"
    alerts:
      - type: telegram

  # TCP — Redis
  - name: "Redis Cache"
    url: "tcp://redis.internal:6379"
    interval: 1m
    conditions:
      - "[CONNECTED] == true"
    alerts:
      - type: telegram

  # DNS check — domain resolve đúng IP không
  - name: "DNS itfromzero.com"
    url: "dns://1.1.1.1"
    dns:
      query-name: "itfromzero.com"
      query-type: "A"
    interval: 10m
    conditions:
      - "[DNS_RCODE] == NOERROR"

  # ICMP ping — server có reachable không
  - name: "VPS Singapore"
    url: "icmp://103.x.x.x"
    interval: 5m
    conditions:
      - "[CONNECTED] == true"

Lấy Bot Token và Chat ID cho Telegram

Vào Telegram, nhắn tin cho @BotFather — gõ /newbot, đặt tên bot, rồi lưu lại token dạng 1234567890:ABCdef... mà BotFather trả về.

Để lấy Chat ID của group hoặc kênh:

# Thêm bot vào group, sau đó gọi API:
curl "https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates"
# Tìm "chat":{"id":-100xxxxxxxxx} trong response

Dùng biến môi trường cho thông tin nhạy cảm

Không nên hardcode token trong config. Gatus hỗ trợ env variable theo cú pháp ${VAR_NAME}:

alerting:
  telegram:
    token: "${TELEGRAM_BOT_TOKEN}"
    id: "${TELEGRAM_CHAT_ID}"

Cập nhật docker-compose.yml để truyền biến:

services:
  gatus:
    image: twinproduction/gatus:stable
    container_name: gatus
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - ./config.yaml:/config/config.yaml
      - gatus_data:/data
    env_file:
      - .env

volumes:
  gatus_data:

File .env:

TELEGRAM_BOT_TOKEN=1234567890:ABCdef...
TELEGRAM_CHAT_ID=-100123456789

Kiểm tra và sử dụng Monitoring Dashboard

Truy cập Status Page

Gatus chạy xong, mở http://your-server-ip:8080 là thấy ngay dashboard. Mỗi endpoint hiển thị trạng thái hiện tại (xanh/đỏ), response time trung bình, và uptime 7 ngày cùng 24 giờ gần nhất theo dạng block timeline — nhìn là biết ngay có vấn đề gì không.

Nếu muốn expose ra internet qua Nginx:

server {
    listen 80;
    server_name status.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Kiểm tra cảnh báo Telegram hoạt động

Thêm một endpoint test với điều kiện chắc chắn thất bại, sau đó xóa đi:

endpoints:
  - name: "Test Alert"
    url: "https://httpstat.us/503"   # Luôn trả về 503
    interval: 30s
    conditions:
      - "[STATUS] == 200"            # Sẽ fail
    alerts:
      - type: telegram
        failure-threshold: 1          # Cảnh báo ngay lần đầu

Restart Gatus và đợi 30 giây — nếu cấu hình đúng, Telegram sẽ nhận được tin nhắn cảnh báo với thông tin endpoint và lý do thất bại.

Xem log và debug

# Xem log realtime
docker compose logs -f gatus

# Kiểm tra config có parse đúng không
docker compose exec gatus cat /config/config.yaml

# Restart sau khi sửa config
docker compose restart gatus

Vài lưu ý thực tế khi vận hành

  • failure-threshold nên đặt >= 2 để tránh cảnh báo nhầm do network hiccup tạm thời
  • Endpoint production quan trọng thì interval: 1m; endpoint ít quan trọng hơn thì 5m là đủ — tránh tạo quá nhiều request không cần thiết
  • Mount volume /data ra ngoài để lịch sử uptime không mất khi restart container
  • Nếu Gatus chạy trên cùng server với service cần monitor, thêm external check từ server khác để tránh false positive khi cả server down

Với setup này, mình không còn phải lo ngại việc website down mà không hay biết. Toàn bộ monitoring endpoint chỉ tốn một file YAML và một container — đơn giản hơn nhiều so với việc dựng Prometheus exporter cho từng dịch vụ.

Share: