Tôi xây hệ thống báo lỗi phía client vì muốn nhìn thấy những vấn đề người dùng thật gặp phải mà tôi khó tái hiện ổn định ở máy local. Bộ báo lỗi làm đúng điều tôi yêu cầu: bắt lỗi rồi gửi cho tôi.
Vấn đề là gần như mọi thứ đều trông nghiêm trọng như nhau.
Script phân tích của bên ngoài tải không được? Cảnh báo đỏ. Script quảng cáo bị chặn? Cảnh báo đỏ. Trình thu thập dữ liệu không tải được Google Analytics? Cảnh báo đỏ. Video xem trước gọi play() rồi bị dừng trước khi Promise hoàn tất? Cảnh báo đỏ. Xuất hiện Script error. không có nguồn hay stack hữu ích? Lại cảnh báo đỏ.
Trong cùng luồng đó cũng có những lỗi thực sự cần xử lý: URL của chính ứng dụng bị ghép sai thành https://example.comhttps://example.com/..., và trình duyệt không tải được một tệp Next.js của ứng dụng dưới /_next/static/chunks/....
Lớp thu thập hoạt động. Hệ thống giám sát thì chưa.
Sự khác biệt đó thay đổi cách tôi nhìn về khả năng quan sát frontend. Một sự kiện lỗi chỉ là bằng chứng rằng có điều gì đó đã xảy ra. Nó chưa phải chẩn đoán, mức độ nghiêm trọng hay một sự cố.
Sai lầm đầu tiên là coi từ “error” đồng nghĩa với “khẩn cấp”
Mental model ban đầu gần như thế này:
browser báo error
↓
gửi CLIENT ERROR
↓
developer phải xử lý
Mô hình này trộn lẫn nhiều câu hỏi khác nhau. Lỗi có nằm trong code của tôi không? Route đang mở có thực sự hỏng không? Đây có phải lần hủy được dự kiến trước không? Trình duyệt có đủ thông tin để xác định nguồn không? Ứng dụng đã phục hồi chưa? Mười thông báo là mười sự cố, hay mười triệu chứng của một sự cố?
Trước khi trả lời được những câu hỏi đó, một sự kiện không nên tự động biến thành cảnh báo.
Trong một lần rà soát sớm, tôi có khoảng mười tám thông báo trước mặt. Phần lớn chỉ là nhiễu từ dịch vụ bên ngoài hoặc hành vi bình thường của vòng đời. Hai trường hợp nổi bật: URL của ứng dụng bị biến dạng rõ ràng là bug, còn một chunk JavaScript của ứng dụng không tải được có thể khiến trang thiếu code cần thiết. Dù vậy, bộ báo lỗi vẫn hiển thị gần như mọi thứ với độ khẩn cấp ngang một quảng cáo bị chặn.
Từ đó tôi không còn xem “thu thập mọi lỗi trình duyệt” và “xây giám sát production” là cùng một bài toán. Lớp thu thập giữ bằng chứng; lớp hệ thống giám sát biến bằng chứng thành quyết định.
Trình duyệt không có một kênh lỗi duy nhất mang cùng ý nghĩa cho mọi loại hỏng hóc
Các lỗi phía client khác nhau không đi vào hệ thống với cùng ngữ nghĩa.
Sự kiện error trên window được dùng cho lỗi script đồng bộ và cũng tham gia vào lỗi tải tài nguyên. Promise bị reject mà không được xử lý đi theo đường khác: trình duyệt phát unhandledrejection. Các phần tử tải script, hình ảnh hoặc media cũng có thể phát error riêng. React và Next.js còn thêm tín hiệu từ error boundary ở tầng framework.
window.error
→ một synchronous script error có thể đã thoát ra ngoài
unhandledrejection
→ rejected Promise chưa được handle ở thời điểm đó
element error
→ resource không tải hoặc không dùng được
framework boundary
→ rendering hoặc execution chạm error boundary
Hook toàn cục nhìn thấy triệu chứng tại biên hệ thống; nó không nhất thiết biết toàn bộ chuỗi nguyên nhân.
Sau khi chấp nhận điều đó, tôi ngừng ép mọi sự kiện ngay lập tức thành một Error chung với cùng mức độ nghiêm trọng.
Nguồn sở hữu là bộ lọc hữu ích đầu tiên
Cách chia đầu tiên thực sự hữu ích là xác định code hoặc tài nguyên bị lỗi thuộc về ai.
Lỗi tải /_next/static/chunks/app/... không giống SDK quảng cáo trên nguồn khác bị lỗi. URL hỏng do trình tạo URL của tôi sinh ra không giống yêu cầu phân tích bị chặn. Lỗi từ tiện ích mở rộng của trình duyệt lại là một nhóm khác.
- Ứng dụng của tôi: JavaScript, CSS, API, media và các URL do code của tôi tạo;
- Framework và runtime: Next.js hoặc React nằm trong đường thực thi của ứng dụng;
- Tích hợp bên ngoài: phân tích, quảng cáo, widget và SDK ngoài;
- Môi trường: tiện ích mở rộng trình duyệt, trình thu thập dữ liệu, trạng thái mạng, công cụ bảo mật riêng tư và hành vi đặc thù của trình duyệt.
Điều này không có nghĩa bên thứ ba là không quan trọng. Nhà cung cấp thanh toán hoặc xác thực có thể rất quan trọng, và lỗi quảng cáo có thể ảnh hưởng doanh thu. Nhưng tích hợp gặp vấn đề không tự động đồng nghĩa ứng dụng bị crash.
Nếu mọi thứ đều vào cùng một kênh cảnh báo khẩn, kênh đó sẽ mất ý nghĩa.
Hai lỗi thuộc về ứng dụng đã dạy tôi thế nào là một tín hiệu có thể hành động
Malformed URL là trường hợp đơn giản:
https://example.comhttps://example.com/resource
Trường hợp này không cần suy đoán về AdBlock, VPN hay chính sách trình duyệt. Bản thân URL đã sai. Ở đâu đó, code đang nối nguồn vào một giá trị vốn đã là URL tuyệt đối.
Sự kiện này có thể hành động ngay vì bằng chứng cụ thể, tài nguyên thuộc về tôi và lỗi chỉ tới một đường code tôi kiểm soát.
Lỗi chunk Next.js thì khác:
Failed to load script:
/_next/static/chunks/9253.647385b4be0958e4.js
Nó cũng thuộc ứng dụng và có thể làm hỏng trang, nhưng sự kiện không chứng minh nguyên nhân. Client cũ có thể yêu cầu tệp của lần deploy trước; yêu cầu có thể timeout; reverse proxy hoặc CDN có thể lỗi; kết nối có thể mất; hoặc tệp thực sự không tồn tại.
Phản ứng đúng không phải “tôi biết nguyên nhân”, mà là “nhóm lỗi này có mức ưu tiên cao và cần thêm ngữ cảnh”.
Mức độ nghiêm trọng có thể cao ngay cả khi độ chắc chắn về nguyên nhân còn thấp.
Script error. là manh mối, không phải stack trace
Error: Script error.
filename: unknown
line: 0
column: 0
Nó trông nghiêm trọng nhưng hầu như không mang thông tin.
Trình duyệt cố ý giới hạn chi tiết lỗi script cross-nguồn. MDN giải thích rằng nếu không có cấu hình CORS phù hợp, window.onerror chỉ nhận được thông tin hạn chế; hành vi crossorigin của <script> ảnh hưởng trực tiếp đến việc có lấy được đầy đủ chi tiết lỗi hay không.
Vì vậy tôi không tự động diễn giải một Script error. mơ hồ thành “ứng dụng của tôi crash”. Nguồn có thể là code của tôi, code bên thứ ba, code bị chèn vào, hoặc một lỗi mà trình duyệt không được phép hiển thị chi tiết vì giới hạn cross-nguồn.
Tôi giữ sự kiện lại và tương quan nó với trang, bản build, trình duyệt và các sự kiện gần đó; nhưng một 0:0 đơn lẻ không tạo cảnh báo khẩn. Nếu cùng dấu hiệu bắt đầu tập trung quanh một phiên bản hoặc route cụ thể, ưu tiên mới thay đổi.
Unknown không đồng nghĩa harmless. Cũng không đồng nghĩa critical.
AbortError có thể hoàn toàn là lỗi thật và vẫn là một phần bình thường của vòng đời
Video xem trước cho tôi ví dụ rõ nhất:
AbortError:
The play() request was interrupted by a call to pause()
HTMLMediaElement.play() trả về Promise, và Promise đó có thể bị reject. Các thao tác trong vòng đời media cũng có thể cố ý hủy playback đang chờ; MDN ghi rõ rằng load() hủy các Promise play() đang chờ bằng AbortError.
Trong lưới xem trước, điều này dễ xảy ra mà người dùng không thấy sản phẩm hỏng. Item đi vào viewport, code gọi play(); người dùng cuộn, item ra ngoài; trước khi playback bắt đầu xong, code dừng hoặc thay media.
Promise bị reject là thật. Sự cố đối với người dùng có thể hoàn toàn không tồn tại.
Cách xử lý đúng thường nằm ngay cạnh chỗ gọi: xử lý Promise tại đó và tách hủy dự kiến khỏi lỗi playback thật. unhandledrejection nên là lưới an toàn, không phải nơi đầu tiên ta mới hiểu vòng đời bình thường của component.
Lỗi từ bên thứ ba cần mô hình sức khỏe riêng
Log ban đầu của tôi có rất nhiều lỗi từ các domain phân tích và quảng cáo. Một số đến từ trình duyệt chú trọng riêng tư, một số từ trình thu thập dữ liệu. Một trong những cảnh báo khẩn vô ích nhất là trình thu thập dữ liệu không tải được Google Analytics.
Điều đó chỉ chứng minh một yêu cầu mạng đã thất bại. Nó gần như không cho biết người dùng thật có dùng được ứng dụng hay không.
Lưu sự kiện không phải vấn đề. Vấn đề là đưa nó vào cùng luồng sự cố với một chunk JavaScript thuộc ứng dụng không tải được.
- Ứng dụng có thực sự hỏng đối với người dùng không?
- Tích hợp bên ngoài có đang khỏe không?
Script quảng cáo bị chặn có thể đi vào metric giao quảng cáo. Lỗi phân tích có thể đi vào metric độ phủ phân tích. Không cái nào nên đánh thức tôi với nhãn “frontend crash” trừ khi có bằng chứng chức năng cốt lõi thực sự phụ thuộc vào nó.
Việc tách riêng thậm chí làm lỗi bên thứ ba dễ nhìn hơn: tôi có thể gom theo nhà cung cấp, trình duyệt và khu vực thay vì nhận chúng như nhiễu đỏ ngẫu nhiên.
navigator.onLine là ngữ cảnh, không phải bằng chứng kết nối
Tôi cũng bắt đầu ghi lại xem trình duyệt có tự coi mình là online hay không. Thông tin này hữu ích, nhưng chỉ như một gợi ý.
Có những sự kiện bị logic bổ sung xếp là lỗi mạng trong khi cùng log vẫn ghi:
Online: true
Không hề mâu thuẫn. MDN cảnh báo rõ rằng navigator.onLine dựa trên heuristic của trình duyệt và hệ điều hành. Máy có thể nối LAN nhưng vẫn không tới được nguồn của tôi. VPN, firewall, DNS và sự cố mạng một phần làm bức tranh phức tạp hơn.
online === false
→ hint mạnh về problem ở environment
online === true
→ KHÔNG chứng minh origin hoặc resource reachable
Phân biệt nhỏ này ngăn hệ thống hệ thống giám sát biến một gợi ý thành chẩn đoán tự tin nhưng sai.
Một lỗi gốc có thể tạo ra nhiều sự kiện trình duyệt
Sau khi cải thiện thu thập, một loại nhiễu khác lộ rõ: một sự cố có thể sinh nhiều thông báo.
Một chunk JavaScript có thể phát resource.error trước, loader module sau đó ném ChunkLoadError, React hoặc Next.js đi qua error boundary, rồi logic khôi phục lên lịch reload. Nếu mỗi tầng gửi một cảnh báo riêng, một thao tác của người dùng trông như nhiều lỗi production độc lập.
Năm thông báo tạo cảm giác như năm người dùng bị ảnh hưởng, dù chúng có thể đến từ một session và một tài nguyên.
Dedupe chỉ theo nội dung thông báo là không đủ. Cần tương quan ở cấp sự cố:
session
+ time window ngắn
+ normalized error class
+ first-party resource
+ client build
+ route
Tôi vẫn muốn giữ sự kiện thô, nhưng thứ gửi cho con người nên là biểu diễn sự cố có tín hiệu mạnh nhất. Nếu error boundary đã có stack từ code của tôi và URL chính xác của chunk, lỗi tài nguyên chung xuất hiện trước không cần tạo cảnh báo khẩn thứ hai.
Cảnh báo theo sự cố. Lưu sự kiện.
Ngữ cảnh quanh lỗi về sau trở nên giá trị hơn chính chuỗi lỗi
Telemetry sau này của tôi có cấu trúc hơn nhiều:
clientBuildId
resource URL
resourceResponseStatus
resourceTransferSize
resourceDurationMs
serviceWorkerVersion
serviceWorkerController
serviceWorkerState
chunkRecoveryScheduled
online
stack / component stack
Với media, tôi còn ghi mã lỗi media, HTTP status khi có thể quan sát độc lập, Content-Type thực tế được trả về, và lỗi có vẻ thuộc HTTP hay đường truyền mạng.
Những field đó cho phép hỏi những điều một exception string chung không trả lời được: lỗi có bắt đầu ở một bản build cụ thể không? Trình duyệt có nhận HTTP response không? Service Worker có điều khiển trang không? Logic khôi phục đã chạy chưa? Nhiều sự kiện có chỉ cùng tài nguyên không? Route hiện tại có thực sự bị ảnh hưởng không?
Resource Timing API có thể cung cấp thời lượng tài nguyên, thông tin transfer và response status ở nơi được hỗ trợ, cho phép. Các field này có giới hạn: timing cross-nguồn bị hạn chế, tài nguyên từ cache có thể có transferSize: 0, và responseStatus không có ở mọi trình duyệt. Vì vậy null và 0 phải được giữ như các trạng thái có ý nghĩa, không biến thành sự chắc chắn giả.
ChunkLoadError là triệu chứng, không phải máy dò 404
Một sự kiện sau đó thay đổi cách tôi đọc lỗi chunk.
Trình duyệt báo ChunkLoadError cho một chunk layout của Next.js, và telemetry đã làm giàu đồng thời có:
resourceResponseStatus: 200
resourceDurationMs: 170523
serviceWorkerState: activated
chunkRecoveryScheduled: true
Thời lượng ghi được khoảng 170 giây. Dù nguyên nhân gốc chính xác của sự cố đó là gì, dữ liệu này đã đủ để bác bỏ một quy tắc quá đơn giản:
ChunkLoadError === server trả 404
Các lỗi chunk khác hoàn toàn không có response status quan sát được. Một số xuất hiện như timeout, một số có thông tin transfer. Cùng lớp lỗi; bằng chứng xung quanh khác nhau.
Điều này đặc biệt quan trọng với Next.js vì tệp dưới /_next/static/ thường có content hash và được thiết kế cho cache immutable. Tài liệu self-hosting Next.js hiện tại mô tả cache header dài hạn cho các asset hashed immutable này. Vì vậy ChunkLoadError có thể liên quan đến lệch phiên bản khi deploy, client cũ, đường truyền mạng, reverse proxy, CDN, cache, Service Worker hoặc artifact bản build thực sự bị thiếu.
Tôi không muốn lớp cảnh báo tự bịa nguyên nhân. Tôi muốn nó giữ bằng chứng cần cho điều tra.
Lỗi media dạy cùng bài học từ một tầng khác
Trong một số sự kiện, phần tử media báo:
MEDIA_ELEMENT_ERROR: Format error
Chỉ nhìn thông báo này thì rất giống lỗi tương thích codec.
Nhưng kiểm tra đường truyền bổ sung cho một số sự kiện cho thấy:
HTTP status: 410
Content-Type: text/html; charset=utf-8
failure kind: http
Trình duyệt yêu cầu video nhưng nhận response lỗi HTTP chứa HTML. Phần tử media không thể decode HTML như video, nên triệu chứng bên ngoài thành “Format error”. Chẩn đoán hữu ích nằm ở tầng truyền dữ liệu.
Tầng phát hiện lỗi trước tiên không nhất thiết là tầng gây ra lỗi.
“Lỗi codec”, “mạng gián đoạn”, “bug cache” và “chunk bị thiếu” đều là kết luận. Telemetry trước hết nên mô tả điều đã quan sát được.
Tôi đánh giá lỗi trình duyệt theo năm chiều
1. Nguồn sở hữu
Nguồn thuộc chính ứng dụng, framework hoặc runtime, tích hợp bên ngoài hay môi trường?
2. Tác động lên người dùng
Route đang hoạt động, rendering, xác thực, chat, checkout hoặc luồng cốt lõi khác có thực sự hỏng không? Hay chỉ quảng cáo tùy chọn, phân tích, preload hoặc xem trước bị lỗi trong khi trang vẫn dùng được?
3. Chất lượng bằng chứng
Tôi có stack từ code của mình, URL tài nguyên, HTTP status, ID bản bản build và component stack không? Hay chỉ có Script error. tại 0:0?
4. Mức độ lặp lại và phạm vi lan rộng
Đây là một sự kiện từ một session, hay cùng chữ ký xuất hiện trên nhiều người dùng, route và trình duyệt khác nhau sau cùng một phiên bản?
5. Khả năng phục hồi
Ứng dụng có tự phục hồi không? Reload chunk đã được lên lịch chưa? Fallback có hoạt động không? Người dùng vẫn bị kẹt chứ?
first-party rõ ràng
+ user impact cao
+ evidence mạnh
+ nhiều session
+ không recovery
= urgent incident
third-party
+ chức năng optional
+ evidence yếu
+ isolated
+ user không bị ảnh hưởng
= metric hoặc low priority
Việc loại bỏ sự kiện phải thận trọng
Khi nhiễu bắt đầu khó chịu, rất dễ muốn viết hàng chục regular expression rồi bỏ mọi thứ phiền phức. Điều đó nguy hiểm.
Nếu chặn mọi AbortError, tôi có thể che mất các yêu cầu API thật sự bị hủy. Nếu xóa mọi Script error., tôi có thể bỏ lỡ một cluster đặc thù trình duyệt chỉ trở nên có ý nghĩa sau khi tổng hợp. Nếu bỏ qua mọi lỗi bên thứ ba, tôi có thể bỏ lỡ nhà cung cấp thanh toán, xác thực hoặc consent đang hỏng.
ALERT
→ incident mạnh, cần hành động
RETAIN / AGGREGATE
→ giữ và đếm; alert khi tạo thành cluster
METRIC / SAMPLE
→ noise dự kiến hoặc low-impact; giữ trend và ví dụ
Hệ thống có thể yên tĩnh hơn mà không trở nên mù.
Bộ phân loại tốt về bản chất là chính sách được viết thành code
Đoạn code sau không được sao chép từ dự án production của tôi. Nó chỉ là ví dụ ngắn về chính sách mà tôi ước mình đã dùng từ đầu:
function classifyClientEvent(event) {
const owner = classifyOwner(event);
if (isExpectedMediaCancellation(event)) {
return { severity: "metric", reason: "expected-cancellation" };
}
if (owner === "first-party" && breaksActiveRoute(event)) {
return { severity: "alert", reason: "first-party-user-impact" };
}
if (isActiveFirstPartyChunkFailure(event)) {
return { severity: "alert", reason: "application-chunk" };
}
if (owner === "third-party") {
return { severity: "aggregate", reason: "integration-health" };
}
if (isOpaqueScriptError(event)) {
return { severity: "aggregate", reason: "insufficient-evidence" };
}
return { severity: "aggregate", reason: "needs-correlation" };
}
Phần khó nằm trong các hàm như breaksActiveRoute(). Chỉ tên exception là không đủ; cần ngữ cảnh route, quyền sở hữu tài nguyên, dữ liệu error boundary và đôi khi cả hiểu biết đặc thù sản phẩm.
Dấu vân tay sự cố nên bám theo chính sự cố, không phải nội dung thông báo
So sánh thông báo y hệt nhau là chiến lược dedupe kém. Offset trong stack minified thay đổi theo bản build, hash chunk thay đổi, URL có identifier động, và cách diễn đạt của trình duyệt cũng khác.
{
errorClass,
normalizedFirstPartyResource,
routeFamily,
clientBuild,
sessionId,
shortTimeBucket
}
Với crash toàn ứng dụng, frame trên cùng thuộc code của tôi trong stack có thể hữu ích hơn. Với lỗi chunk, tài nguyên chunk đã chuẩn hóa hữu ích hơn. Với sự cố truyền media, lớp lỗi HTTP và route media có thể quan trọng hơn thông báo lỗi ngoài cùng của trình duyệt.
resource.error
→ ChunkLoadError
→ framework boundary
→ recovery scheduled
Nhờ vậy, một chuỗi sự kiện liên quan có thể trở thành một sự cố với bốn quan sát đính kèm, thay vì bốn lỗi khẩn độc lập.
Kênh cảnh báo khẩn nên có nhiệm vụ hẹp hơn nhiều
Tôi sẽ dành cảnh báo tức thời cho các trường hợp như: lỗi runtime của ứng dụng có stack hữu ích và làm hỏng route đang hoạt động; error boundary React/Next.js thực sự ảnh hưởng tương tác; JavaScript hoặc CSS của ứng dụng mà route hiện tại cần nhưng không tải được; ChunkLoadError lặp lại ở nhiều session hoặc bản build; lỗi API hoặc dữ liệu cốt lõi khiến người dùng không thể tiếp tục; hoặc vi phạm quy tắc rõ ràng của code mình như tạo URL sai.
Một Script error. mơ hồ đơn lẻ, lỗi tài nguyên ứng dụng đã khôi phục thành công, lỗi media chưa rõ tầng gốc, hoặc bất thường đặc thù trình duyệt cần gom nhóm trước—tôi sẽ lưu nhưng không cảnh báo ngay.
Và thường tôi đưa vào metric hoặc chẩn đoán lấy mẫu: lỗi tài nguyên quảng cáo/phân tích đã biết; AbortError media đúng như dự kiến; lỗi bên thứ ba chỉ xảy ra với trình thu thập dữ liệu; lỗi có dấu hiệu mất kết nối mạnh; và tài nguyên thăm dò tùy chọn không ảnh hưởng route hoạt động.
Cảnh báo khẩn nên đại diện cho tác động người dùng có thể hành động, không phải số lượng thô lời phàn nàn của trình duyệt.
Tôi thích đo sự cố hơn là một “tổng số lỗi” duy nhất
- Sự cố của ứng dụng trên mỗi 1.000 session;
- Session bị ảnh hưởng theo ID bản bản build;
- Sự cố error boundary theo route;
- Lỗi chunk theo tài nguyên và triển khai;
- Tỷ lệ lỗi tích hợp bên ngoài theo nhà cung cấp;
- Khối lượng hủy dự kiến, để một đợt tăng bất ngờ vẫn nhìn thấy;
- Tỷ lệ phục hồi thành công;
- Số sự cố duy nhất tách khỏi số sự kiện thô.
“Có một sự kiện xảy ra” hiếm khi là ngưỡng cảnh báo production tốt. “Cùng sự cố của ứng dụng hiện ảnh hưởng nhiều session độc lập trên bản build mới và khôi phục thất bại” gần với tín hiệu đáng hành động hơn nhiều.
Giám sát phía client vẫn không thể tự mình chứng minh nguyên nhân gốc
Telemetry trình duyệt có giới hạn rõ ràng.
Không có HTTP status có thể nghĩa là API không cung cấp dữ liệu, trình duyệt không hỗ trợ field, có hạn chế cross-nguồn, yêu cầu bị hủy hoặc còn khoảng trống quan sát khác. Service Worker đang hoạt động không chứng minh nó trả tài nguyên cũ. ChunkLoadError xuất hiện sau triển khai không chứng minh lệch phiên bản. online: true cũng không chứng minh nguồn truy cập được.
Giám sát phía client giúp thu hẹp các giả thuyết. Để chứng minh nguyên nhân vẫn có thể cần log server, log reverse proxy, manifest triển khai, trạng thái cache và tái hiện thực tế.
Tôi cũng không muốn observability biến thành thu thập dữ liệu người dùng vô hạn. Mỗi field chỉ nên tồn tại nếu thực sự giúp phân biệt kiểu lỗi.
Telemetry tốt hơn không có nghĩa telemetry nhiều hơn; mà là telemetry phân biệt lỗi tốt hơn.
Quy tắc của tôi bây giờ: thu thập sự kiện, điều tra sự cố, cảnh báo theo tác động
Ban đầu tôi chỉ muốn hệ thống báo lỗi trả lời một câu: “Có gì hỏng không?” Trong production, câu hỏi đó quá rộng để hữu ích. Luôn có trình thu thập dữ liệu không tới được analytics, công cụ riêng tư chặn quảng cáo, Promise media bị hủy có chủ ý, người dùng mất mạng hoặc SDK bên ngoài hành xử sai.
Có phải của chúng ta không?
User có mất functionality không?
Evidence mạnh tới đâu?
Có lặp lại không?
Application đã recover chưa?
Đây là nhiều event hay một incident?
Khi tôi xây hệ thống giám sát quanh những câu hỏi hẹp hơn, dòng thông báo đỏ mới thực sự chuyển từ nhiễu thành công cụ kỹ thuật.
Lỗi trình duyệt là một quan sát. Sự cố là lời giải thích có tương quan về tác động lên người dùng. Cảnh báo là quyết định rằng đã đến lúc con người cần hành động.
Tôi không muốn coi ba thứ đó là một nữa.