porównujący węzeł Winstona i Bunyana.js Logging

porozmawiajmy o logowaniu, dobrze? Arnold noszący gigantyczny dziennik wydaje się być odpowiednim wstępem do tego artykułu, w którym będziemy mówić o popularnym węźle.frameworki logowania js.

Jeśli piszesz jakąś długą aplikację, szczegółowe rejestrowanie jest najważniejsze dla wykrywania problemów i debugowania. Bez dzienników miałbyś kilka sposobów, aby powiedzieć, jak zachowuje się Twoja aplikacja, czy są błędy, jaka jest wydajność, czy robi coś w ogóle, czy po prostu spada na każde inne żądanie, gdy na nie nie patrzysz.

wymagania

pozwala zidentyfikować kilka wymagań, których możemy użyć do porównywania frameworków ze sobą. Niektóre z tych wymagań są dość trywialne, inne nie są tak bardzo.

  1. znacznik czasu każdej linii dziennika. Ten jest dość oczywisty – powinieneś być w stanie powiedzieć, kiedy wystąpił każdy wpis w dzienniku.
  2. format logowania powinien być łatwo przyswajalny zarówno przez ludzi, jak i maszyny.
  3. pozwala na wiele konfigurowalnych strumieni docelowych. Na przykład możesz zapisywać dzienniki śledzenia do jednego pliku, ale gdy wystąpi błąd, Zapisz do tego samego pliku, a następnie do pliku błędu i wyślij wiadomość e-mail w tym samym czasie.

w oparciu o te wymagania (i popularność) istnieją dwa frameworki logowania dla węzła.js warto sprawdzić, w szczególności:

  • Bunyan by Trent Mick.
  • Winston jest częścią Flatiron framework i sponsorowany przez nodejitstu.

konsola

zanim dotrzemy do Bunyana i Winstona, przyjrzyjmy się naszemu staremu przyjacielowiconsole. Najbardziej podstawowym rodzajem logowania, jaki możesz zrobić, jest użycie metod console.log I console.error. To lepsze niż nic, ale nie najlepsze rozwiązanie. Konsola zapisuje odpowiednio do STDOUT i STDERR. Istnieje bardzo interesujące zastrzeżenie, które należy wiedzieć, jeśli chodzi o metodyconsole w węźle.js.

funkcje konsoli są synchroniczne, gdy miejscem docelowym jest terminal lub plik (aby uniknąć utraty wiadomości w przypadku przedwczesnego zakończenia) i asynchroniczne, gdy jest to rura (aby uniknąć blokowania przez dłuższy czas).

oznacza to, że w poniższym przykładzie stdout nie jest blokowany, podczas gdy stderr jest blokowany:

$ node script.js 2> error.log | tee info.log

jest to zasadniczo podejście do rejestrowania „roll your own”. Jest w pełni ręczny, musisz wymyślić własny format i w zasadzie zarządzać wszystkim samodzielnie. Jest to czasochłonne, podatne na błędy i prawdopodobnie chcesz skupić się na funkcjach aplikacji. Biorąc pod uwagę, że istnieją otwarte biblioteki rejestrujące źródła, które są aktywnie utrzymywane, nie jest to warte wysiłku, jeśli próbujesz skupić się na dostarczaniu funkcji.

jeden z najpopularniejszych węzłów.js logging framework to Winston. Ma być prostą i uniwersalną biblioteką logowania z obsługą wielu transportów(transport w świecie Winstona jest zasadniczo urządzeniem magazynującym, np. w którym przechowywane są logi). Każda instancja rejestratora Winston może mieć wiele transportów skonfigurowanych na różnych poziomach logowania.

instalacja

npm install winston

użycie

najbardziej podstawowe użycie Winstona polega na wywołaniu domyślnej instancji eksportowanej z modułuwinston.

var winston = require('winston');winston.log('info', 'Hello distributed log files!');winston.info('Hello again distributed logs');

powyższe jest takie samo jak:

oba przykłady wygenerują następujące wyjście:

info: Hello distributed log files!info: Hello again distributed logs

formatowanie

osobiście trochę mnie zastanawia brak szczegółów w domyślnym formatowaniu. Nie ma znacznika czasu, nazwy Maszyny ani identyfikatora procesu, a format wyjściowy jest łagodnie odpowiedni do parsowania maszynowego. Powiedziawszy, że możesz uzyskać wszystkie informacje samodzielnie, przy odrobinie dodatkowej pracy.

winston.info('Hello world!', {timestamp: Date.now(), pid: process.pid});

Wytwarza następujące wyjście, które jest bardziej pouczające, ale nadal nie jest zbyt odpowiednie do parsowania maszynowego.

info: Hello world! timestamp=1402286804314, pid=80481

wreszcie, metoda log zapewnia te same metody interpolacji łańcuchów co util.format, na przykład:

winston.log('info', 'test message %d', 123);

transportery

można skonfigurować za pomocą opcji konstruktora lub metody exposed, które są bardzo dokładnie udokumentowane na stronie GitHub. Większość konfiguracji zazwyczaj obraca się wokół różnych transportów. Po wyjęciu z pudełka Winston jest wyposażony w transporty oparte na konsoli i plikach, a jeśli zajrzysz na npmjs.org zobaczysz, że istnieją Moduły społeczności dla prawie wszystkiego, co można sobie wyobrazić, od MongoDB po komercyjne platformy stron trzecich.

jednym z bardziej znaczących transporterów moim zdaniem jest winston-irc by Nathan Zadoks, którego możesz użyć do logowania błędów na kanale IRC Twojego zespołu. Widzę, że to się bardzo przyda.

winston.add(require('winston-irc'), { host: 'irc.somewhere.net', nick: 'logger', pass: 'hunter2', channels: { '#logs': true, 'sysadmin': }});

wiele rejestratorów

gdy aplikacja zacznie się rozwijać, prawdopodobnie będziesz chciał mieć wiele rejestratorów z różnymi konfiguracjami, w których każdy rejestrator jest odpowiedzialny za inny obszar funkcji (lub kategorię). Winston obsługuje to na dwa sposoby :poprzezwinston.loggers I instancjewinston.Container. W rzeczywistości winston.loggers jest tylko predefiniowaną instancją winston.Container:

winston.loggers.add('category1', {console: { ... }, file: { ... }});winston.loggers.add('category2', {irc: { ... }, file: { ... }});

teraz, gdy twoje Rejestratory są skonfigurowane, możesz wymagać Winstona w dowolnym pliku w aplikacji i uzyskać dostęp do tych wstępnie skonfigurowanych rejestratorów:

var category1 = winston.loggers.get('category1');category1.info('logging from your IoC container-based logger');

więcej

To jest najbardziej podstawowe użycie, ale jest sporo innych funkcji, przede:

  • Profilowanie
  • interpolacja łańcuchów
  • zapytania i streaming
  • Obsługa exepcji

Bunyan

Ilustracja autorstwa Brendana Corrisa

Bunyan autorstwa Trenta Micka to kolejny framework logowania, który moim zdaniem powinien być brany pod uwagę. Bunyan ma nieco inne podejście do logowania niż Winston, którego misją jest dostarczanie ustrukturyzowanych, czytelnych maszynowo dzienników jako obywatele pierwszej klasy. W rezultacie, rekord dziennika z Bunyana jest jedną linią wyjściaJSON.stringify z niektórymi wspólnymi nazwami dla wymaganych i wspólnych pól dla rekordu dziennika.

instalacja

npm install bunyan

użycie

var bunyan = require('bunyan');var log = bunyan.createLogger({name: 'myapp'});log.info('hi');log.warn({lang: 'fr'}, 'au revoir');

, które spowoduje następujące wyjście:

Jak widać, po wyjęciu z pudełka Bunyan nie jest zbyt przyjazny dla człowieka, jednak większość nowoczesnych systemów rejestrowania rozumie natywnie format JSON, co oznacza, że niewiele jest tutaj do zrobienia, aby karmić logi gdzie indziej w celu przechowywania i przetwarzania. Domyślnie każda wiadomość zawiera sporo metadanych, takich jak znacznik czasu, identyfikator procesu, Nazwa hosta i nazwa aplikacji.

oczywiście, my ludzie, nie znajdujemy tego bardzo strawnego i zwracamy uwagę, że istniejebunyan narzędzie CLI, do którego pobiera JSON poprzez STDIN. Oto ten sam przykład:bunyan:

node example.js | bunyan

daje następujące wyjście:

 INFO: myapp/13372 on pwony-2: hi WARN: myapp/13372 on pwony-2: au revoir (lang=fr)

główną zaletą jest to, że nie musisz niczego rekonfigurować do środowiska programistycznego, wystarczy, że podłączysz się dobunyan. Checkout the GitHub page for more documentation on the CLI tool.

JSON

jedną z kluczowych różnic między Bunyan i Winstonem jest to, że Bunyan działa naprawdę dobrze, gdy chcesz rejestrować złożone konteksty i Obiekty. Spójrzmy na tę linię i jej wyjście z powyższego przykładu:

widać, że{lang: 'fr'} został scalony z głównym obiektem dziennika iau revoir stał sięmsg. Teraz wyobraź sobie coś takiego:

log.info(user, 'registered');log.info({user: user}, 'registered');

, który wytwarza:

lub po przebiciu przezbunyan:

piękno tego podejścia stanie się jasne, gdy spojrzymy na rejestratory dziecięce.

Child Loggers

Bunyan ma koncepcję child loggers, która pozwala wyspecjalizować rejestrator dla sub-komponentu aplikacji, tj. aby utworzyć nowy rejestrator z dodatkowymi polami powiązanymi, które będą zawarte w jego rekordach dziennika. Logger potomny jest tworzony za pomocą log.child(...). Jest to niezwykle przydatne, jeśli chcesz mieć rejestratory zakresów dla różnych komponentów w systemie, żądań lub po prostu zwykłych wywołań funkcji. Spójrzmy na jakiś kod.

wyobraź sobie, że chcesz przenosić identyfikator żądania przez wszystkie linie dziennika dla danego żądania, aby móc je wszystkie połączyć.

req.log logger zawsze zachowa swój kontekst przekazany do funkcjilog.child() I Scali ją ze wszystkimi kolejnymi wywołaniami, tak aby wyjście wyglądało mniej więcej tak:

{"name":"myapp","hostname":"pwony-2","pid":14837,"level":30,"reqId":"XXXX-XX-XXXX","user":"[email protected]","time":"2014-05-26T18:27:43.530Z","v":0}

serializery

dwa problemy pojawiają się, gdy Bunyan próbuje stringizować całe obiekty:

  1. odwołania kołowe. Winston jest nieco mądrzejszy i wykrywa okrągłe odwołania, kiedy one występują (jednak wynik $ref=$ nie jest zbyt przydatny).
  2. niechciany hałas. Wydaje mi się, że ponieważ przedmioty są w pierwszej klasie, znacznie łatwiej jest nabrać nawyku po prostu wyrzucania wszystkiego do dziennika.

aby pomóc sobie z obydwoma, Bunyan ma koncepcję serializera, które są w zasadzie funkcjami transformacji, które pozwalają analizować powszechnie przekazywane obiekty tylko do pól, które Cię interesują:

teraz próbując zalogowaćreq obiekt będzie zawierał tylko trzy pola, które nas interesują.

strumienie

strumienie w Bunyan są tym samym, co transportery w Winston – jest to sposób na wysyłanie logów gdzie indziej w celach wyświetlania i przechowywania. Bunyan używa zapisywalnego interfejsu strumienia z dodatkowymi atrybutami. Instancja rejestratora Bunyan ma jeden lub więcej strumieni i jest określona za pomocą opcji streams:

var log = bunyan.createLogger({ name: "foo", streams: });

więcej

Oto kilka innych wartych uwagi rzeczy do zbadania w Bunyan:

  • obsługa DTrace
  • pola rekordów dziennika

które wybrać?

Winston i Bunyan są zarówno bardzo Dojrzałymi i ugruntowanymi frameworkami do logowania i są bardzo podobne pod względem funkcji. Winston ma wiele wsparcia społeczności dzięki różnym modułom logowania. Bunyan ułatwia po wyjęciu z pudełka analizowanie dzienników, ale pozostawia zużycie użytkownikowi (ogólnie syslog drain działa tutaj całkiem dobrze). Czuję, że wszystko sprowadza się do preferencji i tego, jak łatwo jest zintegrować się ze stosem.

  • co będzie w następnym wydaniu węzła? Przeczytaj o ośmiu ekscytujących nowych funkcjach Node v0. 12 i jak je w pełni wykorzystać, od samych autorów.
  • gotowy do rozwijania API w węźle.js i podłączyć je do swoich danych? Sprawdź węzeł.js loopback API framework. Ułatwiliśmy rozpoczęcie pracy lokalnie lub w ulubionej chmurze dzięki prostej instalacji npm.
  • potrzebujesz szkolenia i certyfikacji dla Node? Dowiedz się więcej o ofertach prywatnych i otwartych opcji StrongLoop.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.