Введение
Журналирование сетевых ошибок (Network Error Logging, NEL) — это механизм сбора сетевых ошибок на стороне клиента, возникающих в источнике.
Он использует заголовок HTTP-ответа NEL , чтобы сообщить браузеру о необходимости сбора сетевых ошибок, а затем интегрируется с API отчетов для отправки сообщений об ошибках на сервер.
Обзор устаревшего API для создания отчетов
Устаревший Report-To получателя
Для использования устаревшего API отчетов вам потребуется установить заголовок HTTP-ответа Report-To . Его значением является объект, описывающий группу конечных точек, которым браузер будет сообщать об ошибках:
Report-To:
{
"max_age": 10886400,
"endpoints": [{
"url": "https://analytics.provider.com/browser-errors"
}]
}
Если URL-адрес вашей конечной точки находится в другом месте, отличном от вашего сайта, конечная точка должна поддерживать предварительные запросы CORS. (например 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 ).
В приведенном примере отправка этого заголовка ответа вместе с вашей главной страницей настраивает браузер на отправку сгенерированных браузером предупреждений на конечную точку https://analytics.provider.com/browser-errors в течение max_age секунд. Важно отметить, что все последующие HTTP-запросы, выполняемые страницей (для изображений, скриптов и т. д.), игнорируются. Конфигурация устанавливается во время отправки ответа от главной страницы.
Пояснение к полям заголовка
Каждая конфигурация конечной точки содержит имя group , max_age и массив endpoints . Вы также можете выбрать, следует ли учитывать поддомены при сообщении об ошибках, используя поле include_subdomains .
| Поле | Тип | Описание |
|---|---|---|
group | нить | Необязательно. Если имя group не указано, конечной точке присваивается имя "default". |
max_age | число | Обязательное значение . Неотрицательное целое число, определяющее время жизни конечной точки в секундах. Значение «0» приведет к удалению группы конечных точек из кэша отчетов пользовательского агента. |
endpoints | Массив<Объект> | Обязательный параметр . Массив JSON-объектов, указывающих фактический URL-адрес вашего сборщика отчетов. |
include_subdomains | логический | Необязательный параметр. Логическое значение, которое включает группу конечных точек для всех поддоменов хоста текущего источника. Если параметр опущен или имеет значение, отличное от «true», поддомены не передаются на конечную точку. |
Имя group — это уникальное имя, используемое для связывания строки с конечной точкой. Используйте это имя в других местах, интегрированных с API отчетов, для ссылки на конкретную группу конечных точек.
Поле max-age также является обязательным и указывает, как долго браузер должен использовать конечную точку и сообщать ей об ошибках.
Поле endpoints представляет собой массив, обеспечивающий функции отказоустойчивости и балансировки нагрузки. См. раздел « Отказоустойчивость и балансировка нагрузки» . Важно отметить, что браузер выберет только одну конечную точку , даже если в группе endpoints указано несколько сборщиков данных. Если вы хотите отправить отчет на несколько серверов одновременно, ваш бэкэнд должен будет перенаправлять отчеты.
Как браузер отправляет отчеты?
Браузер периодически формирует пакеты отчетов и отправляет их на настроенные вами конечные точки для формирования отчетов.
Для отправки отчетов браузер отправляет POST запрос с Content-Type: application/reports+json и телом, содержащим массив предупреждений/ошибок, которые были зафиксированы.
Когда браузер отправляет отчеты?
Отчеты передаются из вашего приложения внеполосным способом , то есть браузер контролирует, когда отчеты отправляются на ваш(и) сервер(ы).
Браузер пытается доставить отчеты из очереди в наиболее подходящее время. Это может быть сразу после их готовности (для своевременной обратной связи с разработчиком), но браузер также может задержать доставку, если он занят обработкой более приоритетных задач или если пользователь в это время находится в медленной и/или перегруженной сети. Браузер также может отдавать приоритет отправке отчетов о конкретном источнике, если пользователь является частым посетителем.
При использовании API отчетов практически не возникает проблем с производительностью (например, конфликтов с сетью вашего приложения). Также нет возможности контролировать, когда браузер отправляет отчеты из очереди.
Настройка нескольких конечных точек
В одном ответе можно настроить сразу несколько конечных точек, отправив несколько заголовков 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"
}]
}
или объединив их в один 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"
}]
}
После отправки заголовка Report-To браузер кэширует конечные точки в соответствии с их значениями max_age и отправляет все эти неприятные предупреждения/ошибки в консоль на ваши URL-адреса.
Переключение на резервный сервер и балансировка нагрузки
В большинстве случаев вам потребуется настроить один сборщик URL-адресов на группу. Однако, поскольку формирование отчетов может генерировать значительный трафик, спецификация включает функции отказоустойчивости и балансировки нагрузки, вдохновленные записью DNS SRV .
Браузер постарается отправить отчет не более чем на одну конечную точку в группе. Конечным точкам можно присвоить weight для распределения нагрузки, при этом каждая конечная точка будет получать определенную долю трафика, поступающего в отчет. Конечным точкам также можно присвоить priority для настройки резервных сборщиков данных.
Резервные сборщики данных используются только в случае неудачной загрузки данных в основные сборщики.
Пример : Создайте резервный сборщик данных по адресу 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}
]
}
Настройка регистрации сетевых ошибок
Настраивать
Для использования NEL настройте заголовок Report-To с помощью сборщика данных, использующего именованную группу:
Report-To: {
...
}, {
"group": "network-errors",
"max_age": 2592000,
"endpoints": [{
"url": "https://analytics.provider.com/networkerrors"
}]
}
Далее отправьте заголовок ответа NEL , чтобы начать сбор ошибок. Поскольку NEL является необязательным для источника, вам нужно отправить заголовок только один раз. И NEL , и Report-To будут применяться к будущим запросам к тому же источнику и будут продолжать собирать ошибки в соответствии со значением max_age , которое использовалось при настройке сборщика.
В заголовке должен быть JSON-объект, содержащий поля max_age и report_to . Используйте последнее поле для ссылки на имя группы сборщика сетевых ошибок:
GET /index.html HTTP/1.1
NEL: {"report_to": "network-errors", "max_age": 2592000}
Субресурсы
Пример : Если example.com загружает foobar.com/cat.gif , а этот ресурс не загружается:
- Сотрудник, занимающийся сбором NEL на
foobar.com, уведомлен. - Сборщик NEL от
example.comне получает уведомления.
Как правило, NEL воспроизводит серверные логи, сгенерированные на стороне клиента.
Поскольку example.com не имеет доступа к серверным журналам foobar.com , он также не имеет доступа к его отчетам NEL.
Отладка настроек отчетов
Если отчеты не отображаются на вашем сервере, перейдите по адресу chrome://net-export/ . Эта страница полезна для проверки правильности настроек и корректной отправки отчетов.
А что насчет ReportingObserver?
ReportingObserver — это связанный, но отличающийся механизм формирования отчетов. Он основан на вызовах JavaScript. Он не подходит для регистрации сетевых ошибок , поскольку сетевые ошибки нельзя перехватить с помощью JavaScript.
Пример сервера
Ниже приведён пример Node-сервера, использующего Express. Он демонстрирует, как настроить отчётность об ошибках сети и создаёт специальный обработчик для захвата результата.
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}`);
});