Giới thiệu
Network Error Logging (NEL) là một cơ chế để thu thập lỗi mạng phía máy khách từ một nguồn gốc.
Cơ chế này sử dụng tiêu đề phản hồi HTTP NEL để yêu cầu trình duyệt thu thập lỗi mạng, sau đó tích hợp với API Báo cáo để báo cáo lỗi cho một máy chủ.
Tổng quan về API Báo cáo cũ
Tiêu đề Report-To cũ
Để sử dụng API Báo cáo cũ, bạn cần thiết lập tiêu đề phản hồi HTTP Report-To. Giá trị của tiêu đề này là một đối tượng mô tả một nhóm điểm cuối để trình duyệt báo cáo lỗi:
Report-To:
{
"max_age": 10886400,
"endpoints": [{
"url": "https://analytics.provider.com/browser-errors"
}]
}
Nếu URL điểm cuối nằm trên một nguồn gốc khác với trang web của bạn, thì điểm cuối đó phải hỗ trợ các yêu cầu kiểm tra trước CORS. (ví dụ: Access-Control-Allow-Origin: *; Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS; Access-Control-Allow-Headers: Content-Type, Authorization, Content-Length, X-Requested-With).
Trong ví dụ này, việc gửi tiêu đề phản hồi này bằng trang chính sẽ định cấu hình trình duyệt để báo cáo các cảnh báo do trình duyệt tạo cho điểm cuối https://analytics.provider.com/browser-errors trong max_age giây.
Điều quan trọng cần lưu ý là tất cả các yêu cầu HTTP tiếp theo do trang thực hiện (đối với hình ảnh, tập lệnh, v.v.) đều bị bỏ qua. Quá trình định cấu hình được thiết lập trong phản hồi của trang chính.
Giải thích về các trường tiêu đề
Mỗi cấu hình điểm cuối chứa một tên group, max_age và mảng endpoints. Bạn cũng có thể chọn xem có nên cân nhắc các miền phụ khi báo cáo lỗi hay không bằng cách sử dụng trường include_subdomains.
| Trường | Loại | Mô tả |
|---|---|---|
group |
chuỗi | Không bắt buộc. Nếu không chỉ định tên group, thì điểm cuối sẽ được đặt tên là "default". |
max_age |
số | Bắt buộc. Một số nguyên không âm xác định thời gian tồn tại của điểm cuối tính bằng giây. Giá trị "0" sẽ khiến nhóm điểm cuối bị xoá khỏi bộ nhớ đệm báo cáo của tác nhân người dùng. |
endpoints |
Array<Object> | Bắt buộc. Một mảng các đối tượng JSON chỉ định URL thực tế của trình thu thập báo cáo. |
include_subdomains |
boolean | Không bắt buộc. Một giá trị boolean cho phép nhóm điểm cuối cho tất cả các miền phụ của máy chủ nguồn gốc hiện tại. Nếu bạn bỏ qua hoặc nhập bất kỳ giá trị nào khác ngoài "true", thì các miền phụ sẽ không được báo cáo cho điểm cuối. |
Tên group là một tên duy nhất dùng để liên kết một chuỗi với một điểm cuối. Sử dụng tên này ở những nơi khác tích hợp với API Báo cáo để tham chiếu đến một nhóm điểm cuối cụ thể.
Trường max-age cũng là bắt buộc và chỉ định thời gian trình duyệt nên sử dụng điểm cuối và báo cáo lỗi cho điểm cuối đó.
Trường endpoints là một mảng để cung cấp các tính năng dự phòng và cân bằng tải. Xem phần Dự phòng và cân bằng tải. Điều quan trọng cần lưu ý là
trình duyệt sẽ chỉ chọn một điểm cuối, ngay cả
khi nhóm liệt kê một số trình thu thập trong endpoints. Nếu bạn muốn gửi báo cáo đến nhiều máy chủ cùng một lúc, thì phần phụ trợ sẽ cần chuyển tiếp các báo cáo.
Trình duyệt gửi báo cáo như thế nào?
Trình duyệt định kỳ tạo lô báo cáo và gửi các báo cáo đó đến các điểm cuối báo cáo mà bạn định cấu hình.
Để gửi báo cáo, trình duyệt sẽ gửi một yêu cầu POST có Content-Type: application/reports+json và một nội dung chứa mảng cảnh báo/lỗi đã được ghi lại.
Khi nào trình duyệt gửi báo cáo?
Báo cáo được gửi ngoài băng tần từ ứng dụng của bạn, nghĩa là trình duyệt kiểm soát thời điểm gửi báo cáo đến(các) máy chủ của bạn.
Trình duyệt cố gắng gửi các báo cáo đã xếp hàng vào thời điểm thích hợp nhất. Thời điểm này có thể là ngay khi các báo cáo đã sẵn sàng (để cung cấp thông tin phản hồi kịp thời cho nhà phát triển), nhưng trình duyệt cũng có thể trì hoãn việc gửi nếu đang bận xử lý công việc có mức độ ưu tiên cao hơn hoặc nếu người dùng đang sử dụng mạng chậm và/hoặc bị tắc nghẽn vào thời điểm đó. Trình duyệt cũng có thể ưu tiên gửi báo cáo về một nguồn gốc cụ thể trước tiên nếu người dùng thường xuyên truy cập.
Khi sử dụng API Báo cáo, bạn không cần lo lắng về hiệu suất (ví dụ: tranh chấp mạng với ứng dụng của bạn). Ngoài ra, bạn không có cách nào để kiểm soát thời điểm trình duyệt gửi các báo cáo đã xếp hàng.
Định cấu hình nhiều điểm cuối
Một phản hồi có thể định cấu hình nhiều điểm cuối cùng một lúc bằng cách gửi nhiều tiêu đề Report-To:
Report-To: {
"group": "default",
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/browser-reports"
}]
}
Report-To: {
"group": "network-errors-endpoint",
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/network-errors"
}]
}
hoặc bằng cách kết hợp các tiêu đề đó thành một tiêu đề HTTP:
Report-To: {
"group": "network-errors-endpoint",
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/network-errors"
}]
},
{
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/browser-errors"
}]
}
Sau khi bạn gửi tiêu đề Report-To, trình duyệt sẽ lưu vào bộ nhớ đệm các điểm cuối theo giá trị max_age và gửi tất cả các cảnh báo/lỗi khó chịu đó đến các URL của bạn.
Dự phòng và cân bằng tải
Hầu hết thời gian, bạn sẽ định cấu hình một trình thu thập URL cho mỗi nhóm. Tuy nhiên, vì việc báo cáo có thể tạo ra một lượng lớn lưu lượng truy cập, nên thông số kỹ thuật này bao gồm các tính năng dự phòng và cân bằng tải lấy cảm hứng từ bản ghi DNS SRV.
Trình duyệt sẽ cố gắng hết sức để gửi báo cáo đến tối đa một điểm cuối trong một nhóm. Bạn có thể chỉ định weight cho các điểm cuối để phân phối tải, trong đó mỗi điểm cuối nhận được một phần lưu lượng truy cập báo cáo được chỉ định. Bạn cũng có thể chỉ định priority cho các điểm cuối để thiết lập trình thu thập dự phòng.
Trình thu thập dự phòng chỉ được thử khi quá trình tải lên trình thu thập chính không thành công.
Ví dụ: Tạo trình thu thập dự phòng tại https://backup.com/reports:
Report-To: {
"group": "endpoint-1",
"max_age": 10886400,
"endpoints": [
{"url": "https://example.com/reports", "priority": 1},
{"url": "https://backup.com/reports", "priority": 2}
]
}
Thiết lập Network Error Logging
Thiết lập
Để sử dụng NEL, hãy thiết lập tiêu đề Report-To bằng một trình thu thập sử dụng nhóm có tên:
Report-To: {
...
}, {
"group": "network-errors",
"max_age": 2592000,
"endpoints": [{
"url": "https://analytics.provider.com/networkerrors"
}]
}
Tiếp theo, hãy gửi tiêu đề phản hồi NEL để bắt đầu thu thập lỗi. Vì NEL là tính năng chọn tham gia cho một nguồn gốc, nên bạn chỉ cần gửi tiêu đề một lần. Cả NEL và Report-To sẽ áp dụng cho các yêu cầu trong tương lai đối với cùng một nguồn gốc và sẽ tiếp tục thu thập lỗi theo giá trị max_age đã dùng để thiết lập trình thu thập.
Giá trị tiêu đề phải là một đối tượng JSON chứa trường max_age và report_to. Sử dụng giá trị sau để tham chiếu đến tên nhóm của trình thu thập lỗi mạng:
GET /index.html HTTP/1.1
NEL: {"report_to": "network-errors", "max_age": 2592000}
Tài nguyên phụ
Ví dụ: Nếu example.com tải foobar.com/cat.gif và tài nguyên đó không tải được:
- Trình thu thập NEL của
foobar.comđược thông báo - Trình thu thập NEL của
example.comkhông được thông báo
Nguyên tắc chung là NEL tái tạo nhật ký phía máy chủ, chỉ được tạo trên ứng dụng.
Vì example.com không có khả năng hiển thị nhật ký máy chủ của foobar.com, nên trang này cũng không có khả năng hiển thị các báo cáo NEL của nhật ký đó.
Gỡ lỗi cấu hình báo cáo
Nếu bạn không thấy báo cáo xuất hiện trên máy chủ, hãy chuyển đến chrome://net-export/. Trang đó hữu ích cho việc xác minh rằng mọi thứ được định cấu hình đúng cách và báo cáo đang được gửi đi đúng cách.
Vậy còn ReportingObserver?
ReportingObserver là một cơ chế báo cáo có liên quan nhưng khác biệt. Cơ chế này dựa trên các lệnh gọi JavaScript.
Cơ chế này không phù hợp để ghi nhật ký lỗi mạng, vì lỗi mạng
không thể chặn thông qua JavaScript.
Máy chủ mẫu
Dưới đây là một ví dụ về máy chủ Node sử dụng Express. Ví dụ này cho thấy cách định cấu hình tính năng báo cáo lỗi mạng và tạo một trình xử lý chuyên dụng để ghi lại kết quả.
const express = require('express');
const app = express();
app.use(
express.json({
type: ['application/json', 'application/reports+json'],
}),
);
app.use(express.urlencoded());
app.get('/', (request, response) => {
// Note: report_to and not report-to for NEL.
response.set('NEL', `{"report_to": "network-errors", "max_age": 2592000}`);
// The Report-To header tells the browser where to send network errors.
// The default group (first example below) captures interventions and
// deprecation reports. Other groups, like the network-error group, are referenced by their "group" name.
response.set(
'Report-To',
`{
"max_age": 2592000,
"endpoints": [{
"url": "https://reporting-observer-api-demo.glitch.me/reports"
}],
}, {
"group": "network-errors",
"max_age": 2592000,
"endpoints": [{
"url": "https://reporting-observer-api-demo.glitch.me/network-reports"
}]
}`,
);
response.sendFile('./index.html');
});
function echoReports(request, response) {
// Record report in server logs or otherwise process results.
for (const report of request.body) {
console.log(report.body);
}
response.send(request.body);
}
app.post('/network-reports', (request, response) => {
console.log(`${request.body.length} Network error reports:`);
echoReports(request, response);
});
const listener = app.listen(process.env.PORT, () => {
console.log(`Your app is listening on port ${listener.address().port}`);
});