sammenligning af Bunyan Node.js Logging

lad os tale om logning, skal vi? Arnold herovre med en kæmpe log føles som en passende introduktion til denne artikel, hvor vi skal tale om populær knude.JS logning rammer.

Hvis du skriver nogen form for lang levetid ansøgning, detaljeret logning er altafgørende at spotte problemer og debugging. Uden logfiler ville du have få måder at fortælle, hvordan din applikation opfører sig, er der Fejl, Hvordan er ydeevnen, gør det overhovedet noget, eller falder det bare over enhver anden anmodning, når du ikke ser på det.

krav

lad os identificere et par krav, som vi kan bruge til at sætte rammerne mod hinanden. Nogle af disse krav er ret trivielle, andre er ikke så meget.

  1. tidsstempel hver loglinje. Denne ene er temmelig selvforklarende-du bør være i stand til at fortælle, når hver log post indtraf.
  2. Logging format skal være let fordøjeligt af mennesker såvel som maskiner.
  3. giver mulighed for flere konfigurerbare destination streams. For eksempel skriver du muligvis sporingslogfiler til en fil, men når der opstår en fejl, skal du skrive til den samme fil og derefter til fejlfil og sende en e-mail på samme tid.

baseret på disse krav (og popularitet) er der to logningsrammer for Node.js værd at tjekke ud, især:

  • Bunyan af Trent Mick.
  • er en del af Flatiron-rammen og sponsoreret af nodejitstu.

konsol

før vi kommer til Bunyan og Vinston, lad os se på vores gamle venconsole. Den mest rudimentære type logning, du kan gøre, er at brugeconsole.log ogconsole.error metoder. Dette er bedre end intet, men næppe den bedste løsning. Konsol skriver til henholdsvis STDOUT og STDERR. Der er en meget interessant advarsel at vide, når det kommer til console metoder i Node.js.

konsolfunktionerne er synkrone, når destinationen er en terminal eller en fil (for at undgå mistede meddelelser i tilfælde af for tidlig udgang) og asynkron, når det er et rør (for at undgå blokering i lange perioder).

det er i det følgende eksempel, at stdout ikke blokerer, mens stderr blokerer:

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

Dette er dybest set en “rul din egen” logning tilgang. Det er fuldt manuelt, du er nødt til at komme med dit eget format og dybest set styre alt selv. Dette er tidskrævende, udsat for fejl, og du vil sandsynligvis fokusere på dine applikationsfunktioner i stedet. I betragtning af at der er open source logging biblioteker derude, som er aktivt vedligeholdt, dette er ikke umagen værd, hvis du forsøger at fokusere på at levere funktioner.

Vinston

en af de mest populære Node.js logging rammer er Vinston. Det er designet til at være en enkel og universel logning bibliotek med understøttelse af flere transporter (en transport i verden er hovedsagelig en lagerenhed, f.eks hvor dine logfiler ender med at blive gemt). Hver forekomst af en logger kan have flere transporter konfigureret på forskellige logningsniveauer.

Installation

npm install winston

brug

den mest basale brug af brug består i at kalde standardforekomsten, der eksporteres frawinston modul.

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

ovenstående er det samme som:

begge eksempler vil producere følgende output:

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

formatering

personligt er jeg lidt forvirret af manglen på detaljer i standardformateren. Der er intet tidsstempel, maskinnavn eller proces-ID, og outputformatet er mildt egnet til maskinparsing. Når det er sagt, kan du få alle oplysninger ud selv med bare lidt ekstra arbejde.

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

producerer følgende output, som er mere informativ, men stadig ikke særlig velegnet til maskinparsing.

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

endelig giver log metoden de samme strenginterpolationsmetoder som util.format, for eksempel:

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

transportører

kan konfigureres via konstruktørindstillinger eller eksponeret metode, som er meget grundigt dokumenteret på GitHub-siden. Det meste af konfigurationen drejer sig typisk om forskellige transporter. Ud af boksen kommer med konsol og fil baserede transporter, og hvis du har et kig på npmjs.org du vil se, at der er fællesskabsmoduler til stort set alt tænkeligt lige fra MongoDB til kommercielle tredjepartsplatforme.

en af de mere bemærkelsesværdige transportører efter min mening er , som du kan bruge til at logge fejl på dit holds IRC-kanal. Jeg kan se, at dette kommer meget praktisk.

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

flere loggere

Når din applikation begynder at vokse, er chancerne for, at du vil have flere loggere med forskellige konfigurationer, hvor hver logger er ansvarlig for et andet funktionsområde (eller kategori). Gennem winston.loggers og forekomster af winston.Container. Faktisk winston.loggers er bare en foruddefineret forekomst af winston.Container:

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

nu hvor dine loggere er konfigureret, kan du få adgang til disse forudkonfigurerede loggere:

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

More

dette er mest grundlæggende brug, men der er en hel del andre funktioner, især:

  • profilering
  • String interpolation
  • forespørgsel og streaming
  • håndtering af undtagelser

Bunyan

Illustration af Brendan Corris

Bunyan af Trent Mick er en anden logningsramme, som jeg synes burde være overvejes. Bunyan tager en lidt anden tilgang til logning end Vinston gør sin mission at give struktureret, maskinlæsbare logfiler som førsteklasses borgere. Som et resultat er en logpost fra Bunyan en linje med JSON.stringify output med nogle almindelige navne for de nødvendige og fælles felter til en logpost.

Installation

npm install bunyan

brug

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

som vil producere følgende output:

som du kan se, ud af kassen Bunyan er ikke særlig menneskelig venlig, men de fleste moderne logsystemer forstår JSON-format indbygget, hvilket betyder, at der ikke er meget at gøre her for at fodre logfilerne andre steder til opbevaring og behandling. Som standard er der en hel del metadata inkluderet i hver meddelelse, såsom tidsstempel, proces-ID, værtsnavn og applikationsnavn.

selvfølgelig finder os mennesker ikke dette meget fordøjeligt og for at adressere, at der er et bunyan CLI-værktøj, som tager JSON via STDIN. Her er det samme eksempel pipes gennem bunyan:

node example.js | bunyan

producerer følgende output:

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

den største fordel her er, at du ikke behøver at omkonfigurere noget til udviklingsmiljø, alt hvad du skal gøre er at rør tilbunyan. Tjek GitHub-siden for mere dokumentation på CLI-værktøjet.

JSON

en af de vigtigste forskelle mellem Bunyan og Bunyan er, at Bunyan fungerer rigtig godt, når du vil logge komplekse sammenhænge og objekter. Lad os se på denne linje og dens output fra eksemplet ovenfor:

Du kan se, at{lang: 'fr'} blev fusioneret med hovedlogobjektet ogau revoir blevmsg. Forestil dig nu noget som dette:

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

som producerer:

eller når du ledes gennembunyan:

skønheden i denne tilgang bliver klar, når du ser på børneloggere.

Børneloggere

Bunyan har et koncept med børneloggere, som gør det muligt at specialisere en logger til en underkomponent i din applikation, dvs. at oprette en ny logger med yderligere bundne felter, der vil blive inkluderet i dens logposter. En barn logger er oprettet med log.child(...). Dette er utroligt praktisk, hvis du vil have scoped loggere til forskellige komponenter i dit system, anmodninger eller bare almindelige funktionsopkald. Lad os se på nogle kode.

Forestil dig, at du vil bære anmodnings-ID gennem alle loglinjer for en given anmodning, så du kan binde dem alle sammen.

req.log logger vil altid holde sin kontekst overført tillog.child() funktionen og flette den med alle efterfølgende opkald, så output ville se sådan ud:

{"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}

serialisatorer

to problemer opstår, når Bunyan forsøger at stramme hele objekter:

  1. cirkulære referencer. Her er en lille smule smartere og registrerer cirkulære referencer, når de opstår (men resultatet output $ref=$ er ikke meget nyttigt).
  2. uønsket støj. Det føles for mig, at fordi objekter er første klasse i det er meget lettere at komme ind i en vane med bare at dumpe alt i loggen.

for at hjælpe med at håndtere begge, har Bunyan et koncept af serialisator, der dybest set er transformationsfunktioner, som lader dig scope ned almindeligt overførte objekter til bare de felter, du er interesseret i:

forsøger nu at loggereq objekt vil bare omfatte de tre felter, som vi er interesseret i.

Streams

streams i Bunyan er det samme som transportører i Bunyan – det er en måde at sende dine logfiler andre steder til visning og opbevaring. Bunyan bruger en skrivbar Stream interface med nogle ekstra attributter. En Bunyan logger-forekomst har en eller flere strømme og er specificeret med streams mulighed:

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

mere

Her er et par mere bemærkelsesværdige ting at udforske i Bunyan:

  • Runtime log snooping via DTrace support
  • log record fields

hvilken skal man vælge?

Bunyan er begge meget modne og etablerede logningsrammer og er meget på niveau med hensyn til funktioner. Vi har en masse fællesskabsstøtte med forskellige logning moduler. Bunyan gør det nemt ud af kassen at analysere logfiler, men efterlader forbruget op brugeren (generelt syslog drain fungerer ret godt her). Jeg føler, at det hele kommer ned til præference, og hvor nemt det er at integrere med din stak.

  • Hvad kommer til næste Node udgivelse? Læs om otte spændende nye Node v0.12-Funktioner, og hvordan du får mest muligt ud af dem, fra forfatterne selv.
  • klar til at udvikle API ‘ er i Node.js og få dem forbundet til dine data? Tjek noden.JS LoopBack API rammer. Vi har gjort det nemt at komme i gang enten lokalt eller på din yndlingssky med en simpel npm-installation.
  • brug for uddannelse og certificering for Node? Lær mere om både de private og åbne muligheder StrongLoop tilbyder.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.