logform
A mutable object-based log format designed for chaining & objectMode streams.
const { format } = require('logform');
const alignedWithColorsAndTime = format.combine(
format.colorize(),
format.timestamp(),
format.align(),
format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)
);
info
Objects
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:
const info = {
level: 'info',
message: 'Hey! Log something?'
}
Properties besides level and message are considered as "meta
". i.e.:
const { level, message, ...meta } = info;
Several of the formats in logform
itself add additional properties:
Property | Format added by | Description |
---|
splat | splat() | String interpolation splat for %d %s -style messages. |
timestamp | timestamp() | timestamp the message was received. |
label | label() | Custom label associated with each message. |
ms | ms() | Number of milliseconds since the previous log message. |
As a consumer you may add whatever properties you wish – internal state is
maintained by Symbol
properties:
Symbol.for('level')
(READ-ONLY): equal to level
property.
Is treated as immutable by all code.Symbol.for('message'):
complete string message set by "finalizing formats":
json
logstash
printf
prettyPrint
simple
Symbol.for('splat')
: additional string interpolation arguments. Used
exclusively by splat()
format.
These Symbols are stored in another package: triple-beam
so that all
consumers of logform
can have the same Symbol reference. i.e.:
const { LEVEL, MESSAGE, SPLAT } = require('triple-beam');
console.log(LEVEL === Symbol.for('level'));
console.log(MESSAGE === Symbol.for('message'));
console.log(SPLAT === Symbol.for('splat'));
Understanding formats
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
info
Object representing the modified info
argument. Object references need not be preserved if immutability is preferred. All current built-in formats consider info
mutable, but [immutablejs] is being considered for future releases. - A falsey value indicating that the
info
argument should be ignored by the caller. (See: Filtering info
Objects) 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');
const volume = format((info, opts) => {
if (opts.yell) {
info.message = info.message.toUpperCase();
} else if (opts.whisper) {
info.message = info.message.toLowerCase();
}
return info;
});
const scream = volume({ yell: true });
console.dir(scream.transform({
level: 'info',
message: `sorry for making you YELL in your head!`
}, scream.options));
const whisper = volume({ whisper: true });
console.dir(whisper.transform({
level: 'info',
message: `WHY ARE THEY MAKING US YELL SO MUCH!`
}), whisper.options);
Combining formats
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;
const labelTimestamp = combine(
label({ label: 'right meow!' }),
timestamp()
);
const info = labelTimestamp.transform({
level: 'info',
message: 'What time is the testing at?'
});
console.dir(info);
Filtering info
Objects
If you wish to filter out a given info
Object completely then simply return a falsey value.
const ignorePrivate = format((info, opts) => {
if (info.private) { return false; }
return info;
});
console.dir(ignorePrivate.transform({
level: 'error',
message: 'Public error to share'
}));
console.dir(ignorePrivate.transform({
level: 'error',
private: true,
message: 'This is super secret - hide it.'
}));
Use 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;
const willNeverThrow = format.combine(
format(info => { return false })(),
format(info => { throw new Error('Never reached') })()
);
console.dir(willNeverThrow.transform({
level: 'info',
message: 'wow such testing'
}))
Formats
Align
The align
format adds a \t
delimiter before the message to align it in the same place.
const { format } = require('logform');
const alignFormat = format.align();
const info = alignFormat.transform({
level: 'info',
message: 'my message'
});
console.log(info);
This was previously exposed as { align: true }
in winston < 3.0.0
.
CLI
The cli
format is a combination of the colorize
and the padLevels
formats. It turns a log info
object into the same format previously available in winston.cli()
in winston < 3.0.0
.
const { format } = require('logform');
const LEVEL = Symbol.for('level');
const cliFormat = format.cli({ colors: { info: 'blue' }});
const info = cliFormat.transform({
[LEVEL]: 'info',
level: 'info',
message: 'my message'
}, { all: true });
console.log(info);
Colorize
The colorize
format adds different colors depending on the log level to the message and/or level.
It accepts the following options:
- level: If set to
true
the color will be applied to the level
. - all: If set to
true
the color will be applied to the message
and level
. - message: If set to
true
the color will be applied to the message
. - colors: An object containing the colors for the log levels. For example:
{ info: 'blue', error: 'red' }
const { format } = require('logform');
const LEVEL = Symbol.for('level');
const colorizeFormat = format.colorize({ colors: { info: 'blue' }});
const info = colorizeFormat.transform({
[LEVEL]: 'info',
level: 'info',
message: 'my message'
}, { all: true });
console.log(info);
This was previously exposed as { colorize: true }
to transports in winston < 3.0.0
.
Combine
The combine
Format allows to combine multiple formats:
const { format } = require('logform');
const { combine, timestamp, json } = format;
const jsonWithTimestamp = combine(
timestamp(),
json()
);
const info = jsonWithTimestamp.transform({
level: 'info',
message: 'my message'
});
console.log(info);
Errors
The errors
format allows you to pass in an instance of a JavaScript Error
directly to the logger. It allows you to specify whether not to include the
stack-trace.
const { format } = require('logform');
const { errors } = format;
const errorsFormat = errors({ stack: true })
const info = errorsFormat.transform(new Error('Oh no!'));
console.log(info);
It will also handle { message }
properties as Error
instances:
const { format } = require('logform');
const { errors } = format;
const errorsFormat = errors({ stack: true })
const info = errorsFormat.transform({
message: new Error('Oh no!')
});
console.log(info);
JSON
The json
format uses safe-stable-stringify
to finalize the message.
It accepts the following options:
- replacer: A function that influences how the
info
is stringified. - space: The number of white space used to format the json.
const { format } = require('logform');
const jsonFormat = format.json();
const info = jsonFormat.transform({
level: 'info',
message: 'my message',
});
console.log(info);
This was previously exposed as { json: true }
to transports in winston < 3.0.0
.
Label
The label
format adds the specified label
before the message or adds it to the info
object.
It accepts the following options:
- label: A label to be added before the message.
- message: If set to
true
the label
will be added to info.message
. If set to false
the label
will be added as info.label
.
const { format } = require('logform');
const labelFormat = format.label();
const info = labelFormat.transform({
level: 'info',
message: 'my message'
}, { label: 'my label', message: true });
console.log(info);
This was previously exposed as { label: 'my label' }
to transports in winston < 3.0.0
.
Logstash
The logstash
Format turns a log info
object into pure JSON with the appropriate logstash options.
const { format } = require('logform');
const { logstash, combine, timestamp } = format;
const logstashFormat = combine(
timestamp(),
logstash()
);
const info = logstashFormat.transform({
level: 'info',
message: 'my message'
});
console.log(info);
This was previously exposed as { logstash: true }
to transports in winston < 3.0.0
.
Metadata
The metadata
format adds a metadata object to collect extraneous data, similar to the metadata object in winston 2.x.
It accepts the following options:
- key: The name of the key used for the metadata object. Defaults to
metadata
. - fillExcept: An array of keys that should not be added to the metadata object.
- fillWith: An array of keys that will be added to the metadata object.
const { format } = require('logform');
const metadataFormat = format.metadata();
const info = metadataFormat.transform({
level: 'info',
message: 'my message',
meta: 42
});
console.log(info);
PadLevels
The padLevels
format pads levels to be the same length.
const { format } = require('logform');
const LEVEL = Symbol.for('level');
const padLevelsFormat = format.padLevels();
const info = padLevelsFormat.transform({
[LEVEL]: 'info',
message: 'my message'
});
console.log(info);
This was previously exposed as { padLevels: true }
to transports in winston < 3.0.0
.
PrettyPrint
The prettyPrint
format finalizes the message using util.inspect
.
It accepts the following options:
- depth: A
number
that specifies the maximum depth of the info
object being stringified by util.inspect
. Defaults to 2
. - colorize: Colorizes the message if set to
true
. Defaults to false
.
The prettyPrint
format should not be used in production because it may impact performance negatively and block the event loop.
NOTE: the LEVEL
, MESSAGE
, and SPLAT
symbols are stripped from the
output message by design.
This was previously exposed as { prettyPrint: true }
to transports in winston < 3.0.0
.
const { format } = require('logform');
const prettyPrintFormat = format.prettyPrint();
const info = prettyPrintFormat.transform({
[LEVEL]: 'info',
level: 'info',
message: 'my message'
});
console.log(info);
Printf
The printf
format allows to create a custom logging format:
const { format } = require('logform');
const myFormat = format.printf((info) => {
return `${info.level} ${info.message}`;
})
const info = myFormat.transform({
level: 'info',
message: 'my message'
});
console.log(info);
Simple
The simple
format finalizes the info
object using the format: level: message stringifiedRest
.
const { format } = require('logform');
const MESSAGE = Symbol.for('message');
const simpleFormat = format.simple();
const info = simpleFormat.transform({
level: 'info',
message: 'my message',
number: 123
});
console.log(info[MESSAGE]);
Splat
The splat
format transforms the message by using util.format
to complete any info.message
provided it has string interpolation tokens.
const { format } = require('logform');
const splatFormat = format.splat();
const info = splatFormat.transform({
level: 'info',
message: 'my message %s',
splat: ['test']
});
console.log(info);
Any additional splat parameters beyond those needed for the %
tokens
(aka "metas") are assumed to be objects. Their enumerable properties are
merged into the info
.
const { format } = require('logform');
const splatFormat = format.splat();
const info = splatFormat.transform({
level: 'info',
message: 'my message %s',
splat: ['test', { thisIsMeta: true }]
});
console.log(info);
This was previously exposed implicitly in winston < 3.0.0
.
Timestamp
The timestamp
format adds a timestamp to the info.
It accepts the following options:
- format: Either the format as a string accepted by the fecha module or a function that returns a formatted date. If no format is provided
new Date().toISOString()
will be used. - alias: The name of an alias for the timestamp property, that will be added to the
info
object.
const { format } = require('logform');
const timestampFormat = format.timestamp();
const info = timestampFormat.transform({
level: 'info',
message: 'my message'
});
console.log(info);
It was previously available in winston < 3.0.0
as { timestamp: true }
and { timestamp: function:String }
.
Uncolorize
The uncolorize
format strips colors from info
objects.
It accepts the following options:
- level: Disables the uncolorize format for
info.level
if set to false
. - message: Disables the uncolorize format for
info.message
if set to false
. - raw: Disables the uncolorize format for
info[MESSAGE]
if set to false
.
This was previously exposed as { stripColors: true }
to transports in winston < 3.0.0
.
Tests
Tests are written with mocha
, assume
, and nyc
. They can be run with npm
:
npm test
LICENSE: MIT