Să vorbim despre logare, vom? Arnold aici care transportă un jurnal gigant se simte ca un intro adecvat la acest articol în care vom vorbi despre nod populare.JS cadre de logare.
dacă scrieți orice fel de aplicație de viață lungă, logarea detaliată este esențială pentru depistarea problemelor și depanarea. Fără jurnalele ar avea câteva moduri de a spune cum se comportă cererea dumneavoastră, există erori, ceea ce este performanța ca, este de a face ceva la toate sau este doar care se încadrează peste orice altă cerere, atunci când nu se uita la ea.
cerințe
vă permite să identifice câteva cerințe pe care le putem folosi pentru a groapă cadrele împotriva celuilalt. Unele dintre aceste cerințe sunt destul de banale, altele nu sunt atât de multe.
- ștampila de timp fiecare linie de jurnal. Acesta este destul de auto-explicativ – ar trebui să fie în măsură să spun când fiecare intrare jurnal a avut loc.
- formatul de logare ar trebui să fie ușor digerabil atât de oameni, cât și de mașini.
- permite mai multe fluxuri de destinație configurabile. De exemplu, este posibil să scrieți jurnale de urmărire într-un fișier, dar când se întâlnește o eroare, scrieți în același fișier, apoi în fișier de eroare și trimiteți un e-mail în același timp.
pe baza acestor cerințe (și popularitate) există două cadre de logare pentru nod.js merită verificat, în special:
- Bunyan de Trent Mick.
- Winston face parte din cadrul Flatiron și este sponsorizat de nodejitstu.
consola
înainte de a ajunge la Bunyan și Winston, să ne uităm la vechiul nostru prietenconsole
. Cel mai rudimentar tip de logare pe care l-ați putea face este să utilizați console.log
și console.error
metode. Acest lucru este mai bun decât nimic, dar cu greu cea mai bună soluție. Consola scrie la STDOUT și respectiv STDERR. Există un avertisment foarte interesant de știut când vine vorba deconsole
metode în nod.js.
funcțiile consolei sunt sincrone atunci când destinația este un terminal sau un fișier (pentru a evita mesajele pierdute în caz de ieșire prematură) și asincrone atunci când este o conductă (pentru a evita blocarea pentru perioade lungi de timp).
adică, în exemplul următor, stdout nu blochează în timp ce stderr blochează:
$ node script.js 2> error.log | tee info.log
aceasta este practic o abordare de logare „roll your own”. Este complet manual, trebuie să veniți cu propriul format și, practic, să gestionați totul singur. Acest lucru consumă mult timp, este predispus la erori și probabil că doriți să vă concentrați pe caracteristicile aplicației dvs. Având în vedere că există biblioteci de logare open source acolo, care sunt menținute în mod activ, acest lucru nu merită efortul dacă încercați să vă concentrați pe furnizarea de funcții.
Winston
una dintre cele mai populare nod.JS cadre de logare este Winston. Este conceput pentru a fi o bibliotecă de logare simplă și universală, cu suport pentru mai multe transporturi (un transport în lumea lui Winston este în esență un dispozitiv de stocare, de exemplu, unde jurnalele dvs. ajung să fie stocate). Fiecare instanță a unui Winston logger poate avea mai multe transporturi configurate la diferite niveluri de înregistrare.
instalare
npm install winston
utilizare
cea mai de bază Utilizare Winston constă în apelarea instanței implicite care este exportată din modulul
winston
.var winston = require('winston');winston.log('info', 'Hello distributed log files!');winston.info('Hello again distributed logs');
cele de mai sus sunt aceleași cu:
ambele exemple vor produce următoarea ieșire:
info: Hello distributed log files!info: Hello again distributed logs
formatare
personal sunt un pic nedumerit de lipsa de detalii în formatatorul implicit. Nu există ștampilă de timp, numele mașinii sau ID-ul procesului, iar formatul de ieșire este ușor potrivit pentru analiza mașinii. Acestea fiind spuse, puteți obține toate informațiile afară-te cu doar un pic de muncă suplimentară.
winston.info('Hello world!', {timestamp: Date.now(), pid: process.pid});
produce următoarea ieșire, care este mai informativă, dar încă nu este foarte potrivită pentru analiza mașinii.
info: Hello world! timestamp=1402286804314, pid=80481
În cele din urmă,
log
metoda oferă aceleași metode de interpolare șir cautil.format
, de exemplu:winston.log('info', 'test message %d', 123);
transportoare
Winston ar putea fi configurat prin opțiuni constructor sau metoda expuse, care sunt foarte bine documentate pe pagina GitHub. Cea mai mare parte a configurației se învârte de obicei în jurul diferitelor transporturi. Din cutie Winston vine cu console și transporturi bazate pe fișiere și, dacă aveți o privire pe npmjs.org veți vedea că există module comunitare pentru aproape tot ceea ce se poate imagina, de la MongoDB la platforme comerciale terțe.
unul dintre cei mai notabili transportatori în opinia mea este Winston-irc de Nathan Zadoks pe care îl puteți folosi pentru a înregistra erori pe canalul IRC al echipei dvs. Văd că asta vine foarte la îndemână.
winston.add(require('winston-irc'), { host: 'irc.somewhere.net', nick: 'logger', pass: 'hunter2', channels: { '#logs': true, 'sysadmin': }});
mai multe loggere
odată ce aplicația dvs. începe să crească, este posibil să doriți să aveți mai multe loggere cu configurații diferite în care fiecare logger este responsabil pentru o zonă (sau categorie) caracteristică diferită. Winston susține că în două moduri: prin
winston.loggers
și instanțe dewinston.Container
. De fapt,winston.loggers
este doar o instanță predefinită awinston.Container
:winston.loggers.add('category1', {console: { ... }, file: { ... }});winston.loggers.add('category2', {irc: { ... }, file: { ... }});
acum, că loggere dvs. sunt configurate puteți solicita Winston în orice fișier în cererea dumneavoastră și accesați aceste loggere preconfigurate:
var category1 = winston.loggers.get('category1');category1.info('logging from your IoC container-based logger');
mai mult
aceasta este cea mai de bază Utilizare Winston, dar există destul de multe alte caracteristici, mai ales:
- profilare
- String interpolare
- interogarea și streaming
- manipularea exeptions
Bunyan
Ilustrație de Brendan Corris
Bunyan de Trent Mick este un alt cadru de logare care cred că ar trebui să fie luate în considerare. Bunyan are o abordare ușor diferită de logare decât Winston a face misiunea sa de a oferi busteni structurate, mașină de citit ca cetățeni de primă clasă. Ca rezultat, o înregistrare jurnal de la Bunyan este o linie de
JSON.stringify
ieșire cu unele nume comune pentru câmpurile necesare și comune pentru o înregistrare jurnal.instalare
npm install bunyan
utilizare
var bunyan = require('bunyan');var log = bunyan.createLogger({name: 'myapp'});log.info('hi');log.warn({lang: 'fr'}, 'au revoir');
care va produce următoarea ieșire:
după cum puteți vedea, din cutie Bunyan nu este foarte prietenos cu oamenii, cu toate acestea cele mai moderne sisteme de logare înțeleg formatul JSON nativ, ceea ce înseamnă că există puține lucruri de făcut aici pentru a alimenta jurnalele în altă parte pentru depozitare și procesare. În mod implicit, există destul de multe date meta incluse în fiecare mesaj, cum ar fi ștampila de timp, ID-ul procesului, numele gazdei și numele aplicației.
desigur, noi, oamenii, nu găsim acest lucru foarte digerabil și pentru a aborda că există un
bunyan
instrument CLI la care ia în JSON prin STDIN. Iată același exemplu transmis prinbunyan
:node example.js | bunyan
produce următoarea ieșire:
INFO: myapp/13372 on pwony-2: hi WARN: myapp/13372 on pwony-2: au revoir (lang=fr)
principalul beneficiu aici este că nu trebuie să reconfigurați nimic pentru mediul de dezvoltare, tot ce trebuie să faceți este să introduceți
bunyan
. Verificați pagina GitHub pentru mai multe documentații despre instrumentul CLI.JSON
una dintre diferențele cheie dintre Bunyan și Winston este că Bunyan funcționează foarte bine atunci când doriți să vă conectați contexte și obiecte complexe. Să ne uităm la această linie și la ieșirea sa din exemplul de mai sus:
puteți vedea că
{lang: 'fr'}
a fost fuzionat cu obiectul principal de jurnal șiau revoir
a devenitmsg
. Acum imaginați-vă ceva de genul acesta:log.info(user, 'registered');log.info({user: user}, 'registered');
care produce:
sau când este introdus prin
bunyan
:frumusețea acestei abordări va deveni clară atunci când ne uităm la loggerii pentru copii.
Loggers pentru copii
Bunyan are un concept de loggers pentru copii, care permite specializarea unui logger pentru o sub-componentă a aplicației dvs., adică. pentru a crea un nou logger cu câmpuri legate suplimentare care vor fi incluse în înregistrările sale jurnal. Un logger copil este creat cu
log.child(...)
. Acest lucru vine în incredibil de util, dacă doriți să aveți loggers scoped pentru diferite componente din sistemul dvs., cereri, sau pur și simplu apeluri de funcții. Să ne uităm la un cod.Imaginați-vă că doriți să efectuați ID-ul cererii prin toate liniile de jurnal pentru o anumită cerere, astfel încât să le puteți lega împreună.
req.log
logger va păstra întotdeauna contextul trecut lalog.child()
funcția și fuziona cu toate apelurile ulterioare, astfel încât ieșirea ar arata ceva de genul asta:{"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}
serializatori
două probleme apar atunci când Bunyan încearcă să Stringify obiecte întregi:
- referințe circulare. Winston este un pic mai inteligent aici și detectează referințe circulare atunci când apar (cu toate acestea rezultatul
$ref=$
nu este foarte util).- zgomot nedorit. Mi se pare că, deoarece obiectele sunt de primă clasă, este mult mai ușor să intri într-un obicei de a arunca totul în jurnal.
pentru a ajuta la a face cu atât, Bunyan are un concept de serializer care sunt practic funcții de transformare care vă permit să Domeniul de aplicare în jos obiecte de obicei a trecut la doar domeniile care vă interesează:
acum încearcă să vă conectați
req
obiect ar include doar cele trei domenii care ne interesează.Streams
Streams în Bunyan sunt același lucru ca și transportatorii în Winston – este o modalitate de a trimite jurnalele în altă parte în scopuri de afișare și stocare. Bunyan folosește o interfață de flux care poate fi scrisă cu câteva atribute suplimentare. O instanță Bunyan logger are unul sau mai multe fluxuri și sunt specificate cu
streams
opțiune:var log = bunyan.createLogger({ name: "foo", streams: });
mai multe
iată câteva lucruri mai notabile pentru a explora în Bunyan:
- runtime log snooping via suport DTrace
- câmpuri de înregistrare jurnal
care să aleagă?
Winston și Bunyan sunt ambele cadre de logare foarte mature și stabilite și sunt foarte mult la egalitate în ceea ce privește caracteristicile. Winston are o mulțime de sprijin comunitar cu diferite module de logare. Bunyan face ușor din cutie pentru a analiza jurnalele, dar lasă consumul utilizatorului (în general, syslog drain funcționează destul de bine aici). Simt că totul se reduce la preferință și la cât de ușor este să te integrezi cu stiva ta.
- ce vine la următoarea versiune de nod? Citiți despre opt noi caracteristici interesante Node v0.12 și cum să profitați la maximum de ele, de la autorii înșiși.
- gata să dezvolte API-uri în nod.js și să le conectați la datele dvs.? Uită-te la nod.js LoopBack cadru API. Am făcut-o ușor pentru a începe, fie la nivel local sau pe nor dumneavoastră preferat, cu un simplu NPM instala.
- aveți nevoie de instruire și certificare pentru Node? Aflați mai multe despre opțiunile private și deschise oferite de StrongLoop.