Vấn đề
Support nhận báo lỗi "tìm không ra gì" hoặc "giá sai" với vỏn vẹn một trace-id. Nhưng request thật gửi lên nhà cung cấp được lắp từ mapping trong cache, config của từng tài khoản và credential riêng — không ai dựng lại bằng tay được.
Sản phẩm khách sạn có công cụ này. Bốn sản phẩm còn lại ghi log vào Redis và MySQL nhưng không ai đọc lại được nếu không SSH vào Redis.
Thiết kế
Hai quyết định gánh cả công cụ.
Snapshot request ngay dòng đầu tiên của handler — trước khi controller điền default và transformer viết lại định dạng ngày — rồi lưu dưới dạng chuỗi plain-text đã chuẩn hoá thay vì blob JSON.
Bảng field được suy ra từ chính schema validate của mỗi endpoint, nên không
field nào rơi âm thầm và kiểu dữ liệu vẫn sống: null, chuỗi rỗng và
không-có-field là ba trạng thái khác nhau.
Endpoint đọc lại sẽ mint một JWT mới và trả về một câu curl dán-là-chạy.
Cả đường ghi log là fire-and-forget, try/catch từng call-site, và được chứng
minh an toàn bằng cách đổi tên bảng log trên staging rồi kiểm tra search vẫn
trả 200.
Kết quả
Vì điểm snapshot và bảng field suy từ schema là cùng một quyết định ở mọi gateway, phần rollout chỉ còn là việc tay chân: một MR cho mỗi gateway, năm sản phẩm trong cùng một ngày, verify trên staging thật. Payload nhỏ hơn JSON 44–75%.
Sau khi lên, mình tự tìm ra bug của chính mình: 5 lần search giống hệt nhau đẻ ra 5 dòng log với đúng 1 payload khác nhau. Fix bằng cách chuyển lệnh ghi vào đúng nhánh cache-MISS sẵn có của từng sản phẩm — tận dụng tín hiệu đã có trong code thay vì thêm một key Redis mới.
Bảng log search trên production hiện khoảng 626.000 dòng.