Logging Đừng Để Để Sau: Bài Học Từ 1M Users
Project đầu tiên mình từng làm — công ty fintech, app phân loại chi tiêu cho hàng triệu khách hàng. Code xong, deploy production, 1M+ users bắt đầu dùng. Mọi thứ ổn cho đến khi sự cố xảy ra.
Mở logs ra — log format không đồng bộ, không đầy đủ, log dư thừa mà không có gì hữu ích.
Log "Để Sau" - Technical Debt
Lúc đó mình nghĩ logging là thứ thêm sau được. Code xong feature, ship nhanh đã.
Nhưng khi production có vấn đề, mình nhận ra mình đang ngồi trong bóng tối:
- Debug trong bóng tối — log chỉ ghi INFO chung chung, không user_id, không request context, không trace được flow
- Không thể tạo báo cáo — không biết ảnh hưởng ai, bao nhiêu user bị tác động
S3 + Athena: Đúng Strategy, Sai Cách Dùng
S3 + Athena là logging strategy hợp lý — nhiều công ty lớn vẫn dùng cho long-term storage và analytics. Vấn đề không phải công cụ, mà là cách chúng mình dùng nó.
Lúc đó log được ghi bằng plain text, mỗi service ghi một format khác nhau. Khi export sang S3, Athena không parse được vì schema không đồng bộ. Mỗi lần query phải transform format cho khớp — mất hàng tuần để tạo một báo cáo đơn giản.
Nếu log được ghi structured từ đầu, S3 + Athena sẽ hoạt động mượt mà. Schema rõ ràng, query SQL chạy ngay, không cần transform.
Logging Tốt Là Như Thế Nào
Sau bài học đó, mình hiểu logging tốt có 3 yếu tố:
Structured Format
Log nên là JSON - (CloudWatch insight, Athena đều hỗ trợ tốt format này), không plain text. Mỗi entry là object có schema rõ ràng:
{
"level": "info",
"message": "Payment processed",
"userId": "u_123",
"requestId": "req_abc",
"action": "payment.create",
"amount": 250000,
"timestamp": "2026-05-14T07:00:00.000Z"
}
Bất kể ngôn ngữ nào cũng có thư viện xử lý log tốt. Với NodeJS có Winston và Pino, Go có zerolog, ...
Correlation ID
Mỗi request phải có ID duy nhất. ID này đi xuyên suốt toàn bộ flow — gateway → service A → service B → database → response. Query theo requestId là trace được toàn bộ hành trình.
Log Level Đúng Chỗ
| Level | Dùng khi nào |
|---|---|
ERROR |
Sự cố cần can thiệp ngay |
WARN |
Bất thường nhưng hệ thống vẫn chạy |
INFO |
Flow bình thường |
DEBUG |
Chi tiết kỹ thuật, chỉ bật khi debug |
Mistake phổ biến: ghi ERROR cho mọi thứ. Khi mọi thứ đều là error, không có gì là error cả.
Các Loại Log Tối Thiểu
Bất kỳ backend system nào cũng phải có 4 loại log từ ngày đầu:
- Access log — mỗi request đến: method, path, status code, response time, user_id. Cơ sở phân tích traffic
- Application log — business events: user created, payment processed. Đủ context để audit
- Error log — full stack trace + request context + user context. Ghi cả state system tại thời điểm đó
- Infrastructure log — slow queries, cache miss rate, memory spikes. Early warning trước khi sự cố xảy ra
Đầu Tư Sớm, Tiết Kiệm Sau
Logging là bảo hiểm — làm sớm thì rẻ, làm muộn thì trả giá. Project đầu tay đã dạy bài học đó theo cách painful nhất.
Bài học đơn giản nhất: trước khi ship feature đầu tiên lên production, set up structured logging với correlation ID. Log đúng format từ đầu, S3 + Athena sẽ hoạt động đúng cách. Log sai format, mọi công cụ đều trở thành pain point.