Czy zmagasz się z wyszukiwaniem błędów w kodzie? Potrzebujesz narzędzi do rejestrowania, które usprawnią ten proces? Zapoznaj się z dalszą częścią artykułu, aby poszerzyć swoją wiedzę na ten temat.
Tworzenie oprogramowania to cykl obejmujący kilka etapów: gromadzenie wymagań, analizę, kodowanie, testowanie i utrzymanie. Faza kodowania/rozwoju jest szczególnie wymagająca pod względem czasu i wysiłku. Programiści mierzą się z błędami składniowymi, logicznymi oraz tymi, które pojawiają się podczas działania programu. Błędy składniowe są wykrywane przez kompilator, wynikają one z naruszenia zasad danego języka programowania.
Natomiast błędy logiczne i błędy czasu wykonywania umykają uwadze zintegrowanych środowisk programistycznych (IDE) i często ich debugowanie i naprawa stanowią wyzwanie. Eliminacja błędów to proces czasochłonny, wymagający intensywnej pracy.
Debugowanie to procedura mająca na celu ustalenie, dlaczego napisany kod nie realizuje zadanych celów. Rozwiązanie problemu jest proste, gdy znany jest jego charakter oraz linijki kodu, w których występuje. W związku z tym rejestrowanie jest nieocenione podczas debugowania kodu.
Czym jest rejestrowanie?
Rejestrowanie polega na przechwytywaniu komunikatów generowanych podczas wykonywania programu. Rejestracji powinny podlegać tylko te komunikaty, które mogą pomóc w debugowaniu. Kluczowa jest wiedza o tym, kiedy wstawić do kodu instrukcje rejestrujące. Równie ważne jest rozróżnianie typów wpisów w dzienniku. Istnieją różne poziomy rejestrowania, takie jak informacyjny, ostrzegawczy, błędu, debugowania i szczegółowy. Wpisy błędów i ostrzeżeń wykorzystuje się do obsługi wyjątków.
Dane zwracane przez funkcje, wyniki operacji na tablicach, dane pobierane z API – to tylko przykłady informacji, które można rejestrować za pomocą komunikatów informacyjnych. Dzienniki debugowania i szczegółowe służą do dokładnego opisu błędów.
Dziennik debugowania zawiera informacje takie jak ślad stosu, parametry wejściowe i wyjściowe. Dziennik „szczegółowy” nie jest tak precyzyjny, jak dziennik „debugowania”, ale zawiera rejestr wszystkich zdarzeń. Dzienniki zapisywane są w konsoli, plikach oraz strumieniu wyjściowym. Do strukturalnego i sformatowanego rejestrowania można wykorzystać narzędzia do zarządzania dziennikami.
Rejestrowanie w Node.js
Node.js to środowisko uruchomieniowe dla języka JavaScript. Aplikacje Node.js są asynchroniczne i nieblokujące, dlatego stosuje się je w systemach operujących na dużej ilości danych i pracujących w czasie rzeczywistym. Najlepszym sposobem na dogłębne poznanie Node.js jest zapoznanie się z samouczkami i dokumentacją. Rejestrowanie jest istotne dla podniesienia wydajności, rozwiązywania problemów i śledzenia błędów. W Node.js rejestrowanie odbywa się przy użyciu wbudowanej funkcji `console.log`. Dostępna jest także funkcja debugowania, która współpracuje z wieloma pakietami i może być efektywnie wykorzystywana.
Oprogramowanie pośredniczące (middleware) służy do obsługi żądań i odpowiedzi. Middleware może być aplikacją lub dowolnym frameworkiem JavaScript. Rejestrowanie w oprogramowaniu pośredniczącym odbywa się za pośrednictwem aplikacji i routerów. Każdy rejestrator w Node.js wymaga użycia polecenia `npm` lub `yarn install` w celu instalacji.
`npm` oznacza „Node Package Manager”, a `YARN` to „Yet Another Resource Negotiator”. YARN jest preferowany, gdyż działa szybciej i instaluje pakiety równolegle.
Poniżej znajduje się lista popularnych rejestratorów Node.js:
Pino
Pino to biblioteka uznawana za jeden z najlepszych rejestratorów dla aplikacji Node.js. Jest to oprogramowanie open source, cechujące się dużą szybkością i rejestrowaniem komunikatów w czytelnym formacie JSON. Poziomy logowania w Pino obejmują komunikaty debugowania, ostrzeżenia, błędy i informacje. Instancję rejestratora Pino można zaimportować do projektu, a instrukcje `console.log` należy zastąpić instrukcjami `logger.info`.
Aby zainstalować Pino, użyj następującego polecenia:
$ npm install pino
Wygenerowane logi są szczegółowe, w formacie JSON, zawierają numer linii logu, typ logu i czas rejestracji. Pino generuje minimalne obciążenie aplikacji i jest bardzo elastyczny w przetwarzaniu logów.
Pino można zintegrować z frameworkami webowymi, takimi jak Hapi, Restify, Express. Logi wygenerowane przez Pino można przechowywać w plikach. Pino działa przy wykorzystaniu wątków roboczych i jest kompatybilny z TypeScript.
Winston
Winston wspiera rejestrowanie dla różnych platform internetowych, z naciskiem na elastyczność i rozszerzalność. Obsługuje wiele typów transportu i pozwala na przechowywanie logów w różnych lokalizacjach. Transporty to miejsca przechowywania komunikatów dziennika.
Oprócz wbudowanych transportów, takich jak Http, Console, File i Stream, wspiera inne, na przykład Cloud Watch i MongoDB. Loguje na różnych poziomach i w różnych formatach. Poziomy rejestrowania sygnalizują ważność problemu.
Różne poziomy rejestrowania przedstawiono poniżej:
{ error: 0, warn: 1, info: 2, http: 3, verbose: 4, debug: 5, silly: 6 }
Format wyjściowy dziennika można dostosować, filtrować i łączyć. Dzienniki zawierają informacje o znaczniku czasu, etykietach powiązanych z dziennikiem, milisekundach, które upłynęły od poprzedniego logu itd.
Winston radzi sobie również z wyjątkami i niespełnionymi obietnicami. Zapewnia dodatkowe funkcje, takie jak uzupełnianie zapytań, dzienniki strumieniowe. W pierwszej kolejności należy zainstalować Winstona. Następnie tworzy się obiekt konfiguracyjny Winstona wraz z transportem do przechowywania dziennika. Obiekt rejestratora jest tworzony za pomocą funkcji `createLogger()`, do której przesyła się komunikat dziennika.
Bunyan dla Node.js
Bunyan służy do szybkiego rejestrowania w Node.js w formacie JSON. Udostępnia też interfejs wiersza poleceń (CLI) do przeglądania logów. Jest lekki i obsługuje różne środowiska uruchomieniowe, takie jak Node.js, Browserify, WebPack i NW.js. Format JSON logów jest dodatkowo upiększany za pomocą funkcji `pretty print`. Logi mają różne poziomy, takie jak krytyczny, błąd, ostrzeżenie, informacja, debugowanie i śledzenie; każdy z nich powiązany jest z wartością liczbową.
Rejestrowane są wszystkie poziomy powyżej poziomu ustawionego dla instancji. Strumień Bunyan to miejsce zapisu danych wyjściowych. Podkomponenty aplikacji można rejestrować za pomocą funkcji `log.child()`. Wszystkie rejestratory potomne są powiązane z określoną aplikacją nadrzędną. Typ strumienia może być plikiem, plikiem rotacyjnym, surowymi danymi. Poniżej znajduje się przykład kodu definiującego strumień:
var bunyan = require('bunyan'); var log = bunyan.createLogger({ name: "foo", streams: [ { stream: process.stderr, level: "debug" }, ... ] });
Bunyan obsługuje również logowanie DTrace. Sondy zaangażowane w rejestrowanie DTrace to `log-trace`, `log-warn`, `log-error`, `log-info`, `log-debug` i `log-fatal`. Bunyan używa serializatorów do tworzenia dzienników w formacie JSON. Funkcje serializatora nie generują wyjątków i są odporne na błędy.
Poziom Logowania
Loglevel służy do rejestrowania w aplikacjach JavaScript. Jest to jeden z najlepszych rejestratorów Node.js, gdyż jest lekki i prosty. Rejestruje dany poziom i używa do rejestrowania pojedynczego pliku bez zależności. Domyślny poziom logowania to „ostrzeżenie”. Wyjście dziennika jest dobrze sformatowane i zawiera numery wierszy. Metody stosowane w rejestrowaniu to śledzenie, debugowanie, ostrzeganie, błędy i informacje.
Są odporne na awarie w każdym środowisku. `getLogger()` to metoda używana do pobrania obiektu rejestratora. Można go również łączyć z innymi wtyczkami w celu rozszerzenia funkcjonalności. Wtyczki te to m.in. `loglevel-plugin-prefix`, `loglevel-plugin-remote`, `ServerSend` i `DEBUG`. Poniżej znajduje się przykład wtyczki do dodawania prefiksów do komunikatów w dzienniku:
var originalFactory = log.methodFactory; log.methodFactory = function (methodName, logLevel, loggerName) { var rawMethod = originalFactory(methodName, logLevel, loggerName); return function (message) { rawMethod("Newsflash: " + message); }; }; log.setLevel(log.getLevel()); // Be sure to call setLevel method in order to apply plugin
Kompilacje uruchamiane są za pomocą polecenia `npm run dist`, a testy za pomocą polecenia `npm test`. Loglevel obsługuje pakiety Webjar, Bower i Atmosphere. Nowa wersja Loglevel ukazuje się za każdym razem, gdy dodawane są nowe funkcje.
Signale
Signale to zestaw 19 rejestratorów dla aplikacji JavaScript. Obsługuje TypeScript i rejestrowanie w zakresie. Składa się z liczników czasu, które pomagają w rejestrowaniu znacznika czasu, danych i nazwy pliku. Oprócz 19 standardowych rejestratorów (np. `await`, `complete`, `fatal`, `fav`, `info`) można tworzyć własne logi.
Własne dzienniki są tworzone przez zdefiniowanie obiektu JSON i pól z danymi rejestratora. Można także tworzyć rejestratory interaktywne. Gdy ustawimy rejestrator interaktywny na `true`, nowe wartości z rejestratorów interaktywnych zastąpią stare.
Największą zaletą Signale jest możliwość odfiltrowania tajnych informacji. Wiele wpisów tajnych jest przechowywanych w tablicy. Do dodawania i usuwania tajemnic z tablicy służą funkcje `addSecrets()` i `clearSecrets()`. Boostnote, Docz, Shower, Taskbook i Vant korzystają z Signale do rejestrowania. Składnia wywołania API z Signale jest następująca:
signale.<logger>(message[,message]|messageObj|errorObj)
Liczba pobrań Signale przekracza 1 milion w momencie pisania tego tekstu.
Tracer
Tracer służy do tworzenia szczegółowych komunikatów rejestrujących. Komunikaty te zawierają znaczniki czasu, nazwy plików, numery wierszy i nazwy metod. Pakiety pomocnicze można zainstalować, aby dostosować format wyjściowy rejestrowania. Pakiety pomocnicze można zainstalować za pomocą następującego polecenia.
npm install -dev tracer
Tracer obsługuje przesyłanie danych do plików, strumieni i MongoDB. Obsługuje kolorowanie konsoli i warunki filtrowania w rejestrowaniu. Początkowo należy zainstalować tracer za pomocą `npm install`. Następnie należy utworzyć obiekt rejestratora i wybrać typ konsoli. W obiekcie można określić różne poziomy lub typy rejestrowania.
Własne filtry można tworzyć definiując funkcje synchroniczne z logiką biznesową. Do rejestrowania systemu można wykorzystać mikroszablony, takie jak `tinytim`.
Cabin.js
Cabin służy do rejestrowania aplikacji Node.js po stronie serwera i klienta. Stosuje się go tam, gdzie niezbędne jest maskowanie wrażliwych i krytycznych danych. Dotyczy to numerów kart kredytowych, nagłówków BasicAuth, soli, haseł, tokenów CSRF i numerów kont bankowych. Poniższy fragment kodu przedstawia przykład rejestrowania za pomocą Cabin.js.
const Cabin = require('cabin'); const cabin = new Cabin(); cabin.info('hello world'); cabin.error(new Error('oops!'));
Cabin zawiera ponad 1600 nazw pól. Jest kompatybilny z zasadą Bring Your Own Logger (BYOL), dzięki czemu współpracuje z różnymi innymi rejestratorami, takimi jak Axe, Pino, Bunyan, Winston. Zmniejsza koszty przechowywania na dyskach dzięki automatycznemu buforowaniu strumieniowemu. Jest kompatybilny z wieloma platformami i łatwy w debugowaniu.
Rejestrowanie po stronie serwera wymaga użycia middleware do routingu i automatycznego rejestrowania danych wyjściowych. Rejestrowanie po stronie przeglądarki wymaga żądań i skryptów XHR. Wykorzystuje Ax, który wyświetla metadane, tj. informacje o danych, ślady stosu i inne błędy. `SHOW_STACK` i `SHOW_META` to zmienne logiczne, ustawione na `true` lub `false`, które umożliwiają wyświetlanie lub ukrywanie śladów stosu i metadanych.
Npmlog
Npmlog to podstawowy typ rejestratora używany przez npm. Metody rejestrowania obejmują poziom, rekord, `maxRecordSize`, `prefixStyle`, nagłówek i strumień. Obsługuje kolorowanie logów. Poziomy rejestrowania to: głupi, szczegółowy, informacyjny, ostrzegawczy, http i błąd. Poniżej znajduje się przykład kodu wykorzystującego dziennik npm.
var log = require('npmlog') // additional stuff ---------------------------+ // message ----------+ | // prefix ----+ | | // level -+ | | | // v v v v log.info('fyi', 'I have a kitty cat: %j', myKittyCat)
Wszystkie komunikaty są pomijane, jeśli jako poziom rejestrowania ustawiono „Nieskończoność”. Jeśli ustawiono „-Nieskończoność”, opcja wyświetlania komunikatów musi być włączona, aby móc zobaczyć logi.
Do rejestrowania wykorzystuje się zdarzenia i obiekty komunikatów. Komunikaty prefiksowe emitowane są, gdy używane są zdarzenia prefiksowe. Obiekty stylów są używane do formatowania logów, np. dodawania koloru do tekstu i tła, stylu czcionki (pogrubienie, kursywa, podkreślenie). Niektóre pakiety dzienników npm to `brolog`, `npmlogger`, `npmdate log`.
Roarr
Roarr to rejestrator dla Node.js, który nie wymaga inicjalizacji i generuje uporządkowane dane. Posiada CLI i zmienne środowiskowe. Jest kompatybilny z przeglądarką. Może być zintegrowany z Fastify, Fastify, Elastic Search. Rozróżnia kod aplikacji od kodu zależności. Każdy komunikat logu zawiera kontekst, wiadomość, sekwencję, czas i wersję. Poziomy dziennika obejmują śledzenie, debugowanie, informacje, ostrzeżenie, błąd i krytyczny. Poniżej znajduje się przykładowy kod rejestrowania w Roarr:
import { ROARR, } from 'roarr'; ROARR.write = (message) => { console.log(JSON.parse(message)); };
Można również wykonywać serializację błędów, tzn. wystąpienie błędu można zarejestrować wraz z kontekstem obiektu. Zmienne środowiskowe specyficzne dla Node.js i Roarr to `ROARR_LOG` i `ROARR_STREAM`. „adoptuj” to funkcja używana w Node.js do przekazywania właściwości kontekstu na różne poziomy. Funkcje potomne mogą być też używane z oprogramowaniem pośredniczącym podczas rejestrowania.
Podsumowanie
Rejestrowanie to sposób śledzenia różnych działań i zdarzeń podczas wykonywania programu. Odgrywa kluczową rolę w debugowaniu kodu. Pomaga także w zwiększeniu czytelności kodu. Node.js to otwarte środowisko uruchomieniowe dla JavaScript. Do najpopularniejszych rejestratorów dla Node.js zalicza się Pino, Winston, Bunyan, Signale, Tracer, Npmlog. Każdy z nich ma swoje unikalne funkcje, np. profilowanie, filtrowanie, przesyłanie strumieniowe i transport.
Niektóre rejestratory obsługują kolorową konsolę, a inne są przystosowane do obsługi poufnych danych. Szczegółowe i sformatowane logi są szczególnie pomocne programistom podczas naprawiania błędów. Format JSON jest zazwyczaj preferowany do rejestrowania, gdyż zapisuje dane w postaci par klucz-wartość, co czyni go czytelnym.
Rejestratory można zintegrować z innymi aplikacjami i są kompatybilne z wieloma przeglądarkami. Przed wyborem typu rejestratora, zawsze należy wziąć pod uwagę specyfikę aplikacji.
Możesz również zapoznać się z instrukcją instalacji Node.js i NPM w systemach Windows i macOS.