# Sentry cho FDE: sửa lỗi ở site khách khi bạn không có mặt

> Không SSH được, không mở được log, khách chỉ nhắn "nó bị lỗi": Sentry giúp bạn biết lỗi gì, ở đâu, từ bản nào.

Bản gốc: https://fdetimes.net/vi/cong-cu/sentry-theo-doi-loi-ung-dung-giao-cho-khach/

Thử hình dung lúc 10 giờ tối, khách nhắn: "Màn hình duyệt đơn lại trắng trơn." Bạn không vào được server của họ và cũng không biết user nào bị, bị từ lúc nào. Sửa nhanh hay chậm chủ yếu phụ thuộc vào việc bạn có đủ ngữ cảnh hay không, chứ độ phức tạp của code thường không phải yếu tố quyết định.

Với một FDE, đây là tình huống quen thuộc. Ứng dụng bạn dựng chạy trong môi trường của người khác, lỗi xảy ra khi bạn không có mặt, còn người báo lỗi thường không phải kỹ sư. Sentry là công cụ mang ngữ cảnh đó về tận bàn làm việc của bạn.

## Sentry làm gì ngoài việc bắt exception?

Sentry khởi đầu là một dự án mã nguồn mở. Hiện nay, công ty mô tả sứ mệnh của mình là giúp mọi developer chẩn đoán, sửa và tối ưu hiệu năng code. Chữ quan trọng ở đây là "chẩn đoán": bắt được lỗi mới chỉ là bước đầu, giá trị thật nằm ở cách Sentry sắp xếp lỗi.

Đơn vị cơ bản là event, tức một lần lỗi xảy ra. Nếu để nguyên, 500 event sẽ là 500 dòng chẳng nói lên điều gì. Sentry dùng fingerprint để gom các event giống nhau thành issue, nhờ vậy bạn thấy một vấn đề lặp lại bao nhiêu lần và biết nên ưu tiên lỗi nào.

Mỗi issue có một trang Issue Details. Phần Stack Trace chỉ ra dòng code nơi event bị lỗi. Breadcrumbs ghi lại chuỗi sự kiện xảy ra trước lỗi, và vì là dữ liệu có cấu trúc nên chúng chứa nhiều thông tin hơn log truyền thống.

## Ba loại ngữ cảnh, ba cách dùng khác nhau

Người mới hay nhầm tag với context. Ở site khách, nhầm chỗ này nghĩa là đến lúc cần lọc thì lại không lọc được. Bảng dưới đây tóm tắt sự khác biệt:

| Loại dữ liệu | Bản chất | Dùng khi |
|---|---|---|
| Tag | Cặp key/value dạng chuỗi, được index và tìm kiếm được | Cần lọc: lỗi này chỉ xảy ra ở trình duyệt nào, thiết bị nào, user nào |
| Context | Nhóm dữ liệu liên quan để hỗ trợ debug, không tìm kiếm được | Cần đọc chi tiết khi đã mở một event cụ thể |
| Breadcrumbs | Dòng thời gian các sự kiện trước lỗi | Cần biết người dùng hoặc hệ thống đã làm gì ngay trước khi hỏng |

Quy tắc rút ra khá đơn giản. Những gì bạn sẽ muốn hỏi theo kiểu "có bao nhiêu lỗi thuộc nhóm X" thì đặt vào tag. Những gì chỉ cần xem khi đang soi một ca cụ thể thì để trong context.

Với JavaScript SDK, một bản cấu hình tối thiểu cho app duyệt đơn có thể trông như sau (tên release và giá trị chỉ để minh họa):

```js
Sentry.init({
dsn: "",
release: "duyet-don@2.4.1",
sampleRate: 1.0,
});

// Tag: sẽ cần lọc theo chi nhánh
Sentry.setTag("branch_id", "cn-moi-07");

// Context: chỉ đọc khi mở một event cụ thể
Sentry.setContext("order", { orderId: "DH-1024", status: "pending" });
```

Mã chi nhánh nằm ở tag vì sớm muộn bạn sẽ hỏi "lỗi này có chỉ xảy ra ở một chi nhánh không". Mã đơn và trạng thái đơn nằm ở context vì chỉ có ích khi bạn đang soi một event. Dòng `release` là thứ bạn sẽ cần đến ở cuối ca dưới đây.

## Một ca cụ thể: màn hình duyệt đơn trắng trơn

Quay lại tin nhắn lúc 10 giờ tối, giả sử app đã được cài Sentry từ đầu. Bạn mở dashboard và thấy một issue mới với vài trăm event, tức là vài trăm lần màn hình trắng kia đã được fingerprint gom lại thành cùng một vấn đề. Đây là một lỗi lặp lại, không phải hàng trăm lỗi khác nhau.

Stack trace chỉ vào dòng code đọc một trường trong dữ liệu đơn hàng. Breadcrumbs cho thấy ngay trước đó người dùng mở bộ lọc rồi gọi API lấy danh sách đơn. Bạn lọc theo tag `branch_id` và thấy lỗi chỉ xuất hiện ở một nhóm user, giả sử là nhóm thuộc chi nhánh vừa được thêm vào hệ thống.

Mảnh ghép cuối cùng là release. Trong Sentry, release là một phiên bản code đã được deploy lên một môi trường. Khi có release, Sentry có thể gợi ý commit và người có khả năng đã gây ra lỗi.

Nếu issue này đã từng được resolve mà nay xuất hiện lại ở release mới, Sentry sẽ đánh dấu nó là regression. Nhìn vào đó, bạn biết ngay bản deploy chiều nay đã làm lỗi cũ quay lại.

Khách chưa kịp gửi thêm ảnh chụp màn hình thì bạn đã trả lời được: lỗi gì, ở dòng nào, nhóm user nào, từ bản nào. Việc nên làm đầu tiên là báo cho khách phạm vi ảnh hưởng, sau đó mới sửa. Khách thường cần nghe "chỉ chi nhánh mới bị" sớm hơn cả bản vá.

**Điểm mấu chốt:** Lỗi ở hệ thống khách chỉ sửa nhanh được khi bạn mang được ngữ cảnh về bàn mình.

## Những chỗ dễ vấp khi đưa vào hệ thống khách

Rủi ro lớn nhất nằm ở dữ liệu. Breadcrumbs và context càng nhiều thông tin thì càng dễ kéo theo email, số điện thoại hay token của người dùng cuối. Sentry có thể xóa thông tin nhạy cảm ở phía server ngay trước khi lưu. Với app chạy trong hệ thống khách, hãy cấu hình phần này trước khi bật Sentry trên production, đừng để làm sau.

Chỗ vấp thứ hai là sampling. Mặc định, SDK gửi toàn bộ lỗi vì error sample rate bằng 1. Còn transaction và tracing thì sẽ không được gửi nếu bạn chưa cấu hình. Vì vậy, khi khách than "chậm" chứ không phải "lỗi", bản cài mặc định sẽ không cho bạn chút dữ liệu hiệu năng nào.

Chỗ vấp thứ ba xuất hiện khi khách yêu cầu chạy on-prem. Sentry có bản self-hosted, nhưng đó chỉ là thiết lập tối thiểu, không có cam kết hay đội hỗ trợ riêng. Nếu đi theo hướng này, hãy thống nhất rõ với khách ai sẽ vận hành và nâng cấp nó, và đừng mặc định người đó là bạn.

Sentry còn có Seer, một AI debugging agent tự quét các issue mới đổ về để tìm root cause và tự động hóa việc phân loại. Seer có ích khi số issue lớn, nhưng nó chỉ làm việc được với ngữ cảnh bạn đã gửi lên. Nếu thiếu tag và không gắn release thì agent nào cũng phải đoán.

## Học gì trước, và tự kiểm tra thế nào?

Thứ tự hợp lý là: đọc thành thạo trang Issue Details, sau đó gắn release cho mọi lần deploy, rồi thiết kế bộ tag cho domain của mình, cuối cùng mới đến data scrubbing và tracing. Bước nào cũng có thể làm thử trên một side project trong một buổi tối.

Bài tự kiểm tra: với app duyệt đơn ở trên, hãy quyết định năm trường sau đặt vào tag hay context. Đó là vai trò của user (nhân viên hay quản lý), trình duyệt, danh sách sản phẩm trong đơn, môi trường (staging hay production), và nội dung phản hồi của API lấy danh sách đơn.

Gợi ý đáp án: vai trò user, trình duyệt và môi trường là tag, vì bạn sẽ muốn hỏi "lỗi này có chỉ rơi vào quản lý, chỉ trên một trình duyệt, chỉ ở production không".

Danh sách sản phẩm và phản hồi API là context, vì chỉ có ích khi soi một event. Hai trường này cũng là nơi dữ liệu nhạy cảm dễ lọt vào nhất, nên phải đi qua data scrubbing.

Khi đã làm xong bài này trên side project, hãy viết nó lên CV đúng như việc đã làm. Một dòng như "thiết kế bộ tag, release tracking và PII scrubbing cho error monitoring của app" có trọng lượng hơn nhiều so với "biết dùng Sentry".

Ở site khách hàng, sau buổi go-live, lần tiếp theo khách nhớ đến bạn thường là lúc có sự cố. Khi đó, bạn trả lời được ngay lỗi gì, ở đâu, từ bản nào, hay phải chờ họ chụp thêm màn hình, phần lớn phụ thuộc vào cách bạn cấu hình Sentry từ ngày triển khai.

**Thử ngay tuần này:**

- Cài Sentry vào một side project, cố ý gây một lỗi rồi đọc trang Issue Details, từ stack trace đến breadcrumbs
- Gắn release cho mỗi lần deploy, resolve một issue rồi để lỗi đó quay lại ở bản sau và xem Sentry đánh dấu regression
- Liệt kê các trường nhạy cảm trong app của bạn (email, số điện thoại, token) rồi cấu hình data scrubbing cho chúng

## Nguồn

- [About Sentry | Sentry](https://sentry.io/about/)

- [Issues | Sentry Docs](https://docs.sentry.io/product/issues/)

- [Breadcrumbs (Browser JavaScript) | Sentry Docs](https://docs.sentry.io/platforms/javascript/enriching-events/breadcrumbs/)

- [Issue Details | Sentry Docs](https://docs.sentry.io/product/issues/issue-details/)

- [Releases | Sentry Docs](https://docs.sentry.io/product/releases/)

- [Data Scrubbing | Sentry Docs](https://docs.sentry.io/security-legal-pii/scrubbing/)

- [Sampling (Browser JavaScript) | Sentry Docs](https://docs.sentry.io/platforms/javascript/configuration/sampling/)

- [Seer | Sentry Docs](https://docs.sentry.io/product/ai-in-sentry/seer/)

- [Self-Hosted Sentry | Sentry Docs](https://develop.sentry.dev/self-hosted/)
