An mutable object-based log format designed for chaining & objectMode streams.
const{ format }=require('logform');constalignedWithColorsAndTime=format.combine(format.colorize(),format.timestamp(),format.align(),format.printf(info=>`${info.timestamp}${info.level}: ${info.message}`));The info parameter provided to a given format represents a single log message. The object itself is mutable. Every info must have at least the level and message properties:
{level: 'info',// Level of the logging message message: 'Hey! Log something?'// Descriptive message being logged.}logform itself exposes several additional properties:
splat: string interpolation splat for%d %s-style messages.timestamp: timestamp the message was received.label: custom label associated with each message.
As a consumer you may add whatever properties you wish – internal state is maintained by Symbol properties:
Symbol.for('level')(READ-ONLY): equal tolevelproperty. Is treated as immutable by all code.Symbol.for('message'):complete string message set by "finalizing formats":json,logstash,printf,prettyPrint, andsimple.
Formats are prototypal objects (i.e. class instances) that define a single method: transform(info, opts) and return the mutated info
info: an object representing the log message.opts: setting specific to the current instance of the format.
They are expected to return one of two things:
- An
infoObject representing the modifiedinfoargument. Object references need not be preserved if immutability is preferred. All current built-in formats considerinfomutable, but [immutablejs] is being considered for future releases. - A falsey value indicating that the
infoargument should be ignored by the caller. (See: FilteringinfoObjects) below.
logform.format is designed to be as simple as possible. To define a new format simple pass it a transform(info, opts) function to get a new Format.
The named Format returned can be used to create as many copies of the given Format as desired:
const{ format }=require('logform');constvolume=format((info,opts)=>{if(opts.yell){info.message=info.message.toUpperCase();}elseif(opts.whisper){info.message=info.message.toLowerCase();}returninfo;});// `volume` is now a function that returns instances of the format.constscream=volume({yell: true});console.dir(scream.transform({level: 'info',message: `sorry for making you YELL in your head!`},scream.options));// {// level: 'info'// message: 'SORRY FOR MAKING YOU YELL IN YOUR HEAD!'// }// `volume` can be used multiple times to create different formats.constwhisper=volume({whisper: true});console.dir(whisper.transform({level: 'info',message: `WHY ARE THEY MAKING US YELL SO MUCH!`}),whisper.options);// {// level: 'info'// message: 'why are they making us yell so much!'// }Any number of formats may be combined into a single format using format.combine. Since format.combine takes no opts, as a convenience it returns pre-created instance of the combined format.
const{ format }=require('logform');const{ combine, timestamp, label }=format;constlabelTimestamp=combine(label({label: 'right meow!'}),timestamp());constinfo=labelTimestamp.transform({level: 'info',message: 'What time is the testing at?'});console.dir(info);// { level: 'info',// message: 'What time is the testing at?',// label: 'right meow!',// timestamp: '2017-09-30T03:57:26.875Z' }If you wish to filter out a given info Object completely then simply return a falsey value.
constignorePrivate=format((info,opts)=>{if(info.private){returnfalse;}returninfo;});console.dir(ignorePrivate.transform({level: 'error',message: 'Public error to share'}));// { level: 'error', message: 'Public error to share' }console.dir(ignorePrivate.transform({level: 'error',private: true,message: 'This is super secret - hide it.'}));// falseUse of format.combine will respect any falsey values return and stop evaluation of later formats in the series. For example:
const{ format }=require('logform');const{ combine, timestamp, label }=format;constwillNeverThrow=format.combine(format(info=>{returnfalse})(),// Ignores everythingformat(info=>{thrownewError('Never reached')})());console.dir(willNeverThrow.transform({level: 'info',message: 'wow such testing'}))Tests are written with mocha, assume, and nyc. They can be run with npm:
npm test