Introdução
O Network Error Logging (NEL) é um mecanismo para coletar erros de rede do lado do cliente de uma origem.
Ele usa o cabeçalho de resposta HTTP NEL para instruir o navegador a coletar erros de rede e, em seguida, se integra à API Reporting para informar os erros a um servidor.
Visão geral da API Reporting legada
O cabeçalho Report-To legado
Para usar a API Reporting legada, é necessário definir um cabeçalho de resposta HTTP Report-To. O
valor dele é um objeto que descreve um grupo de endpoints para o navegador
informar erros:
Report-To:
{
"max_age": 10886400,
"endpoints": [{
"url": "https://analytics.provider.com/browser-errors"
}]
}
Se o URL do endpoint estiver em uma origem diferente do seu site, o endpoint precisará ser compatível com solicitações de simulação de CORS. (por exemplo, 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).
No exemplo, o envio desse cabeçalho de resposta com sua página principal
configura o navegador para informar avisos gerados pelo navegador
ao endpoint https://analytics.provider.com/browser-errors por max_age segundos.
É importante observar que todas as solicitações HTTP subsequentes feitas pela página
(para imagens, scripts etc.) são ignoradas. A configuração é definida durante
a resposta da página principal.
Explicação dos campos de cabeçalho
Cada configuração de endpoint contém um nome group, max_age e uma matriz
endpoints. Também é possível escolher se os subdomínios serão considerados ao informar
erros usando o campo include_subdomains.
| Campo | Tipo | Descrição |
|---|---|---|
group |
string | Opcional. Se um nome de group não for especificado, o endpoint receberá o nome "default". |
max_age |
número | Obrigatório. Um número inteiro não negativo que define o ciclo de vida do endpoint em segundos. Um valor "0" fará com que o grupo de endpoints seja removido do cache de relatórios do user agent. |
endpoints |
Matriz<Objeto> | Obrigatório. Uma matriz de objetos JSON que especificam o URL real do coletor de relatórios. |
include_subdomains |
booleano | Opcional. Um booleano que ativa o grupo de endpoints para todos os subdomínios do host da origem atual. Se omitido ou se for qualquer valor diferente de "true", os subdomínios não serão informados ao endpoint. |
O nome group é um nome exclusivo usado para associar uma string a um endpoint. Use esse nome em outros lugares que se integram
à API Reporting para se referir a um grupo de endpoints específico.
O campo max-age também é obrigatório e especifica por quanto tempo o navegador deve usar o endpoint e relatar erros a ele.
O campo endpoints é uma matriz para fornecer recursos de failover e balanceamento de carga. Consulte a seção sobre failover e balanceamento de carga. É importante observar que o navegador selecionará apenas um endpoint, mesmo que a lista de grupo liste vários coletores em endpoints. Se você quiser enviar um relatório para vários servidores de uma só vez, seu back-end precisará encaminhar os relatórios.
Como o navegador envia relatórios?
O navegador agrupa periodicamente os relatórios e os envia para os endpoints de relatórios que você configurar.
Para enviar relatórios, o navegador emite uma solicitação POST
com
Content-Type: application/reports+json e um corpo que contém a matriz de
avisos/erros que foram capturados.
Quando o navegador envia relatórios?
Os relatórios são enviados fora de banda do seu app, ou seja, o navegador controla quando os relatórios são enviados para seus servidores.
O navegador tenta enviar os relatórios em fila no momento mais oportuno. Isso pode acontecer assim que eles estiverem prontos (para fornecer feedback oportuno ao desenvolvedor), mas o navegador também pode atrasar a entrega se estiver ocupado processando um trabalho de maior prioridade ou se o usuário estiver em uma rede lenta e/ou congestionada no momento. O navegador também pode priorizar o envio de relatórios sobre uma origem específica primeiro, se o usuário for um visitante frequente.
Não há quase nenhuma preocupação com o desempenho (por exemplo, contenção de rede com seu app) ao usar a API Reporting. Também não é possível controlar quando o navegador envia relatórios em fila.
Como configurar vários endpoints
Uma única resposta pode configurar vários endpoints de uma só vez enviando
vários cabeçalhos 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"
}]
}
ou combinando-os em um único cabeçalho 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"
}]
}
Depois que você enviar o cabeçalho Report-To, o navegador vai armazenar em cache os endpoints
de acordo com os valores de max_age e enviar todos os avisos/erros
do console para seus URLs.
Failover e balanceamento de carga
Na maioria das vezes, você vai configurar um coletor de URLs por grupo. No entanto, como os relatórios podem gerar muito tráfego, a especificação inclui recursos de failover e balanceamento de carga inspirados no registro SRV do DNS.
O navegador vai fazer o possível para enviar um relatório para no máximo um endpoint
em um grupo. Os endpoints podem receber um weight para distribuir a carga, com cada
endpoint recebendo uma fração especificada do tráfego de relatórios. Os endpoints também podem
receber um priority para configurar coletores de substituição.
Os coletores de fallback só são usados quando os uploads para os coletores principais falham.
Exemplo: criar um coletor substituto em 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}
]
}
Como configurar o registro de erros de rede
Configuração
Para usar o NEL, configure o cabeçalho Report-To com um
coletor que use um grupo nomeado:
Report-To: {
...
}, {
"group": "network-errors",
"max_age": 2592000,
"endpoints": [{
"url": "https://analytics.provider.com/networkerrors"
}]
}
Em seguida, envie o cabeçalho de resposta NEL para começar a coletar erros. Como o NEL
é ativado para uma origem, você só precisa enviar o cabeçalho uma vez. Tanto NEL quanto
Report-To serão aplicados a solicitações futuras para a mesma origem e continuarão
a coletar erros de acordo com o valor de max_age que foi usado para configurar
o coletor.
O valor do cabeçalho precisa ser um objeto JSON que contenha um campo max_age e
report_to. Use o último para referenciar o nome do grupo do seu
coletor de erros de rede:
GET /index.html HTTP/1.1
NEL: {"report_to": "network-errors", "max_age": 2592000}
Sub-recursos
Exemplo: se example.com carregar foobar.com/cat.gif e esse recurso não for carregado:
- O coletor NEL de
foobar.comé notificado - O coletor NEL de
example.comnão é notificado
A regra geral é que o NEL reproduz registros do lado do servidor, gerados apenas no cliente.
Como o example.com não tem visibilidade dos registros do servidor do foobar.com, ele também não tem visibilidade dos relatórios de NEL.
Configurações de relatórios de depuração
Se os relatórios não aparecerem no servidor, acesse
chrome://net-export/. Essa página é útil para
verificar se as configurações estão corretas e se os relatórios estão sendo enviados
adequadamente.
E o ReportingObserver?
ReportingObserver é um mecanismo de denúncia relacionado, mas diferente. Ele é baseado em chamadas JavaScript.
Ele não é adequado para o registro de erros de rede, já que eles
não podem ser interceptados pelo JavaScript.
Servidor de exemplo
Confira abaixo um exemplo de servidor Node que usa o Express. Ele mostra como configurar relatórios para erros de rede e cria um gerenciador dedicado para capturar o resultado.
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}`);
});
Leitura adicional
- Monitorar seu aplicativo da Web com a API Reporting (postagem principal sobre a API Reporting)
- Guia de migração da API Reporting v0 para v1
- Especificação: API Reporting legada (v0)
- Especificação: nova API Reporting (v1)