1. 10:33 06/08/2026
Khi ứng dụng còn nhỏ, nhiều đội chỉ cần mở console hoặc xem vài dòng log là đoán được lỗi. Nhưng khi hệ thống có nhiều API, worker, database, cache, dịch vụ bên thứ ba và người dùng thật, câu hỏi “vì sao tính năng này chậm/lỗi?” sẽ khó trả lời hơn rất nhiều. Đây là lúc logging và observability trở thành một phần quan trọng của phát triển web/app, không chỉ là việc “in lỗi ra màn hình”.
Logging là gì?
Logging là việc ghi lại các sự kiện xảy ra trong hệ thống: request đi vào, thao tác quan trọng, lỗi, thời gian xử lý, trạng thái thanh toán, kết quả gọi API bên ngoài... Log tốt giúp lập trình viên điều tra sự cố nhanh hơn, hiểu hành vi thật của hệ thống và phát hiện vấn đề trước khi người dùng phàn nàn quá nhiều.
Ví dụ thực tế: người dùng báo “tôi bấm thanh toán nhưng không thấy đơn hàng”. Nếu hệ thống có log tốt, bạn có thể lần theo:
- Request tạo đơn hàng có tới server không?
- User ID và order ID liên quan là gì?
- Cổng thanh toán trả về thành công, thất bại hay timeout?
- Worker xử lý xác nhận thanh toán có chạy không?
- Email/thông báo đã được gửi chưa?
Nếu không có log, việc điều tra thường biến thành đoán mò.
Đừng chỉ log lỗi, hãy log cả ngữ cảnh
Một dòng log kiểu “Payment failed” thường chưa đủ hữu ích. Nên có thêm ngữ cảnh để truy vết, ví dụ:
- request_id hoặc correlation_id để nối các log của cùng một request
- user_id nếu phù hợp
- order_id, payment_id hoặc mã nghiệp vụ liên quan
- tên hành động đang xử lý
- trạng thái trả về từ dịch vụ bên ngoài
- thời gian xử lý
Ví dụ nội dung log tốt hơn: “payment_failed request_id=abc123 user_id=42 order_id=981 gateway_status=timeout duration_ms=3200”. Khi đọc dòng này, bạn đã có hướng điều tra rõ hơn nhiều.
Các mức log nên dùng có chủ đích
Một lỗi phổ biến là log gì cũng để error, hoặc ngược lại chỉ log khi hệ thống đã hỏng nặng. Có thể phân biệt đơn giản:
- debug: thông tin chi tiết khi phát triển hoặc điều tra sâu, không nên bật tràn lan ở production
- info: sự kiện bình thường nhưng quan trọng, như tạo đơn hàng thành công, user đăng nhập, job hoàn tất
- warn: dấu hiệu bất thường nhưng chưa làm hỏng luồng chính, ví dụ API bên ngoài chậm hoặc retry lần đầu
- error: lỗi làm thao tác thất bại, cần được theo dõi
- fatal/critical: sự cố nghiêm trọng khiến dịch vụ không thể tiếp tục hoạt động bình thường
Dùng đúng mức log giúp đội vận hành lọc thông tin dễ hơn và tránh bị “chai lì” trước quá nhiều cảnh báo không quan trọng.
Cẩn thận với dữ liệu nhạy cảm
Log rất hữu ích nhưng cũng có thể trở thành rủi ro bảo mật nếu ghi bừa bãi. Không nên log mật khẩu, access token, refresh token, số thẻ, mã OTP, cookie phiên đăng nhập hoặc dữ liệu cá nhân không cần thiết. Với email, số điện thoại, địa chỉ, hãy cân nhắc che một phần hoặc chỉ log ID nội bộ.
Một nguyên tắc thực tế: trước khi thêm log, hãy tự hỏi “nếu dòng này bị lộ hoặc được nhiều người nội bộ đọc, có gây rủi ro cho người dùng không?”.
Observability rộng hơn logging
Logging chỉ là một phần. Observability thường gồm ba mảng chính:
- Logs: chuyện gì đã xảy ra?
- Metrics: hệ thống đang hoạt động ra sao theo thời gian? Ví dụ số request, tỷ lệ lỗi, độ trễ, CPU, RAM, số job đang chờ.
- Traces: một request đi qua những dịch vụ nào, mất bao lâu ở từng bước?
Với ứng dụng đơn giản, log có thể đủ. Nhưng khi có nhiều service, trace giúp thấy rõ request bị chậm ở database, cache, service thanh toán hay đoạn xử lý nội bộ.
Lời khuyên có thể áp dụng ngay
1. Thêm request_id cho mỗi request
Mỗi request nên có một ID duy nhất. Khi backend gọi sang service khác hoặc đẩy job vào hàng đợi, hãy truyền ID này đi cùng nếu có thể. Nhờ vậy, bạn có thể tìm toàn bộ log liên quan đến một thao tác của người dùng.
2. Log các điểm nghiệp vụ quan trọng
Không cần log từng dòng code. Hãy log ở các mốc có ý nghĩa: tạo đơn hàng, xác nhận thanh toán, gửi email, đổi trạng thái tài khoản, cập nhật gói dịch vụ, đồng bộ dữ liệu.
3. Đo thời gian xử lý
Với API hoặc job quan trọng, nên ghi duration. Một lỗi “không xảy ra” nhưng xử lý mất 10 giây vẫn là vấn đề trải nghiệm.
4. Chuẩn hóa cấu trúc log
Nếu có thể, dùng log dạng có cấu trúc với các trường rõ ràng như level, timestamp, request_id, user_id, action, message. Log có cấu trúc dễ tìm kiếm và phân tích hơn log văn bản tự do.
5. Thiết lập cảnh báo dựa trên tín hiệu quan trọng
Đừng gửi cảnh báo cho mọi dòng error nhỏ. Hãy cảnh báo khi tỷ lệ lỗi tăng, API quá chậm, queue tồn đọng lâu, số lần thanh toán thất bại tăng bất thường hoặc service quan trọng không phản hồi.
Kết luận
Logging và observability không phải phần “trang trí” sau khi code xong. Chúng là công cụ giúp đội phát triển hiểu hệ thống trong môi trường thật. Một hệ thống có log tốt sẽ tiết kiệm rất nhiều thời gian khi debug, giảm thời gian xử lý sự cố và giúp ra quyết định kỹ thuật tự tin hơn. Hãy bắt đầu từ những việc nhỏ: thêm request_id, log các hành động nghiệp vụ quan trọng, tránh ghi dữ liệu nhạy cảm và đo thời gian xử lý ở các luồng chính.