Logowanie błędów sieciowych (NEL)

Wstęp

Logowanie błędów sieci (NEL) to mechanizm gromadzenia błędów sieci po stronie klienta ze źródła.

Wykorzystuje nagłówek odpowiedzi HTTP NEL, aby poinformować przeglądarkę, że ma zbierać błędy sieci, a następnie integruje się z interfejsem API do raportowania, aby zgłaszać błędy do serwera.

Omówienie starszej wersji interfejsu Reporting API

Aby korzystać ze starszej wersji interfejsu API do raportowania, musisz ustawić nagłówek odpowiedzi HTTP Report-To. Jego wartością jest obiekt opisujący grupę punktów końcowych, w której przeglądarka zgłasza błędy, aby:

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

Jeśli adres URL punktu końcowego znajduje się w innym punkcie początkowym niż Twoja witryna, punkt końcowy powinien obsługiwać żądania wstępnego CORS. (np. 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).

W tym przykładzie wysłanie tego nagłówka odpowiedzi ze stroną główną spowoduje, że przeglądarka będzie przesyłać do punktu końcowego https://analytics.provider.com/browser-errors ostrzeżenia generowane przez przeglądarkę na max_age s. Pamiętaj, że wszystkie kolejne żądania HTTP wysyłane przez stronę (dotyczące obrazów, skryptów itp.) są ignorowane. Konfiguracja jest konfigurowana w czasie odpowiedzi strony głównej.

Objaśnienie pól nagłówka

Każda konfiguracja punktu końcowego zawiera nazwę group, max_age i tablicę endpoints. Korzystając z pola include_subdomains, możesz też zdecydować, czy podczas raportowania błędów uwzględniać subdomeny.

Pole Typ Opis
group string, Opcjonalnie. Jeśli nazwa group nie została określona, punkt końcowy otrzyma nazwę „default”.
max_age Liczba Wymagany. Nieujemna liczba całkowita określająca czas działania punktu końcowego w sekundach. Wartość „0” spowoduje usunięcie grupy punktów końcowych z pamięci podręcznej raportowania klienta użytkownika.
endpoints tablica<obiekt> Wymagany. Tablica obiektów JSON określających rzeczywisty adres URL kolektora raportów.
include_subdomains boolean Opcjonalnie. Wartość logiczna, która włącza grupę punktów końcowych dla wszystkich subdomen hosta bieżącego źródła. Jeśli zostanie pominięty lub inny niż „true”, subdomeny nie będą raportowane do punktu końcowego.

Nazwa group to unikalna nazwa używana do powiązania ciągu znaków z punktem końcowym. Używaj tej nazwy w innych miejscach, które są zintegrowane z interfejsem API do raportowania, aby odwołać się do konkretnej grupy punktów końcowych.

Pole max-age jest też wymagane. Określa ono, jak długo przeglądarka ma używać punktu końcowego i zgłaszać mu błędy.

Pole endpoints to tablica udostępniająca funkcje przełączania awaryjnego i równoważenia obciążenia. Zapoznaj się z sekcją na temat przełączania awaryjnego i równoważenia obciążenia. Pamiętaj, że przeglądarka wybierze tylko jeden punkt końcowy, nawet jeśli grupa zawiera kilka kolektorów w elemencie endpoints. Jeśli chcesz wysłać raport na kilka serwerów jednocześnie, backend musi je przekazać.

W jaki sposób przeglądarka wysyła raporty?

Przeglądarka okresowo grupuje raporty i wysyła je do skonfigurowanych przez Ciebie punktów końcowych raportowania.

Aby wysyłać raporty, przeglądarka wysyła żądanie POST do Content-Type: application/reports+json i treści zawierające tablicę z przechwyconymi ostrzeżeniami/błędami.

Kiedy przeglądarka wysyła raporty?

Raporty są dostarczane poza aplikacją, co oznacza, że przeglądarka kontroluje przesyłanie raportów na serwery.

Przeglądarka próbuje dostarczyć raporty w kolejce w najodpowiedniejszych momentach. Może to nastąpić od razu, gdy projekt jest gotowy (aby w odpowiednim czasie przekazać deweloperowi informacje), ale przeglądarka może też opóźnić dostarczanie, jeśli ma zajęte zadania o wyższym priorytecie lub korzysta wtedy z wolnej lub przeciążonej sieci. Jeśli użytkownik jest częstym użytkownikiem, przeglądarka może też priorytetowo traktować wysyłanie raportów o konkretnym miejscu w pierwszej kolejności.

Podczas korzystania z interfejsu API do raportowania występują niewielkie lub żadne problemy z wydajnością (np. rywalizacja o sieć z aplikacją). Nie ma też sposobu na kontrolowanie, kiedy przeglądarka wysyła raporty w kolejce.

Konfigurowanie wielu punktów końcowych

W jednej odpowiedzi można skonfigurować kilka punktów końcowych jednocześnie, wysyłając kilka nagłówków 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"
             }]
           }

lub łącząc je w jeden nagłówek 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"
             }]
           }

Gdy wyślesz nagłówek Report-To, przeglądarka zapisze punkty końcowe zgodnie z ich wartościami max_age i wyśle wszystkie te ostrzeżenia/błędy w konsoli do adresów URL.

Przełączanie awaryjne i równoważenie obciążenia

Zwykle konfiguruje się po jednym kolektorze adresów URL na grupę. Raportowanie może jednak generować duży ruch, dlatego specyfikacja obejmuje funkcje przełączania awaryjnego i równoważenia obciążenia inspirowane rekordem SRV DNS.

Przeglądarka postara się przesyłać raport do maksymalnie jednego punktu końcowego w grupie. Punkty końcowe można przypisać jako weight, aby rozłożyć obciążenie, przy czym każdy punkt końcowy otrzymuje określoną część raportowania ruchu. Punkty końcowe można też przypisać jako priority, aby skonfigurować kolektory zastępcze.

Kolektory zapasowe są podejmowane tylko wtedy, gdy przesyłanie do głównych kolektorów kończy się niepowodzeniem.

Przykład: utwórz kolektor zastępczy pod adresem 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}
             ]
           }

Konfigurowanie logowania błędów sieciowych

Konfiguracja

Aby używać NEL, skonfiguruj nagłówek Report-To z kolektorem, który używa grupy nazwanej:

Report-To: {
    ...
  }, {
    "group": "network-errors",
    "max_age": 2592000,
    "endpoints": [{
      "url": "https://analytics.provider.com/networkerrors"
    }]
  }

Następnie wyślij nagłówek odpowiedzi NEL, aby zacząć zbierać błędy. Ponieważ opcja NEL jest akceptowana dla źródła, wystarczy wysłać nagłówek tylko raz. Zarówno dyrektywa NEL, jak i Report-To będą stosowane do przyszłych żądań wysyłanych do tego samego źródła i nadal będą zbierać błędy zgodnie z wartością max_age użytej do skonfigurowania kolektora.

Wartość nagłówka powinna być obiektem JSON zawierającym pole max_age i report_to. Użyj drugiego, aby odwołać się do nazwy grupy kolektora błędów sieci:

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

Zasoby podrzędne

Przykład: jeśli example.com wczyta zasób foobar.com/cat.gif i nie uda się wczytać tego zasobu:

  • Kolektor NEL użytkownika foobar.com otrzymał powiadomienie
  • Kolektor NEL użytkownika example.com nie otrzymuje powiadomienia

Zgodnie z ogólną zasadą NEL odtwarza logi po stronie serwera wygenerowane po stronie klienta.

example.com nie ma wglądu w logi serwerów foobar.com, więc nie ma też wglądu w raporty NEL.

Konfiguracje raportu debugowania

Jeśli nie widzisz raportów na swoim serwerze, otwórz stronę chrome://net-export/. Ta strona przydaje się do sprawdzania, czy wszystko jest skonfigurowane prawidłowo i czy raporty są wysyłane prawidłowo.

A co z ReportingObserver?

ReportingObserver to powiązany, choć inny mechanizm raportowania. Jest oparta na wywołaniach JavaScript. Nie jest on przystosowany do logowania błędów sieciowych, ponieważ błędów sieciowych nie da się przechwycić za pomocą kodu JavaScript.

Przykładowy serwer

Poniżej znajdziesz przykładowy serwer węzłów, który korzysta z Express. Pokazuje ono, jak skonfigurować raportowanie pod kątem błędów sieci, i tworzy dedykowany moduł obsługi do rejestrowania wyniku.

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}`);
});

Więcej informacji