Graylog: Tập Trung Hóa và Phân Tích Log Từ Nhiều Server Linux

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

Quản lý log khi hệ thống lớn dần: Vấn đề không ai muốn nhưng ai cũng gặp

Hồi mới setup 2–3 server, mình vẫn SSH thẳng vào từng máy rồi tail -f /var/log/syslog để debug. Cách đó ổn — cho đến khi số server tăng lên 8, rồi 15. Khi production bị lỗi lúc 2 giờ sáng và bạn phải SSH vào từng machine để tìm error message, đó là lúc bạn thật sự cần centralized logging.

Graylog là thứ mình đưa vào production sau khi đã “đau” đủ rồi. Sau 6 tháng chạy thực tế, mình viết lại những gì thực sự hữu ích — không phải copy từ tài liệu chính thức.

Graylog là gì và tại sao không dùng ELK Stack?

Nói thẳng: Graylog nhận log từ mọi server, index tất cả vào OpenSearch, rồi cho bạn search và tạo alert từ một UI duy nhất. Không còn cảnh mở 10 terminal tab để grep trên từng máy nữa.

Kiến trúc gồm 3 thành phần chính:

  • Graylog Server: xử lý, parse, route log
  • MongoDB: lưu metadata — cấu hình, user, stream, alert
  • OpenSearch (hoặc Elasticsearch): full-text search engine — nơi log thực sự được lưu và query

ELK Stack thì sao? Mình đã chạy thử cả hai. ELK mạnh hơn về customization, nhưng mất khoảng 2–3 ngày để setup đúng cách. Graylog thì nửa buổi là xong. Với team nhỏ không có DevOps chuyên biệt, đó là sự khác biệt đáng kể — nhất là phần alert và stream management, Graylog thắng rõ ràng.

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

Docker Compose là cách nhanh nhất để chạy Graylog. Mình dùng cách này cả trong dev lẫn small production — ổn định với workload dưới 50GB log/ngày.

Tạo file docker-compose.yml:

version: '3.8'
services:
  mongodb:
    image: mongo:6.0
    volumes:
      - mongodb_data:/data/db
    restart: unless-stopped

  opensearch:
    image: opensearchproject/opensearch:2.11.0
    environment:
      - discovery.type=single-node
      - DISABLE_SECURITY_PLUGIN=true
      - OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - opensearch_data:/usr/share/opensearch/data
    restart: unless-stopped

  graylog:
    image: graylog/graylog:5.2
    environment:
      - GRAYLOG_PASSWORD_SECRET=somepasswordpepper1234567890abc
      - GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      - GRAYLOG_HTTP_EXTERNAL_URI=http://YOUR_SERVER_IP:9000/
      - GRAYLOG_ELASTICSEARCH_HOSTS=http://opensearch:9200
      - GRAYLOG_MONGODB_URI=mongodb://mongodb:27017/graylog
    depends_on:
      - mongodb
      - opensearch
    ports:
      - "9000:9000"        # Web UI
      - "12201:12201/udp"  # GELF UDP input
      - "514:514/udp"      # Syslog UDP input
    volumes:
      - graylog_data:/usr/share/graylog/data
    restart: unless-stopped

volumes:
  mongodb_data:
  opensearch_data:
  graylog_data:

Quan trọng: GRAYLOG_ROOT_PASSWORD_SHA2 ở trên là hash của chuỗi “admin”. Đổi ngay trước khi deploy thật:

echo -n "your_strong_password" | sha256sum | cut -d' ' -f1

Khởi động stack:

docker compose up -d
# Chờ khoảng 60–90 giây để Graylog khởi động hoàn toàn
docker compose logs -f graylog

Web UI chạy tại http://YOUR_SERVER_IP:9000. Đăng nhập với admin và password vừa tạo.

Tạo Input để nhận log

Mở System → Inputs trên Web UI. Tạo 2 input này trước:

1. Syslog UDP (port 514)

Chọn Syslog UDP, bind address 0.0.0.0, port 514. Input này nhận log từ rsyslog trực tiếp — nhanh, đơn giản, không cần cài agent thêm.

2. GELF UDP (port 12201)

Chọn GELF UDP, port 12201. GELF (Graylog Extended Log Format) là format JSON có cấu trúc — hỗ trợ custom fields, phù hợp với application log từ Docker containers hoặc app tự viết.

Cấu hình rsyslog trên server client

Trên mỗi server Linux cần gửi log về Graylog, cấu hình rsyslog:

sudo nano /etc/rsyslog.d/90-graylog.conf

Thêm vào file một dòng duy nhất:

# Gửi tất cả log qua UDP đến Graylog
*.* @GRAYLOG_SERVER_IP:514;RSYSLOG_SyslogProtocol23Format

Restart rsyslog rồi test ngay:

sudo systemctl restart rsyslog

# Gửi test message
logger -t test "Hello from $(hostname)"

Mở Graylog Web UI → Search, tìm source:hostname_cua_ban — thấy message “Hello from…” là xong.

Gửi log Docker container qua GELF

Với Docker, thêm log driver vào docker-compose.yml của service cần monitor:

services:
  my_app:
    image: my_app:latest
    logging:
      driver: gelf
      options:
        gelf-address: "udp://GRAYLOG_SERVER_IP:12201"
        tag: "my_app"

Tạo Stream và Alert

Stream là tính năng mình thích nhất của Graylog. Nó route log theo rule vào các “kênh” riêng — stream riêng cho Nginx, cho SSH auth, cho application errors. Cực kỳ tiện khi cần debug theo từng service mà không bị ngập trong log chung.

Tạo stream tại Streams → Create Stream. Một số rule hữu dụng:

  • Field source contains webserver-01 — lọc log từ 1 server cụ thể
  • Field message matches regex ERROR|CRITICAL|FATAL — bắt tất cả error
  • Field facility equals auth — chỉ lấy auth log (SSH, sudo)

Xong stream rồi thì thêm Alert Condition. Ví dụ: “gửi notification nếu có hơn 10 ERROR message trong 5 phút”. Kết hợp với Notification gửi về Slack, email, hoặc webhook — tuỳ bạn.

Thật ra mình phải thừa nhận: alert fatigue là vấn đề thực tế mình gặp ngay từ đầu. Set threshold quá thấp — alert bắn liên tục, rồi bắt đầu ignore hết. Phải tune lại nhiều lần: tăng threshold, thêm điều kiện AND, whitelist một số source nhất định. Kinh nghiệm rút ra: bắt đầu với threshold cao, quan sát 1–2 tuần để nắm baseline của hệ thống, rồi dần điều chỉnh xuống. Production của bạn có traffic pattern riêng — đừng copy số liệu từ blog nào.

Kết luận sau 6 tháng chạy thực tế

Graylog giải quyết bài toán “log ở đâu” một cách thực sự hiệu quả. Những gì mình ghi nhận sau nửa năm:

  • Thời gian debug incident giảm từ ~30 phút xuống ~5 phút vì có thể search cross-server trong 1 UI
  • Phát hiện được 2 lần brute-force SSH nhờ alert trên failed auth logs
  • Retention policy (tự xóa log cũ hơn 30 ngày) giữ disk usage ổn định — không lo bị đầy disk đột ngột

Một điểm cần biết trước: Graylog khá ngốn RAM. Cụm 1 node của mình cần tối thiểu 8GB để chạy ổn — riêng OpenSearch đã chiếm 2–4GB. Server nhỏ hơn thì xem xét Grafana Loki: nhẹ hơn nhiều, search kém hơn một chút, nhưng đủ dùng cho hầu hết trường hợp.

Còn nếu bạn có ngân sách và quản lý 20+ server — Graylog vẫn là lựa chọn đáng tin. Setup một lần, dùng lâu dài. Lần sau debug lúc 2 giờ sáng sẽ bớt khổ hơn nhiều.

Share: