Netzwerkfehler-Logging (NEL)

Einführung

Netzwerkfehler-Logging (Network Error Logging, NEL) ist ein Mechanismus, Erfassen clientseitiger Netzwerkfehler aus einer Quelle.

Über den HTTP-Antwortheader NEL wird der Browser angewiesen, Netzwerkfehler zu erfassen. Diese Fehler werden dann in die Reporting API eingebunden, um sie an einen Server zu melden.

Überblick über die alte Reporting API

Wenn Sie die alte Reporting API verwenden möchten, müssen Sie einen Report-To-HTTP-Antwortheader festlegen. Das value ist ein Objekt, das eine Endpunktgruppe für den Browser beschreibt um Fehler zu melden an:

Report-To:
{
    "max_age": 10886400,
    "endpoints": [{
    "url": "https://analytics.provider.com/browser-errors"
    }]
}

Wenn die Endpunkt-URL einen anderen Ursprung hat als Ihre Website, 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).

Im Beispiel wird der Antwortheader mit der Hauptseite Der Browser wird so konfiguriert, dass vom Browser generierte Warnungen gemeldet werden. zum Endpunkt https://analytics.provider.com/browser-errors für max_age Sekunden. Beachten Sie, dass alle nachfolgenden HTTP-Anfragen, die von der Seite (für Bilder, Skripte usw.) werden ignoriert. Konfiguration wird eingerichtet während die Antwort der Hauptseite.

Erläuterung der Headerfelder

Jede Endpunktkonfiguration enthält einen group-Namen, eine max_age und eine endpoints Array. Sie können auch festlegen, ob bei der Berichterstellung auch Subdomains berücksichtigt werden sollen. Fehler mithilfe des Felds include_subdomains.

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. Ein Wert von „0“ wird die Endpunktgruppe aus dem Berichtscache des User-Agents entfernt.
endpoints Array<Objekt> Erforderlich. Ein Array von JSON-Objekten, die die tatsächliche URL Ihres Berichts-Collectors angeben.
include_subdomains boolean Optional. Ein boolescher Wert, mit dem die Endpunktgruppe für alle Subdomains des Hosts des aktuellen Ursprungs aktiviert wird. Wenn das Attribut weggelassen wird oder einen anderen Wert als „true“ hat, werden die Subdomains nicht an den Endpunkt gemeldet.

Der Name group ist ein eindeutiger Name, mit dem ein String verknüpft wird Endpunkt. Verwenden Sie diesen Namen auch an anderen Stellen, mit der Reporting API verwenden, um auf eine bestimmte Endpunktgruppe zu verweisen.

Das Feld max-age ist ebenfalls ein Pflichtfeld und gibt an, wie wie lange der Browser den Endpunkt verwenden und Fehler an ihn melden soll.

Das Feld endpoints ist ein Array für Failover und Load-Balancing Funktionen. Weitere Informationen finden Sie im Abschnitt Failover und Load-Balancing. Es ist Beachten Sie, dass der Browser nur einen Endpunkt auswählt, auch wenn Die Gruppe listet mehrere Collectors in endpoints auf. Wenn Sie eine an mehrere Server gleichzeitig senden, muss das Backend den Berichte.

Wie sendet der Browser Berichte?

Der Browser fasst regelmäßig Berichte zusammen und sendet sie an die Berichterstellung. von Ihnen konfigurierten Endpunkten.

Zum Senden von Berichten gibt der Browser den Fehler POST aus Anfrage mit Content-Type: application/reports+json und einen Textkörper mit dem Array von Warnungen/Fehler, die erfasst wurden.

Wann sendet der Browser Berichte?

Berichte werden Out-of-Band-Berichte von Ihrer App übertragen. Das bedeutet, dass der Browser legt fest, wann Berichte an Ihre Server gesendet werden.

Der Browser versucht, Bereitstellung von Berichten in der Warteschlange zum optimalen Zeitpunkt Dies kann geschehen, sobald sie bereit sind, zeitnahes Feedback an den Entwickler. Der Browser kann aber auch die Lieferung verzögern, Verarbeitung von Aufgaben mit höherer Priorität beschäftigt oder wenn der Nutzer zu langsam ist und/oder Netzwerk überlastet ist. Der Browser priorisiert möglicherweise auch Berichte zu einem bestimmten Ursprung zuerst, wenn der Nutzer ein regelmäßiger Besucher ist.

Es gibt wenig bis keine Leistungsbedenken (z.B. Netzwerkkonflikte mit Ihrer App), wenn Sie die Reporting API verwenden. Es gibt Außerdem lässt sich nicht steuern, wann der Browser Berichte in der Warteschlange sendet.

Mehrere Endpunkte konfigurieren

Mit einer einzigen Antwort können mehrere Endpunkte gleichzeitig konfiguriert werden, indem Mehrere Report-To-Header:

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 durch Kombinieren in einem einzigen HTTP-Header:

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 Report-To-Header gesendet haben, speichert der Browser die Endpunkte im Cache entsprechend ihren max_age-Werten und sendet alle diese Warnungen/Fehler an Ihre URLs anhängen.

Failover und Load-Balancing

Meistens konfigurieren Sie einen URL-Collector pro Gruppe. Sie können jedoch Da die Berichterstellung viele Zugriffe generieren kann, ist in den Spezifikationen die Failover-Funktion und Load-Balancing-Funktionen, die vom DNS SRV-Eintrag:

Der Browser versucht, einen Bericht an maximal einen Endpunkt zu senden in einer Gruppe. Endpunkte kann ein weight zugewiesen werden, um die Last zu verteilen, an den Endpunkt, der einen bestimmten Anteil des Berichttraffics empfängt. Endpunkte können wird auch einer priority zugewiesen, um Fallback-Collectors einzurichten.

Fallback-Collectors werden nur dann versucht, wenn Uploads in 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 einer Collector, 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 dem Erfassen der Fehler zu beginnen. Seit NEL ist die Zustimmung für einen Ursprung. Sie müssen den Header nur einmal senden. Sowohl NEL als auch Report-To gilt für zukünftige Anfragen an denselben Ursprung und wird fortgesetzt , um Fehler gemäß dem max_age-Wert zu erfassen, der für die Einrichtung verwendet wurde den Collector.

Der Headerwert sollte ein JSON-Objekt sein, das ein max_age und report_to. Verwenden Sie Letztere, um auf den Gruppennamen Ihres Erfassung von Netzwerkfehlern:

GET /index.html HTTP/1.1
NEL: {"report_to": "network-errors", "max_age": 2592000}

Unterressourcen

Beispiel: Wenn example.com foobar.com/cat.gif lädt und diese Ressource fehlschlägt zum Laden:

  • Der NEL-Collector von foobar.com wird benachrichtigt
  • Der NEL-Collector von example.com wird nicht benachrichtigt

Die Faustregel ist, dass NEL serverseitige Protokolle reproduziert, Kundschaft.

Da example.com keinen Einblick in den Server von foobar.com hat Logs hat es auch keinen Einblick in seine NEL-Berichte.

Fehler in Berichtskonfigurationen beheben

Sollten auf Ihrem Server keine Berichte angezeigt werden, wechseln Sie zu chrome://net-export/ Diese Seite ist nützlich für Prüfen, ob die Einstellungen richtig konfiguriert sind und Berichte gesendet werden richtig aus.

Was ist mit ReportingObserver?

ReportingObserver ist ein ähnliches Meldeverfahren, aber anders. Es basiert auf JavaScript-Aufrufen. Sie eignet sich nicht für das Logging von Netzwerkfehlern, da Netzwerkfehler nicht über JavaScript abgefangen werden.

Beispielserver

Unten sehen Sie ein Beispiel für einen Knotenserver, der Express verwendet. Er zeigt, wie die Berichterstellung für Netzwerkfehler konfiguriert wird, und erstellt einen dedizierten Handler, 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}`);
});

Weitere Informationen