Vector: Giải pháp thu thập log Docker ‘siêu nhẹ’ thay thế Logstash

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Tại sao bạn nên ngừng dùng Logstash hoặc Fluentd?

Nếu đang vận hành microservices, chắc hẳn bạn đã từng đau đầu khi Logstash ngốn tới 1GB RAM chỉ để chuyển tiếp vài dòng log. Trước đây, bộ ba ELK (Elasticsearch – Logstash – Kibana) là tiêu chuẩn. Tuy nhiên, Logstash chạy trên JVM rất nặng nề. Fluentd khá hơn nhưng vẫn dựa trên Ruby, dễ gây nghẽn cổ chai khi dữ liệu (throughput) tăng đột biến.

Mình từng gặp ca khó: VPS 4GB RAM đang chạy mượt 4 microservices thì “đứng hình” vì Logstash. Chỉ cần cài thêm nó để đẩy log, RAM lập tức vọt lên 90%. Hệ thống bắt đầu giật lag liên tục. Đó là lúc mình tìm đến Vector và thực sự bị thuyết phục.

Vector được viết bằng Rust, nổi tiếng với khả năng xử lý hàng chục nghìn event mỗi giây mà chỉ tốn khoảng 20-30MB RAM. Con số này thấp hơn 10-20 lần so với Logstash. Từ khi chuyển sang Vector trên Docker Compose v2, chi phí duy trì VPS của mình giảm đáng kể nhờ không cần nâng cấp RAM chỉ để chứa log agent.

Triển khai Vector để “gom” log Docker

Chúng ta sẽ setup một mô hình thực tế: Vector chạy dưới dạng container, “nghe” log từ Docker Socket và xuất ra console. Toàn bộ quá trình này dựa trên Docker Compose v2 – tiêu chuẩn hiện đại nhất.

Bước 1: Khởi tạo file cấu hình

Vector điều khiển mọi thứ qua file vector.yaml. Hãy tạo thư mục dự án và file cấu hình bằng lệnh sau:

mkdir vector-docker-logs && cd vector-docker-logs
touch vector.yaml

Dưới đây là cấu hình tối giản để Vector bắt đầu thu thập dữ liệu:

# vector.yaml
sources:
  docker_logs:
    type: "docker_logs"

sinks:
  out:
    type: "console"
    inputs:
      - "docker_logs"
    encoding:
      codec: "json"

Bước 2: Thiết lập Docker Compose

File docker-compose.yml sẽ định nghĩa Vector và một ứng dụng Nginx để tạo log mẫu. Lưu ý phiên bản image distroless để tối ưu bảo mật và dung lượng.

# docker-compose.yml
services:
  vector:
    image: timberio/vector:0.34.1-distroless-static
    container_name: vector
    volumes:
      - ./vector.yaml:/etc/vector/vector.yaml:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      - "8686:8686"

  app-nginx:
    image: nginx:latest
    container_name: demo-nginx
    ports:
      - "8080:80"

Kinh nghiệm xương máu: Đừng quên mount /var/run/docker.sock. Nếu thiếu dòng này, Vector sẽ bị “mù” hoàn toàn vì không thể giao tiếp với Docker Daemon để lấy dữ liệu từ các container khác.

Xử lý log chuyên nghiệp với VRL

Log thô từ Docker thường chứa nhiều thông tin thừa. Sức mạnh thực sự của Vector nằm ở VRL (Vector Remap Language), giúp bạn lọc và biến đổi dữ liệu theo thời gian thực.

Lọc và định dạng lại dữ liệu

Giả sử bạn chỉ muốn giữ lại log của container có tên chứa chữ “demo” và gắn thêm nhãn môi trường. Hãy cập nhật vector.yaml:

sources:
  docker_logs:
    type: "docker_logs"

transforms:
  # Chỉ lấy log từ container demo-nginx
  filter_nginx:
    type: "filter"
    inputs:
      - "docker_logs"
    condition: | 
      includes(string!(.container_name), "demo-nginx")

  # Thêm thông tin định danh
  parse_logs:
    type: "remap"
    inputs:
      - "filter_nginx"
    source: |
      .env = "production"
      .processed_at = now()
      .message = upcase(string!(.message))

sinks:
  stdout:
    type: "console"
    inputs:
      - "parse_logs"
    encoding:
      codec: "json"

VRL rất nhanh vì nó được compile trực tiếp. Việc chuyển message sang chữ hoa (upcase) hay thêm timestamp chỉ tốn vài micro giây, không hề gây delay cho pipeline.

Chuyển log về Loki hoặc Elasticsearch

Khi log đã sạch, bạn có thể đẩy chúng về hệ thống lưu trữ tập trung như Grafana Loki:

sinks:
  loki_sink:
    type: "loki"
    inputs:
      - "parse_logs"
    endpoint: "http://loki:3100"
    labels:
      container_name: "{{ container_name }}"
      service: "my-app"

Kiểm tra hiệu năng thực tế

Khởi động hệ thống bằng lệnh: docker compose up -d. Sau đó, hãy thử truy cập localhost:8080 để tạo traffic cho Nginx.

Để xem Vector đang xử lý thế nào, bạn dùng lệnh: docker logs -f vector. Bạn sẽ thấy các dòng log JSON xuất hiện ngay lập tức với đầy đủ các trường envprocessed_at đã cấu hình.

Điểm cộng lớn là dashboard nội bộ của Vector. Hãy thêm đoạn code này vào file cấu hình:

api:
  enabled: true
  address: "0.0.0.0:8686"

Khi chạy vector top, bạn sẽ thấy biểu đồ throughput. Ngay cả khi xử lý 5.000 – 10.000 dòng log mỗi giây, mức chiếm dụng CPU của Vector thường vẫn dưới 5% trên các dòng CPU phổ thông.

Lời kết

Chuyển sang Vector là một trong những quyết định đúng đắn nhất để tối ưu hạ tầng Docker. Nó không chỉ nhẹ mà còn cực kỳ linh hoạt nhờ ngôn ngữ VRL. Nếu bạn đang mệt mỏi với việc bảo trì Java/JVM cho Logstash, hãy thử Vector ngay hôm nay. Chúc anh em triển khai thành công, nếu gặp lỗi cú pháp VRL thì cứ để lại comment mình hỗ trợ nhé!

Share: