Logowanie błędów sieciowych (NEL)

Wprowadzenie

Logowanie błędów sieciowych (NEL) to mechanizm zbierania błędów sieciowych po stronie klienta z źródła.

Używa nagłówka odpowiedzi HTTP NEL, aby poinformować przeglądarkę o zbieraniu błędów sieciowych, a potem integruje się z interfejsem Reporting API, aby zgłaszać błędy na serwer.

Omówienie starszej wersji interfejsu Reporting API

Aby korzystać z poprzedniej wersji interfejsu Reporting API, musisz ustawić nagłówek odpowiedzi HTTP Report-To. Jego wartość to obiekt opisujący grupę punktów końcowych, do której przeglądarka ma zgłaszać błędy:

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

Jeśli adres URL punktu końcowego znajduje się w innej domenie niż Twoja witryna, punkt końcowy powinien obsługiwać żądania wstępne 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 z główną stroną powoduje skonfigurowanie przeglądarki tak, aby przez max_age s przesyłała do punktu końcowego https://analytics.provider.com/browser-errors ostrzeżenia generowane przez przeglądarkę. Pamiętaj, że wszystkie kolejne żądania HTTP wysyłane przez stronę (np. w przypadku obrazów, skryptów itp.) są ignorowane. Konfiguracja jest ustawiana podczas odpowiedzi strony głównej.

Objaśnienie pól nagłówka

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

Pole Typ Opis
group ciąg znaków Opcjonalnie: Jeśli nazwa group nie jest określona, punkt końcowy otrzymuje nazwę „default”.
max_age liczba Wymagany. Nieujemna liczba całkowita określająca czas trwania punktu końcowego w sekundach. Wartość „0” spowoduje usunięcie grupy punktów końcowych z pamięci podręcznej raportowania przeglądarki użytkownika.
endpoints Tablica<Object> Wymagany. Tablica obiektów JSON, które określają rzeczywisty adres URL zbieracza raportów.
include_subdomains wartość logiczna Opcjonalnie: Wartość logiczna, która włącza grupę punktów końcowych dla wszystkich subdomen hosta bieżącego źródła. Jeśli parametr jest pominięty lub ma wartość inną niż „prawda”, podsubdomeny nie są raportowane do punktu końcowego.

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

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

Pole endpoints to tablica, która zapewnia funkcje przełączania awaryjnego i równoważenia obciążenia. Zobacz sekcję Przełączanie awaryjne i równoważenie obciążenia. Pamiętaj, że przeglądarka wybierze tylko 1 punkt końcowy, nawet jeśli grupa zawiera w sekcji endpoints kilka elementów kolekcjonera. Jeśli chcesz wysłać raport na kilka serwerów jednocześnie, backend musi przekazać raporty.

Jak przeglądarka wysyła raporty?

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

Aby wysłać raporty, przeglądarka wysyła żądanie POST z parametrem Content-Type: application/reports+json i zbiorem zarejestrowanych ostrzeżeń/błędów.

Kiedy przeglądarka wysyła raporty?

Raporty są dostarczane poza Twoją aplikacją, co oznacza, że to przeglądarka kontroluje, kiedy raporty są wysyłane na serwer.

Przeglądarka próbuje dostarczyć raporty oczekujące w kolejce w najdogodniejszym momencie. Może to nastąpić od razu, gdy dane są gotowe (aby umożliwić szybkie przesłanie opinii deweloperowi), ale przeglądarka może też opóźnić wysłanie danych, jeśli jest zajęta przetwarzaniem zadań o wyższym priorytecie lub jeśli użytkownik korzysta w danym momencie z wolnej lub zatłoczonej sieci. Jeśli użytkownik często odwiedza daną witrynę, przeglądarka może też nadać priorytet wysyłaniu raportów dotyczących konkretnego źródła.

Podczas korzystania z interfejsu Reporting API nie ma prawie żadnych problemów ze skutecznością (np. konflikty sieciowe z Twoją aplikacją). Nie można też kontrolować, kiedy przeglądarka wysyła raporty z kolejki.

Konfigurowanie wielu punktów końcowych

Jedna odpowiedź może konfigurować kilka punktów końcowych jednocześnie, wysyłając wiele 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"
             }]
           }

Po wysłaniu nagłówka Report-To przeglądarka umieszcza w pamięci podręcznej punkty końcowe zgodnie z ich wartościami max_age i wysyła wszystkie te nieprzyjemne ostrzeżenia/błędy konsoli do Twoich adresów URL.

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

W większości przypadków skonfigurujesz 1 kolektora adresów URL na grupę. Ponieważ jednak raportowanie może generować sporo ruchu, specyfikacja obejmuje funkcje failover i równoważenia obciążenia inspirowane przez rekord SRV w DNS.

Przeglądarka zrobi, co w jej mocy, aby przesłać raport do maksymalnie 1 usługodawcy w grupie. Punktom końcowym można przypisać weight, aby rozłożyć obciążenie. Każdy endpoint otrzymuje określoną część natężenia ruchu. Punktom końcowym można też przypisać priority, aby skonfigurować zbieracze zapasowe.

Kolektory zapasowe są używane tylko wtedy, gdy przesyłanie do kolektorów głównych zakończy się niepowodzeniem.

Przykład: utwórz kolekcjonera zastępczego na stronie 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 rejestrowania błędów sieci

Konfiguracja

Aby używać NEL, skonfiguruj nagłówek Report-To za pomocą kolektora, który używa grupy o nazwie:

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ż NEL jest opcjonalny dla źródła, nagłówek wystarczy wysłać tylko raz. Zarówno NEL, jak i Report-To będą miały zastosowanie do przyszłych żądań do tego samego źródła i nadal będą zbierać błędy zgodnie z wartością max_age użytą do skonfigurowania kolektora.

Wartość nagłówka powinna być obiektem JSON zawierającym pole max_agereport_to. Używaj tego ostatniego, aby odwoływać 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 wczytuje foobar.com/cat.gif, a ten zasób nie wczytuje się:

  • Powiadomienie NEL uczestnika foobar.com
  • example.com NEL collector is not notified

Zasada jest taka, że NEL odtwarza logi po stronie serwera, które są generowane na kliencie.

Ponieważ example.com nie ma dostępu do plików dziennika serwera foobar.com, nie ma też dostępu do raportów NEL.

Debugowanie konfiguracji raportów

Jeśli nie widzisz raportów na serwerze, przejdź do sekcji chrome://net-export/. Ta strona jest przydatna do sprawdzania, czy wszystko jest prawidłowo skonfigurowane i czy raporty są wysyłane prawidłowo.

A ReportingObserver?

ReportingObserver to powiązany, ale inny mechanizm raportowania. Jest ono obliczane na podstawie wywołań kodu JavaScript. Nie nadaje się do rejestrowania błędów sieciowych, ponieważ błędów sieciowych nie można przechwycić za pomocą JavaScriptu.

Przykładowy serwer

Poniżej znajduje się przykład serwera Node, który korzysta z Express. Pokazuje on, jak skonfigurować raportowanie błędów sieciowych, i tworzy specjalny moduł obsługi, który rejestruje wyniki.

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