Introdução
O registro de erros de rede (NEL, na sigla em inglês) é 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 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, você precisa definir um cabeçalho de resposta HTTP Report-To
. O
valor é 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á oferecer suporte a solicitações de simulação do 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, enviar esse cabeçalho de resposta com a página principal configura o navegador para relatar avisos gerados pelo navegador para o 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.) serã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 você quer considerar subdomínios ao relatar erros usando o campo include_subdomains
.
Campo | Tipo | Descrição |
---|---|---|
group |
string | Opcional. Se um nome group não for especificado, o endpoint receberá o nome "padrão". |
max_age |
number | Obrigatório. Um número inteiro não negativo que define a vida útil do endpoint em segundos. Um valor de "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 |
boolean | Opcional. Um booleano que ativa o grupo de endpoints para todos os subdomínios do host da origem atual. Se omitido ou algo diferente de "true", os subdomínios não são informados para o endpoint. |
O nome group
é um nome exclusivo usado para associar uma string a
um endpoint. Use esse nome em outros locais 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 precisa usar o endpoint e informar 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 que o navegador selecione apenas um endpoint, mesmo
que o grupo liste vários coletores em endpoints
. Se você quiser enviar um
relatório a vários servidores de uma só vez, seu back-end precisará encaminhá-los.
Como o navegador envia relatórios?
O navegador agrupa periodicamente os relatórios e os envia aos endpoints de relatório configurados por você.
Para enviar relatórios, o navegador emite uma solicitação POST
com
Content-Type: application/reports+json
e um corpo contendo a matriz de
avisos/erros que foram capturados.
Quando o navegador envia relatórios?
Os relatórios são enviados fora de banda do app, o que significa que o navegador controla quando os relatórios são enviados aos seus servidores.
O navegador tenta entregar relatórios na fila no momento mais oportuno. Isso pode acontecer assim que eles estiverem prontos (para fornecer feedback rápido ao desenvolvedor), mas o navegador também poderá atrasar a entrega se estiver ocupado processando um trabalho de prioridade mais alta 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, caso o usuário seja um visitante frequente.
Há pouca ou 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 na 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ê envia o cabeçalho Report-To
, o navegador armazena em cache os endpoints
de acordo com os valores max_age
e envia todos os avisos/erros
inadequados do console para seus URLs.
Failover e balanceamento de carga
Na maioria das vezes, você precisa configurar um coletor de URL por grupo. No entanto, como os relatórios podem gerar uma boa quantidade de 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 entregar um relatório para no máximo um endpoint
de um grupo. É possível atribuir um weight
aos endpoints para distribuir a carga, e cada endpoint recebe uma fração especificada do tráfego de relatórios. Os endpoints também podem receber um priority
para configurar coletores de substituto.
Os coletores substitutos só são testados quando os uploads para os coletores principais falham.
Exemplo: crie 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 a geração de registros de erros de rede
Instalação
Para usar 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. NEL
e
Report-To
serão aplicados a solicitações futuras para a mesma origem e continuarão
coletando erros de acordo com o valor max_age
usado para configurar
o coletor.
O valor do cabeçalho precisa ser um objeto JSON que contenha os campos max_age
e report_to
. Use este último para fazer referência ao nome do grupo do
coletor de erros de rede:
GET /index.html HTTP/1.1
NEL: {"report_to": "network-errors", "max_age": 2592000}
Recursos secundários
Exemplo: se example.com
carregar foobar.com/cat.gif
e esse recurso não for carregado:
- O coletor NEL de
foobar.com
foi notificado - O coletor NEL de
example.com
não é notificado.
A regra prática é que o NEL reproduz registros do lado do servidor, gerados apenas no cliente.
Como example.com
não tem visibilidade nos registros do servidor de foobar.com
, ele também não tem visibilidade nos relatórios NEL.
Configurações de relatórios de depuração
Se os relatórios não aparecerem no seu 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 corretamente.
E o ReportingObserver?
ReportingObserver
é um mecanismo de denúncia relacionado, mas diferente. Ela é baseada em chamadas JavaScript.
Não é adequado para geração de registros de erros de rede, já que erros de rede
não podem ser interceptados por JavaScript.
Exemplo de servidor
Veja abaixo um exemplo de servidor Node que usa Express. Ele mostra como configurar a geração de 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}`);
});
Sugestões de leitura
- 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)