Bài 15 · Nâng cao · 26 phút
Metrics, audit log & báo cáo
Biên soạn bởi Nguyễn Anh Tuấn
Audit log mọi action admin & auth event; metrics báo cáo toàn diện: sức khoẻ hệ thống, rủi ro user/business/hàng, tiền vào ra (đối soát SePay) và cảnh báo khi vượt ngưỡng.
Sản phẩm đã chạy: khách đăng nhập, nạp tiền, mua hàng; admin quản lý. Nhưng nếu không đo và ghi lại, mèo con mù: hệ thống đang khoẻ hay đang chảy máu tiền, có ai đang dò tài khoản, kho có đang âm không - đều không biết cho tới khi khách kêu.
Khả năng nhìn vào trong hệ thống gọi là observability, dựng từ hai thứ: log (ghi từng sự kiện) và metrics (số đo gom lại), rồi từ đó ra báo cáo và cảnh báo.
Tầng nền là audit log - nhật ký nghiệp vụ ghi "ai làm gì, trên cái gì, khi nào, từ đâu". Ghi cho mọi action admin (đổi giá, khoá tài khoản, cộng/trừ số dư) và mọi auth event (đăng nhập, thất bại, đổi mật khẩu, bật/tắt 2FA). Đây là bằng chứng khi có sự cố hay tranh chấp:
- ▸Append-only: log chỉ thêm, KHÔNG sửa/xoá - mới là bằng chứng tin được.
- ▸Ghi đủ: ai (user id), hành động, đối tượng, thời gian, IP/thiết bị, kết quả.
- ▸TUYỆT ĐỐI không ghi mật khẩu, mã 2FA/OTP, số thẻ, token - che (mask) hoặc bỏ.
Tới lượt mèo con (build). Bật plan mode, đưa mô tả, duyệt rồi cho dựng:
gõ trong ô Claude Code (sau khi bật plan mode)
Tạo bảng audit_log (user_id, hành động, đối tượng, thời gian, IP, kết quả),
append-only. Ghi MỘT dòng cho mọi action admin (đổi giá, khoá tài khoản,
cộng/trừ số dư) và mọi auth event (đăng nhập, login_failed, đăng xuất,
đổi mật khẩu, bật/tắt 2FA). KHÔNG ghi mật khẩu/mã 2FA/số thẻ vào log. Bạn đã xong bước này khi
Từ log và metrics, dựng báo cáo theo bốn nhóm để nhìn bao quát sức khoẻ và rủi ro của cả sản phẩm:
- ▸🩺 Sức khoẻ hệ thống: uptime, tỉ lệ lỗi, độ trễ, hàng đợi BullMQ tồn, webhook lỗi.
- ▸👤 Rủi ro user: đăng nhập thất bại dồn dập, nhiều thiết bị lạ, nạp/rút bất thường.
- ▸📦 Rủi ro hàng & business: kho âm/sắp hết, đơn lỗi, tỉ lệ hoàn tiền cao.
- ▸💰 Tiền vào/ra: tổng nạp, tổng mua/rút, số dư hệ thống - và đối soát với SePay.
Tới lượt mèo con
Phần nhạy nhất là tiền. Báo cáo phải trả lời gọn: hôm nay vào bao nhiêu (nạp), ra bao nhiêu (mua/rút), số dư toàn hệ thống là bao nhiêu. Và quan trọng: đối soát (reconciliation) - tổng tiền đã cộng vào ví khách phải khớp tổng giao dịch SePay báo về.
Đối soát - mã giả minh hoạ (Claude viết bằng code Next.js)
tong_da_cong = SUM(giao_dich.so_tien WHERE loai='nap' AND trang_thai='hoan_tat')
tong_sepay = SUM(sepay.so_tien WHERE da_xac_nhan)
if tong_da_cong != tong_sepay:
canh_bao("Lệch tiền nạp", tong_da_cong - tong_sepay) # tìm ngay Trung thực
Tới lượt mèo con
Báo cáo đẹp nhưng không ai ngồi xem 24/7. Với vài metrics quan trọng, đặt ngưỡng cảnh báo để hệ thống tự báo khi có bất thường - xử lý kịp thay vì đợi khách kêu.
- ▸Ví dụ ngưỡng: webhook lỗi > 5% trong 10 phút; một tài khoản rút > X trong 1 giờ; kho âm.
- ▸Vượt ngưỡng thì báo qua email/Zalo/Slack, kèm đường dẫn tới chi tiết.
- ▸Đừng đặt quá nhiều cảnh báo vụn - nhiễu thì người ta bỏ qua cả cái quan trọng.
Tới lượt mèo con
Log là con dao hai lưỡi: ghi đủ để truy vết, nhưng ghi bừa thì thành kho bí mật cho kẻ tấn công. Nguyên tắc: không bao giờ log mật khẩu, mã 2FA, số thẻ, token; che bớt dữ liệu cá nhân; và giữ log không sửa được để còn là bằng chứng.
Tới lượt mèo con
Bước tiếp theo
Câu hỏi thường gặp
Log thường (application log) là nhật ký kỹ thuật để gỡ lỗi. Audit log là nhật ký NGHIỆP VỤ ghi "ai làm gì, trên cái gì, khi nào, từ đâu (IP)" - nhất là các action admin và auth event. Nó là bằng chứng truy vết khi có sự cố hay tranh chấp, nên phải append-only (chỉ thêm, không sửa/xoá).
Ghi: ai (user id), hành động (đổi giá, khoá tài khoản, cộng số dư), đối tượng, thời gian, IP/thiết bị, kết quả. KHÔNG ghi: mật khẩu, mã 2FA/OTP, số thẻ, token - log lộ thì thành kho bí mật cho kẻ tấn công. Dữ liệu nhạy cảm thì che (mask) hoặc bỏ.
Log là từng dòng sự kiện riêng lẻ. Metrics là SỐ ĐO gom lại theo thời gian: số đăng nhập thất bại/giờ, tổng tiền nạp/ngày, số đơn lỗi, hàng đợi tồn bao nhiêu. Báo cáo và biểu đồ dựng từ metrics; log để soi chi tiết khi cần truy ngược.