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 informar ao navegador que ele precisa 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
Cabeçalho Report-To
legada
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 site, ele
precisa oferecer suporte a solicitações de pré-lançamento 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, o envio desse cabeçalho de resposta com a 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 do cabeçalho
Cada configuração de endpoint contém um nome group
, max_age
e uma matriz
endpoints
. Também é possível escolher se quer considerar subdomínios ao relatar erros usando o campo include_subdomains
.
Campo | Tipo | Descrição |
---|---|---|
group |
string | Opcional. Se um nome de group não for especificado, o endpoint vai receber o nome "default". |
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 agente do usuário. |
endpoints |
Matriz<Object> | Obrigatório. Uma matriz de objetos JSON que especifica 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 for omitido ou qualquer valor diferente de "true", os subdomínios não serão informados ao endpoint. |
O 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 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 observar que o navegador selecionará apenas um endpoint, mesmo
que o 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 vai precisar encaminhar os
relatórios.
Como o navegador envia relatórios?
O navegador agrupa relatórios periodicamente e os envia para os endpoints de relatórios configurados.
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 da banda do seu app, o que significa que o navegador controla quando os relatórios são enviados para os servidores.
O navegador tenta entregar relatórios na fila no momento mais oportuno. Isso pode acontecer assim que eles estiverem prontos (para fornecer feedback oportuno ao desenvolvedor), mas o navegador também poderá atrasar a entrega se estiver ocupado processando trabalhos 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, se o usuário for um visitante frequente.
Há pouca ou nenhuma preocupação de desempenho (por exemplo, contenção de rede com seu app) ao usar a API Reporting. Também não há como 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-as 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 esses avisos/erros do console
para os URLs.
Failover e balanceamento de carga
Na maioria das vezes, você vai 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 enviar um relatório para no máximo um endpoint
em um grupo. É possível atribuir um weight
aos endpoints para distribuir a carga, com cada endpoint recebendo uma fração especificada do tráfego de relatórios. Os endpoints também podem
ser atribuídos a um priority
para configurar coletores substitutos.
Os coletores substitutos só são usados 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 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
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 um campo max_age
e
report_to
. Use o ú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}
Sub-recursos
Exemplo: se example.com
carregar foobar.com/cat.gif
e esse recurso não for carregado:
- O coletor de NEL de
foobar.com
é notificado - O coletor de NEL de
example.com
não é notificado
A regra geral é que o NEL reproduz logs do lado do servidor, gerados no cliente.
Como example.com
não tem visibilidade nos registros do servidor
de foobar.com
, também não tem visibilidade nos relatórios de NEL.
Depurar configurações de relatórios
Se os relatórios não aparecerem no seu servidor, acesse chrome://net-export/
. Essa página é útil para
verificar se as coisas estão configuradas corretamente e se os relatórios estão sendo enviados
corretamente.
E o ReportingObserver?
ReportingObserver
é um mecanismo de geração de relatórios relacionado, mas diferente. Ele é baseado em chamadas do JavaScript.
Ele não é adequado para o registro de erros de rede, já que os erros de rede
não podem ser interceptados pelo JavaScript.
Exemplo de servidor
Veja abaixo um exemplo de servidor de nó que usa o Express. Ele mostra como configurar a geração de relatórios para erros de rede e cria um manipulador 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 a v1
- Especificação: API Reporting legada (v0)
- Especificação: nova API Reporting (v1)