Einführung
Network Error Logging (NEL) ist ein Mechanismus zum Erfassen von clientseitigen Netzwerkfehlern von einem Ursprung.
Der HTTP-Antwortheader NEL wird verwendet, um den Browser anzuweisen, Netzwerkfehler zu erfassen. Anschließend wird die Reporting API eingebunden, um die Fehler an einen Server zu melden.
Übersicht über die alte Reporting API
Der Legacy-Header Report-To
Wenn Sie die alte Reporting API verwenden möchten, müssen Sie einen Report-To-HTTP-Antwortheader festlegen. Der Wert ist ein Objekt, das eine Endpunktgruppe beschreibt, an die der Browser Fehler melden soll:
Report-To:
{
"max_age": 10886400,
"endpoints": [{
"url": "https://analytics.provider.com/browser-errors"
}]
}
Wenn sich die Endpunkt-URL auf einem anderen Ursprung als Ihre Website befindet, sollte der Endpunkt CORS-Preflight-Anfragen unterstützen. (z.B. 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).
Wenn Sie diesen Antwortheader mit Ihrer Hauptseite senden, wird der Browser so konfiguriert, dass er vom Browser generierte Warnungen für max_age Sekunden an den Endpunkt https://analytics.provider.com/browser-errors meldet.
Alle nachfolgenden HTTP-Anfragen, die von der Seite gestellt werden (für Bilder, Skripts usw.), werden ignoriert. Die Konfiguration wird während der Antwort der Hauptseite eingerichtet.
Erläuterung der Headerfelder
Jede Endpunktkonfiguration enthält einen group-Namen, max_age und ein endpoints-Array. Mit dem Feld include_subdomains können Sie auch festlegen, ob Subdomains beim Melden von Fehlern berücksichtigt werden sollen.
| Feld | Typ | Beschreibung |
|---|---|---|
group |
String | Optional. Wenn kein group-Name angegeben ist, erhält der Endpunkt den Namen „default“. |
max_age |
Zahl | Erforderlich. Eine nicht negative Ganzzahl, die die Lebensdauer des Endpunkts in Sekunden definiert. Der Wert „0“ führt dazu, dass die Endpunktgruppe aus dem Berichts-Cache des User-Agents entfernt wird. |
endpoints |
Array<Object> | Erforderlich. Ein Array von JSON-Objekten, die die tatsächliche URL Ihres Berichtssammlers angeben. |
include_subdomains |
boolean | Optional. Ein boolescher Wert, der die Endpunktgruppe für alle Subdomains des Hosts des aktuellen Ursprungs aktiviert. Wenn der Wert weggelassen wird oder nicht „true“ ist, werden die Subdomains nicht an den Endpunkt gemeldet. |
Der Name group ist ein eindeutiger Name, mit dem ein String einem Endpunkt zugeordnet wird. Verwenden Sie diesen Namen an anderen Stellen, die in die Reporting API eingebunden sind, um auf eine bestimmte Endpunktgruppe zu verweisen.
Das Feld max-age ist ebenfalls erforderlich und gibt an, wie lange der Browser den Endpunkt verwenden und Fehler an ihn melden soll.
Das Feld endpoints ist ein Array, das Failover- und Load-Balancing-Funktionen bietet. Weitere Informationen finden Sie im Abschnitt Failover und Load Balancing. Der Browser wählt nur einen Endpunkt aus, auch wenn in der Gruppe mehrere Collectors in endpoints aufgeführt sind. Wenn Sie einen Bericht an mehrere Server gleichzeitig senden möchten, muss Ihr Backend die Berichte weiterleiten.
Wie sendet der Browser Berichte?
Der Browser bündelt Berichte regelmäßig und sendet sie an die von Ihnen konfigurierten Berichterstellungsendpunkte.
Zum Senden von Berichten sendet der Browser eine POST-Anfrage mit Content-Type: application/reports+json und einem Text, der das Array der erfassten Warnungen/Fehler enthält.
Wann sendet der Browser Berichte?
Berichte werden außerhalb der App bereitgestellt, d. h., der Browser steuert, wann Berichte an Ihre Server gesendet werden.
Der Browser versucht, Berichte in der Warteschlange zum günstigsten Zeitpunkt zu senden. Das kann geschehen, sobald sie bereit sind (um dem Entwickler zeitnah Feedback zu geben). Der Browser kann die Übermittlung aber auch verzögern, wenn er mit der Verarbeitung von Aufgaben mit höherer Priorität beschäftigt ist oder wenn der Nutzer sich zu diesem Zeitpunkt in einem langsamen und/oder überlasteten Netzwerk befindet. Der Browser kann auch das Senden von Berichten zu einem bestimmten Ursprung priorisieren, wenn der Nutzer ein häufiger Besucher ist.
Bei der Verwendung der Reporting API gibt es kaum oder gar keine Leistungsprobleme (z.B. Netzwerkkonflikte mit Ihrer App). Es gibt auch keine Möglichkeit, zu steuern, wann der Browser Berichte in der Warteschlange sendet.
Mehrere Endpunkte konfigurieren
In einer einzelnen Antwort können mehrere Endpunkte gleichzeitig konfiguriert werden, indem mehrere Report-To-Header gesendet werden:
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"
}]
}
oder indem Sie sie in einem einzigen HTTP-Header kombinieren:
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"
}]
}
Nachdem Sie den Header Report-To gesendet haben, speichert der Browser die Endpunkte gemäß ihren max_age-Werten im Cache und sendet alle diese lästigen Konsolenwarnungen/-fehler an Ihre URLs.
Failover und Load Balancing
In den meisten Fällen konfigurieren Sie einen URL-Collector pro Gruppe. Da die Berichterstellung jedoch viel Traffic verursachen kann, enthält die Spezifikation Failover- und Load-Balancing-Funktionen, die vom DNS-SRV-Eintrag inspiriert sind.
Der Browser versucht, einen Bericht an höchstens einen Endpunkt in einer Gruppe zu senden. Endpunkten kann ein weight zugewiesen werden, um die Last zu verteilen. Jeder Endpunkt erhält einen bestimmten Anteil des Berichts-Traffics. Endpunkten kann auch ein priority zugewiesen werden, um Fallback-Collectors einzurichten.
Fallback-Collectors werden nur verwendet, wenn Uploads auf primäre Collectors fehlschlagen.
Beispiel: Erstellen Sie einen Fallback-Collector unter 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}
]
}
Netzwerkfehler-Logging einrichten
Einrichtung
Wenn Sie NEL verwenden möchten, richten Sie den Report-To-Header mit einem Collector ein, der eine benannte Gruppe verwendet:
Report-To: {
...
}, {
"group": "network-errors",
"max_age": 2592000,
"endpoints": [{
"url": "https://analytics.provider.com/networkerrors"
}]
}
Senden Sie als Nächstes den Antwortheader NEL, um mit der Erfassung von Fehlern zu beginnen. Da NEL für einen Ursprung optional ist, müssen Sie den Header nur einmal senden. Sowohl NEL als auch Report-To gelten für zukünftige Anfragen an denselben Ursprung und erfassen weiterhin Fehler gemäß dem max_age-Wert, der zum Einrichten des Collectors verwendet wurde.
Der Headerwert sollte ein JSON-Objekt sein, das ein max_age- und ein report_to-Feld enthält. Verwenden Sie Letzteres, um auf den Gruppennamen Ihres Netzwerkfehler-Collectors zu verweisen:
GET /index.html HTTP/1.1
NEL: {"report_to": "network-errors", "max_age": 2592000}
Unterressourcen
Beispiel: Wenn example.com die Ressource foobar.com/cat.gif lädt und diese Ressource nicht geladen werden kann:
- Der NEL-Collector von
foobar.comwird benachrichtigt - Der NEL-Collector von
example.comwird nicht benachrichtigt.
Als Faustregel gilt, dass NEL serverseitige Logs reproduziert, die nur auf dem Client generiert werden.
Da example.com keinen Einblick in die Serverprotokolle von foobar.com hat, hat es auch keinen Einblick in die NEL-Berichte.
Konfigurationen für Debugging-Berichte
Wenn auf Ihrem Server keine Berichte angezeigt werden, rufen Sie chrome://net-export/ auf. Auf dieser Seite können Sie prüfen, ob alles richtig konfiguriert ist und Berichte ordnungsgemäß gesendet werden.
Was ist mit ReportingObserver?
ReportingObserver ist ein ähnlicher, aber anderer Meldemechanismus. Sie basiert auf JavaScript-Aufrufen.
Sie ist nicht für die Protokollierung von Netzwerkfehlern geeignet, da Netzwerkfehler nicht über JavaScript abgefangen werden können.
Beispielserver
Unten sehen Sie ein Beispiel für einen Node-Server, der Express verwendet. Es wird gezeigt, wie Sie die Berichterstellung für Netzwerkfehler konfigurieren und einen dedizierten Handler erstellen, um das Ergebnis zu erfassen.
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}`);
});