1. 00:28 06/08/2026
Khi ứng dụng chạy ổn, log thường bị xem là phần phụ. Nhưng đến lúc người dùng báo “em bấm thanh toán mà không thấy gì”, server trả lỗi 500 lúc nửa đêm, hoặc một tác vụ nền xử lý sai dữ liệu, log mới trở thành thứ giúp đội phát triển hiểu chuyện gì đã xảy ra. Ghi log tốt không phải là in thật nhiều dòng ra màn hình, mà là ghi đúng thông tin, đúng mức độ và đủ ngữ cảnh để điều tra.
1. Đừng chỉ log mỗi thông báo lỗi
Một dòng log kiểu “Error occurred” gần như vô dụng nếu không có thêm thông tin. Khi xử lý một request quan trọng, nên có các dữ liệu ngữ cảnh như:
- request_id hoặc trace_id để lần theo toàn bộ luồng xử lý
- user_id nếu có đăng nhập, tránh ghi thông tin nhạy cảm
- endpoint hoặc hành động đang thực hiện
- mã đơn hàng, mã giao dịch, mã tác vụ nếu liên quan
- thời gian xử lý hoặc trạng thái kết quả
Ví dụ, thay vì log:
“Payment failed”
Nên log theo hướng:
“Payment failed: order_id=ORD123, user_id=45, provider=stripe, error_code=card_declined, request_id=abc-xyz”
Chỉ cần nhìn dòng này, lập trình viên đã biết lỗi nằm ở đơn nào, người dùng nào, nhà cung cấp nào và có thể tìm tiếp các log cùng request_id.
2. Phân biệt các mức log
Một lỗi phổ biến là cái gì cũng log ở mức error. Điều này làm hệ thống cảnh báo bị nhiễu, lâu dần không ai còn chú ý nữa. Có thể phân chia đơn giản như sau:
- debug: thông tin chi tiết khi phát triển hoặc điều tra sâu
- info: sự kiện bình thường nhưng có giá trị theo dõi, ví dụ tạo đơn thành công
- warn: dấu hiệu bất thường nhưng chưa làm hỏng luồng chính, ví dụ gọi API ngoài chậm
- error: lỗi thật sự khiến một thao tác thất bại
- fatal/critical: lỗi nghiêm trọng ảnh hưởng toàn hệ thống
Trong môi trường production, thường không nên bật debug mặc định, trừ khi có cơ chế bật tạm thời cho một nhóm request hoặc một khoảng thời gian ngắn.
3. Không ghi dữ liệu nhạy cảm vào log
Log thường được nhiều người trong đội kỹ thuật truy cập, thậm chí được gửi sang hệ thống bên thứ ba để lưu trữ và phân tích. Vì vậy không nên ghi:
- mật khẩu, token, API key
- số thẻ, mã OTP, mã xác thực
- cookie phiên đăng nhập
- dữ liệu cá nhân không cần thiết
Nếu cần điều tra, hãy ghi dạng che bớt, ví dụ email chỉ hiện một phần, token chỉ hiện vài ký tự cuối, hoặc dùng mã định danh nội bộ thay vì dữ liệu gốc.
4. Dùng log có cấu trúc thay vì chuỗi tự do
Với dự án nhỏ, log dạng text vẫn dùng được. Nhưng khi hệ thống lớn dần, log có cấu trúc như JSON sẽ dễ tìm kiếm và lọc hơn. Ví dụ mỗi dòng log có các trường cố định: timestamp, level, message, request_id, user_id, service, action, duration_ms.
Lợi ích là sau này bạn có thể truy vấn: “tìm tất cả request thanh toán thất bại của user_id 45”, hoặc “thống kê endpoint nào thường mất hơn 2 giây”. Nếu log chỉ là một câu văn dài, việc phân tích sẽ khó hơn nhiều.
5. Ghi log ở ranh giới quan trọng
Không cần log từng dòng xử lý nhỏ, nhưng nên log ở các điểm chuyển giao quan trọng:
- nhận request từ client
- gọi API bên ngoài
- ghi dữ liệu quan trọng vào database
- đưa job vào queue hoặc xử lý xong job
- xảy ra exception chưa dự đoán
- thay đổi trạng thái nghiệp vụ quan trọng như đơn hàng, thanh toán, tài khoản
Ví dụ với luồng đặt hàng, có thể log khi tạo đơn, khi gọi cổng thanh toán, khi nhận callback thanh toán, khi cập nhật trạng thái đơn và khi gửi email xác nhận. Như vậy nếu trạng thái bị lệch, bạn có đủ dấu vết để đối chiếu.
6. Gắn request_id cho mỗi request
Đây là thói quen rất đáng áp dụng. Khi một request đi qua nhiều lớp như frontend, backend, queue, service thanh toán, mỗi nơi nên mang theo cùng một request_id hoặc correlation_id. Khi cần điều tra, chỉ cần tìm theo mã này là thấy toàn bộ hành trình.
Với ứng dụng có nhiều service, request_id gần như là bắt buộc. Nếu không có, việc tìm lỗi giống như mò kim đáy bể, nhất là khi nhiều người dùng thao tác cùng lúc.
7. Đặt chính sách lưu trữ và xoay vòng log
Log không nên được để phình mãi trên ổ đĩa. Cần có chính sách xoay vòng và thời gian lưu phù hợp. Ví dụ log ứng dụng thông thường có thể lưu ngắn hơn, còn log liên quan giao dịch quan trọng có thể cần lưu lâu hơn tùy yêu cầu vận hành. Điều quan trọng là phải có kế hoạch, thay vì chờ đến khi server đầy đĩa mới xử lý.
Kết luận
Logging tốt giúp giảm thời gian điều tra lỗi, cải thiện vận hành và hỗ trợ chăm sóc người dùng. Một hệ thống log hữu ích nên có đủ ngữ cảnh, phân mức rõ ràng, tránh dữ liệu nhạy cảm, có cấu trúc và gắn được request_id. Nếu dự án của bạn chưa có thói quen này, hãy bắt đầu từ các luồng quan trọng nhất như đăng nhập, thanh toán, tạo đơn, gửi email và tác vụ nền. Chỉ vài thay đổi nhỏ trong cách ghi log có thể tiết kiệm rất nhiều thời gian khi sự cố thật sự xảy ra.
0