Cài đặt Fluent Bit trên Ubuntu: Thu thập log hệ thống và Docker container, chuyển tiếp về Elasticsearch

Ubuntu tutorial - IT technology blog
Ubuntu tutorial - IT technology blog

2:17 sáng. Slack báo alert: service API trả 500 liên tục. Mình ssh vào server, nhảy vào từng container chạy docker logs --tail 100 api_container, rồi lại journalctl -u nginx --since "5 minutes ago", rồi grep file log của PostgreSQL. 15 phút sau vẫn chưa thấy root cause vì log nằm rải rác ở 6 chỗ khác nhau.

Hôm sau mình dành 2 tiếng dựng Fluent Bit. Từ đó đến nay — mình đã cài Ubuntu Server 22.04 trên hơn 20 con VPS, và cài Fluent Bit là một trong những việc mình luôn làm đầu tiên — cài xong là thở phào, biết rằng lần sau có sự cố lúc nửa đêm sẽ không còn phải grep thủ công nữa.

So sánh các công cụ thu thập log: Logstash, Fluentd, Filebeat, Fluent Bit

Trước khi nhảy vào cài đặt, cần chọn đúng công cụ. Chọn sai là mất thời gian migrate sau.

Logstash — Mạnh nhưng ngốn RAM

Là thành viên cốt lõi của Elastic Stack nên tích hợp Elasticsearch gần như zero-config. Pipeline DSL linh hoạt, kho plugin đồ sộ. Nhưng nó chạy trên JVM — tốn 300–500MB RAM khi idle, lúc cao điểm có thể leo lên 1–2GB. Trên VPS 2GB RAM đang chạy ứng dụng, Logstash là con voi trong căn phòng nhỏ.

Fluentd — Cân bằng tốt, ecosystem mạnh nhất

Chạy bằng Ruby, nhẹ hơn Logstash kha khá (~40–100MB RAM). Điểm mạnh thực sự là chiều rộng: Fluentd có thể nhận log từ hàng chục nguồn, aggregate, transform, rồi route về nhiều đích cùng lúc — và có plugin cho gần như mọi thứ bạn nghĩ tới. Fluentd và Fluent Bit là anh em cùng cha, đều do Treasure Data phát triển. Nhiều hệ thống lớn dùng Fluent Bit làm agent gom log từ từng node, forward về một Fluentd aggregator trung tâm để xử lý nặng.

Filebeat — Nhẹ nhưng đơn chức năng

Viết bằng Go, cùng họ Elastic Stack với Logstash, footprint gọn ~30–50MB. Vấn đề là Filebeat sinh ra để ship log — đọc file, chuyển đi, xong. Muốn parse và enrich log phức tạp? Phải đẩy cái gánh đó sang Elasticsearch Ingest Pipeline xử lý tiếp.

Fluent Bit — Siêu nhẹ, đủ dùng

C-based. Memory footprint khi idle chỉ khoảng 450KB — không nhầm, kilobyte chứ không phải megabyte. 50+ input plugin, 40+ output plugin, xử lý được parse/filter/enrich/route trước khi forward. Cho use case systemd + Docker → Elasticsearch, không có công cụ nào làm được nhiều hơn mà tiêu ít RAM hơn.

Phân tích ưu nhược điểm thực tế

  • Logstash: Cực mạnh, tích hợp Elastic Stack hoàn hảo — nhưng RAM 300MB+ loại nó ra khỏi danh sách cho VPS nhỏ
  • Fluentd: Plugin ecosystem mạnh nhất, lý tưởng làm aggregator node xử lý log tập trung từ nhiều server
  • Filebeat: Nhẹ và dễ cài, nhưng thiếu tính năng filter nên phụ thuộc vào Elasticsearch để xử lý
  • Fluent Bit: Siêu nhẹ, đủ tính năng cho hầu hết use case — lý tưởng để chạy agent trên mọi node trong fleet

Quyết định: Fluent Bit chạy trên từng server, gom log từ systemd và Docker, forward thẳng về Elasticsearch. Không cần aggregator trung gian khi fleet không quá vài chục node.

Cài đặt Fluent Bit trên Ubuntu 22.04

Fluent Bit có repo apt chính thức — cài theo cách này thì apt upgrade sau này tự cập nhật luôn, không phải nhớ thêm bước nào:

# Thêm GPG key và repo chính thức
curl -fsSL https://packages.fluentbit.io/fluentbit.key | sudo gpg --dearmor -o /usr/share/keyrings/fluentbit-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/fluentbit-keyring.gpg] https://packages.fluentbit.io/ubuntu/jammy jammy main" | \
  sudo tee /etc/apt/sources.list.d/fluent-bit.list

sudo apt-get update
sudo apt-get install -y fluent-bit

# Bật và khởi động service
sudo systemctl enable fluent-bit
sudo systemctl start fluent-bit
sudo systemctl status fluent-bit

File config mặc định ở /etc/fluent-bit/fluent-bit.conf. Backup một cái trước khi chỉnh — thói quen tốt:

sudo cp /etc/fluent-bit/fluent-bit.conf /etc/fluent-bit/fluent-bit.conf.bak

Cấu hình thu thập log hệ thống và container

Thu thập log từ systemd/journald

Plugin systemd của Fluent Bit đọc thẳng từ journald, không qua file — quan trọng là không bỏ sót log khi log rotate. Thêm vào file config:

[SERVICE]
    Flush        5
    Daemon       Off
    Log_Level    info
    Parsers_File parsers.conf

[INPUT]
    Name            systemd
    Tag             system.*
    Systemd_Filter  _SYSTEMD_UNIT=nginx.service
    Systemd_Filter  _SYSTEMD_UNIT=postgresql.service
    Systemd_Filter  _SYSTEMD_UNIT=docker.service
    Read_From_Tail  On

Muốn gom toàn bộ system log thì bỏ các dòng Systemd_Filter đi. Nhưng mình thường filter theo service vì Elasticsearch nhận ít data hơn, query nhanh hơn.

Thu thập log từ Docker container

Cách đơn giản nhất là để Fluent Bit đọc trực tiếp file log Docker tạo ra tại /var/lib/docker/containers/:

[INPUT]
    Name              tail
    Tag               docker.*
    Path              /var/lib/docker/containers/*/*.log
    Parser            docker
    DB                /var/log/fluent-bit-docker.db
    Mem_Buf_Limit     5MB
    Skip_Long_Lines   On
    Refresh_Interval  10

Fluent Bit chạy dưới user riêng và cần quyền đọc thư mục Docker. Một lệnh là xong:

sudo usermod -aG docker fluent-bit
sudo systemctl restart fluent-bit

Lọc và làm giàu dữ liệu log

Raw log từ systemd thường lộn xộn — container ID thay vì tên service, timestamp không đồng nhất giữa các ứng dụng, cả đống metadata thừa mà Elasticsearch không cần. Vài dòng FILTER xử lý gọn:

# Thêm hostname và môi trường vào mọi log record
[FILTER]
    Name   record_modifier
    Match  *
    Record hostname ${HOSTNAME}
    Record env      production

# Chỉ giữ log level ERROR/WARN từ Docker container
[FILTER]
    Name  grep
    Match docker.*
    Regex log (ERROR|WARN|WARNING|FATAL|CRITICAL)

# Parse log JSON từ ứng dụng Node.js hoặc Python structlog
[FILTER]
    Name         parser
    Match        docker.*
    Key_Name     log
    Parser       json
    Reserve_Data True

Chuyển tiếp log về Elasticsearch

Plugin es output tích hợp sẵn trong Fluent Bit, không cần cài thêm gì:

[OUTPUT]
    Name              es
    Match             *
    Host              elasticsearch.internal
    Port              9200
    Index             server-logs
    Type              _doc
    Logstash_Format   On
    Logstash_Prefix   server-logs
    Logstash_DateFormat %Y.%m.%d
    Retry_Limit       5

    # Nếu Elasticsearch có authentication
    HTTP_User         elastic
    HTTP_Passwd       your_password

    # Nếu dùng HTTPS
    tls               On
    tls.verify        Off

Với Logstash_Format On, Fluent Bit tạo index theo format server-logs-2026.11.14 — giống cách Logstash làm, thuận tiện để setup ILM (Index Lifecycle Management) trong Kibana sau này.

Test và kiểm tra kết quả

Trước khi restart service, kiểm tra syntax config:

# Dry-run để kiểm tra syntax
sudo fluent-bit -c /etc/fluent-bit/fluent-bit.conf --dry-run

# Restart nếu không có lỗi
sudo systemctl restart fluent-bit

# Theo dõi log của Fluent Bit
sudo journalctl -u fluent-bit -f

Kiểm tra log đã về Elasticsearch chưa:

# Xem indices đã được tạo chưa
curl -X GET "http://elasticsearch.internal:9200/_cat/indices?v&index=server-logs*"

# Xem vài record đầu tiên
curl -X GET "http://elasticsearch.internal:9200/server-logs-*/_search?pretty&size=5"

Thấy indices server-logs-YYYY.MM.DD xuất hiện trong Elasticsearch là xong phần cứng. Qua Kibana, tạo index pattern server-logs-*, vào Discover — log từ tất cả service đổ về real-time.

Một vài lưu ý khi vận hành

  • Buffer ra disk: Nếu Elasticsearch down tạm thời, Fluent Bit có thể buffer log ra disk thay vì mất dữ liệu. Thêm storage.type filesystem vào section [SERVICE] và chỉ định storage.path
  • Backpressure: Khi Elasticsearch xử lý chậm hơn tốc độ gom log, Fluent Bit có cơ chế throttle tự động. Giới hạn Mem_Buf_Limit trong mỗi INPUT để tránh OOM trên server nhỏ
  • Flush interval: Với fleet nhiều server, để Flush 10 thay vì mặc định 5 — giảm một nửa số request tới Elasticsearch mà không ảnh hưởng đáng kể đến realtime
  • Log rotation: Plugin tail tự xử lý log rotation thông qua tham số DB — không cần config thêm logrotate

Lần tiếp theo có alert lúc 2 giờ sáng, thay vì grep thủ công 6 nơi khác nhau, mình chỉ cần mở Kibana Discover, filter theo khoảng thời gian và tên service — root cause thường hiện ra trong vòng 2 phút.

Share: