Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn là kỹ sư vận hành của một sàn thương mại điện tử tại Việt Nam. 2 giờ sáng, điện thoại rung: khách hàng báo không thanh toán được. Hệ thống của bạn có 40 server ứng dụng, 8 server database, 6 node của message queue, chưa kể hàng chục container Kubernetes tự sinh ra rồi tự chết. Câu hỏi đơn giản "lỗi thanh toán này bắt nguồn từ đâu?" bỗng trở thành cơn ác mộng nếu bạn phải SSH vào từng máy rồi grep từng file log.
Đây chính xác là vấn đề mà log aggregation (tập trung hóa log) sinh ra để giải quyết. Trong các bài trước, chúng ta đã bàn về logging best practices (Bài 20) và ba trụ cột của observability (Bài 19). Bài này tập trung riêng vào hạ tầng thu thập, lưu trữ và truy vấn log tập trung — cụ thể là ba hệ sinh thái phổ biến nhất hiện nay: ELK Stack, Grafana Loki, và Datadog. Sau bài này, bạn sẽ hiểu cách chọn nền tảng phù hợp với quy mô và ngân sách, cũng như tránh những cái bẫy chi phí khiến nhiều team "vỡ trận" hóa đơn.
Khái niệm cốt lõi
Tại sao SSH-và-grep không scale được
Với 1-2 server, cách "thủ công" vẫn ổn: SSH vào máy, tail -f /var/log/app.log, grep ERROR. Nhưng cách này sụp đổ ngay khi hệ thống lớn lên, vì bốn lý do:
- Không thể query xuyên máy. Một request đi qua 5 microservice trên 5 server khác nhau. Để lần theo nó, bạn phải mở 5 terminal cùng lúc — bất khả thi lúc 2 giờ sáng.
- Log biến mất khi máy chết. Với container và autoscaling, một pod có thể sống 3 phút rồi bị thu hồi. Log nằm trong máy đó cũng mất theo. Bạn cần đẩy log ra ngoài trước khi máy chết.
- Không có alert và retention thống nhất. Bạn không thể đặt cảnh báo "khi số lỗi 500 vượt 100/phút" nếu log rải rác khắp nơi. Chính sách lưu trữ (giữ log bao lâu) cũng loạn xạ mỗi máy một kiểu.
- Không phân quyền được. Dev cần xem log để debug nhưng không nên có quyền SSH vào production.
Kiến trúc chung của một pipeline log
Dù bạn dùng nền tảng nào, pipeline log tập trung luôn có bốn tầng:
- Collection / Shipping (thu thập): một agent chạy trên mỗi máy đọc log rồi đẩy đi. Ví dụ: Filebeat, Fluent Bit, Fluentd, Promtail, Vector, hoặc Datadog Agent.
- Processing / Parsing (xử lý): phân tích dòng log thô thành các trường có cấu trúc (timestamp, level, service, trace_id...). Ví dụ: Logstash, Fluentd, hoặc pipeline xử lý ngay trên nền tảng.
- Storage / Indexing (lưu trữ): nơi log được lưu và đánh index để tìm kiếm nhanh. Đây là tầng tốn kém và quyết định hiệu năng nhất.
- Visualization / Query (trực quan hóa): giao diện để truy vấn, vẽ dashboard, đặt alert. Ví dụ: Kibana, Grafana.
ELK Stack (Elasticsearch, Logstash, Kibana)
ELK là hệ sinh thái lâu đời và mạnh nhất về khả năng tìm kiếm toàn văn (full-text search).
- Elasticsearch: database dạng tìm kiếm, đánh index toàn bộ nội dung log. Nhờ vậy bạn có thể tìm bất kỳ từ khóa nào cực nhanh.
- Logstash: đường ống xử lý và biến đổi log (parse, làm giàu, lọc). Khá nặng RAM, nên nhiều team thay bằng Fluentd hoặc để Elasticsearch ingest pipeline làm việc nhẹ.
- Kibana: giao diện query và dashboard.
- Beats (Filebeat, Metricbeat...): các agent nhẹ đẩy dữ liệu vào.
Grafana Loki
Loki ra đời sau, với triết lý ngược lại ES: "đừng index nội dung log, chỉ index metadata (label)." Loki chỉ đánh index vài nhãn như {service="payment", env="prod"}, còn nội dung log được nén và lưu dạng object storage (S3, GCS, MinIO). Khi query, Loki dùng label để khoanh vùng rồi grep trong khối dữ liệu đó.
- Promtail / Grafana Alloy: agent thu thập, gắn label.
- Loki: lưu trữ, dùng object storage giá rẻ.
- Grafana: giao diện query bằng LogQL (cú pháp giống PromQL).
Datadog
Datadog là nền tảng SaaS trả phí, bạn không tự vận hành hạ tầng. Cài Datadog Agent, log tự động chảy về cloud của Datadog cùng với metrics, traces, APM — tất cả trong một giao diện.
Điểm mạnh: gần như "cắm là chạy", tương quan tự động giữa log-metric-trace, không phải lo cluster. Rất phù hợp team nhỏ muốn tập trung vào sản phẩm thay vì vận hành observability. Điểm yếu: chi phí có thể tăng theo cấp số nhân. Datadog tính tiền theo lượng log ingest và số log indexed (giữ để query). Nhiều công ty tăng trưởng nhanh đã sốc khi hóa đơn Datadog vượt cả tiền thuê hạ tầng chính.
Tình huống thực tế
Ví dụ 1 — Startup fintech Sài Gòn: từ ELK "quá tải" sang Loki
Một startup ví điện tử ở TP.HCM (khoảng 40 kỹ sư) bắt đầu với ELK tự host trên 3 node Elasticsearch. Lượng log tăng lên ~500 GB/ngày khi họ scale từ 100 nghìn lên 1 triệu người dùng. Cluster ES liên tục đỏ (red status) vì hết dung lượng disk và JVM heap OOM. Team phải cắt cử một kỹ sư gần như toàn thời gian chỉ để "chăm" Elasticsearch — rotate index, tinh chỉnh shard, dọn dữ liệu cũ.
Họ đánh giá lại và nhận ra: 90% log của họ chỉ được query bằng vài label (service, level, trace_id), rất hiếm khi cần full-text search. Đây là điều kiện lý tưởng cho Loki. Họ chuyển sang Loki lưu trên object storage của nhà cung cấp cloud, giữ Grafana làm giao diện chung. Kết quả: chi phí lưu trữ log giảm khoảng 65%, và không còn ai phải "trực" Elasticsearch nữa.
Bài học: Đừng chọn ELK theo quán tính. Nếu pattern truy vấn của bạn chủ yếu là lọc theo label chứ không phải tìm từ khóa tự do, Loki tiết kiệm hơn nhiều và nhẹ vận hành hơn.
Ví dụ 2 — Cú sốc hóa đơn Datadog của một scale-up
Một công ty SaaS Đông Nam Á dùng Datadog vì tốc độ triển khai. Ban đầu hóa đơn khoảng 3.000 USD/tháng, hoàn toàn chấp nhận được. Nhưng khi họ bật debug logging trên toàn hệ thống để điều tra một sự cố, rồi... quên tắt, lượng log ingest tăng gấp 8 lần. Tháng sau hóa đơn Datadog nhảy lên gần 24.000 USD — riêng phần log chiếm phần lớn.
Nguyên nhân sâu xa: họ index tất cả log trên Datadog, kể cả những dòng debug vô nghĩa. Sau đó họ áp dụng log pipeline với indexing filter: chỉ index log level WARN trở lên và log của các service quan trọng; phần còn lại vẫn được ingest để phân tích nhưng lưu ở dạng rẻ (rehydration khi cần) hoặc bị loại bỏ ngay tại agent. Hóa đơn quay về khoảng 5.000 USD/tháng.
Bài học: Với nền tảng SaaS tính theo volume, quyết định "log gì" và "index gì" chính là quyết định chi phí. Luôn đặt filter ngay từ đầu và giám sát mức ingest như một metric riêng.
Ví dụ 3 — E-commerce dùng ELK để truy vết gian lận
Một sàn thương mại điện tử Việt Nam giữ ELK vì họ thực sự cần full-text search: đội chống gian lận (fraud) phải tìm kiếm tự do trên nội dung log — địa chỉ IP lạ, chuỗi user-agent bất thường, pattern trong payload đơn hàng. Loki sẽ chậm cho kiểu query này vì phải grep khối dữ liệu lớn.
Họ tối ưu ELK thay vì bỏ: dùng Index Lifecycle Management (ILM) để log nóng (7 ngày) nằm trên SSD nhanh, log ấm chuyển sang disk rẻ, và log trên 30 ngày tự động xóa hoặc snapshot xuống object storage. Nhờ vậy vừa giữ được sức mạnh search vừa kiểm soát chi phí lưu trữ.
Bài học: Chọn nền tảng theo pattern truy vấn thật của team. Khi full-text search là nghiệp vụ cốt lõi, ELK vẫn là lựa chọn xứng đáng — miễn là bạn quản lý vòng đời dữ liệu tử tế.
Hướng dẫn từng bước
Dưới đây là lộ trình dựng một log aggregation pipeline từ đầu, áp dụng được cho cả ba nền tảng:
- Chuẩn hóa log ở tầng ứng dụng trước. Đảm bảo ứng dụng xuất log dạng JSON có cấu trúc (structured logging) với các trường thống nhất:
timestamp,level,service,trace_id,message. Không có bước này thì mọi thứ phía sau sẽ chật vật parse.
- Chọn nền tảng theo ba tiêu chí: pattern truy vấn (label-filter hay full-text?), ngân sách và năng lực vận hành (có người chăm cluster không?), và nhu cầu tương quan với metric/trace. Nếu team nhỏ, không muốn vận hành: Datadog. Nếu cần search mạnh, có kỹ sư: ELK. Nếu muốn rẻ, đã dùng Grafana: Loki.
- Cài agent thu thập trên mọi node. Filebeat/Fluent Bit cho ELK, Promtail/Alloy cho Loki, Datadog Agent cho Datadog. Trong Kubernetes, triển khai agent dưới dạng DaemonSet để mỗi node có đúng một instance.
- Thiết lập tầng xử lý và gắn label/field. Parse JSON, gắn nhãn service và environment. Với Loki, giữ số lượng label nhỏ và giá trị hữu hạn — tuyệt đối không đưa user_id, request_id vào label.
- Định nghĩa chính sách retention và tiering. Ví dụ: log nóng 7 ngày để query nhanh, log lạnh 90 ngày lưu rẻ, sau đó xóa. Cấu hình ILM (ELK), retention của Loki, hoặc index/retention của Datadog.
- Dựng dashboard và alert. Tạo dashboard error rate theo service, và alert cho các tín hiệu quan trọng (ví dụ đột biến lỗi 500). Nhớ bài học ở Bài 18: alert phải là signal, không phải noise.
- Giám sát chính pipeline log. Theo dõi lượng ingest (GB/ngày), độ trễ, và chi phí. Đặt budget alert để không lặp lại "cú sốc Datadog".
Lỗi thường gặp & mẹo
- Index mọi thứ với ELK/Datadog. Đây là nguyên nhân số một khiến chi phí phình to. Hãy lọc từ tầng agent: loại bỏ log debug, health-check spam, log của bot. Chỉ index cái bạn thực sự query.
- Cardinality bùng nổ trên Loki. Gắn label có giá trị vô hạn (user_id, session_id, timestamp) sẽ tạo hàng triệu stream và làm Loki sập. Nhớ nguyên tắc: thông tin định danh nằm trong nội dung log, không nằm trong label.
- Không đặt retention. Log cứ chất đống đến khi hết disk hoặc hết tiền. Luôn định nghĩa vòng đời dữ liệu ngay từ ngày đầu.
- Chạy Elasticsearch một node cho production. ES cần replica; một node là mất dữ liệu khi máy chết. Nhưng cũng đừng quá tay — replica quá nhiều lại nhân đôi chi phí lưu trữ.
- Log không có trace_id. Không có trace_id thì log tập trung mất một nửa giá trị vì không lần theo request xuyên service được. Hãy propagate trace_id (liên kết với Bài 23 về distributed tracing).
- Mẹo — bật debug logging phải có "hẹn giờ tắt". Khi bật debug để điều tra sự cố, đặt ngay reminder hoặc feature flag tự tắt (Bài 17) để tránh quên như ví dụ 2.
- Mẹo — tách "hot query" và "cold archive". Log cần query gấp thì index; log để tuân thủ/audit thì nén và ném xuống object storage giá rẻ, chỉ rehydrate khi thanh tra yêu cầu.
Bài tập thực hành
- Lập bảng so sánh cho chính hệ thống của bạn. Kẻ bảng ba cột ELK / Loki / Datadog với các hàng: chi phí lưu trữ, năng lực full-text search, độ khó vận hành, khả năng tương quan metric-trace. Điền dựa trên bối cảnh team bạn rồi tự đưa ra kết luận nên chọn cái nào và tại sao.
- Dựng thử Loki trên máy cá nhân. Dùng Docker Compose chạy stack Loki + Promtail + Grafana, đẩy log của một ứng dụng nhỏ vào, rồi viết một truy vấn LogQL lọc theo label
{service="..."}và đếm số dòng chứa từ "error". Quan sát tốc độ so vớigrep.
- Ước tính chi phí. Giả sử hệ thống của bạn sinh 200 GB log/ngày. Hãy ước tính chi phí hàng tháng cho hai kịch bản: (a) index 100% log trên một nền tảng SaaS, và (b) chỉ index 15% (phần WARN trở lên), 85% còn lại lưu object storage. So sánh con số và rút ra kết luận về chiến lược indexing.
- Thiết kế label cho Loki. Cho một dịch vụ payment có các trường: service, env, region, user_id, http_status, trace_id. Hãy phân loại trường nào nên làm label và trường nào nên nằm trong nội dung log. Giải thích lý do dựa trên nguyên tắc cardinality.
Tóm tắt
Log aggregation ra đời vì SSH-và-grep không thể scale: bạn cần gom log từ mọi nguồn về một nơi để có query, alert, dashboard và retention thống nhất. Một pipeline log luôn gồm bốn tầng — thu thập, xử lý, lưu trữ, trực quan hóa — và điểm khác biệt cốt lõi giữa các nền tảng nằm ở tầng lưu trữ/index, cũng là nơi quyết định chi phí.
ELK mạnh nhất về full-text search nhưng nặng vận hành và tốn lưu trữ vì index toàn văn — phù hợp khi search tự do là nghiệp vụ cốt lõi. Loki đảo ngược triết lý, chỉ index label và lưu trên object storage giá rẻ — phù hợp khi bạn truy vấn theo label và muốn tiết kiệm, nhưng phải kiểm soát cardinality. Datadog là SaaS "cắm là chạy", tuyệt vời cho team nhỏ, nhưng chi phí ingest/index có thể tăng vọt nếu không lọc kỹ.
Nguyên tắc xuyên suốt: chọn nền tảng theo pattern truy vấn thật của team, kiểm soát cái gì được index, và luôn có chính sách retention. Làm đúng ba điều đó, bạn vừa có khả năng debug lúc 2 giờ sáng, vừa giữ được hóa đơn trong tầm kiểm soát.