Logger that supports custom stream, events, handy helper methods and built in debugger creation.
$ npm install timbr
OR
$ npm install timbr --production
Require or import
import * as timbr from 'timbr';
const log = timbr.init({ /* your options here */ })
OR
import * as timbr from 'timbr';
// IMPORTANT: When using Typescript do NOT
// define your custom log levels as ITimbrLevel.
// In order for the "keyof typeof" trick to work
// with record it can't be typed with the interface
// this will be applied internally in Timbr's instance.
// Just define as plain object and you'll be good.
const LOG_LEVELS = {
emerg: ['bgRed', 'yellow'],
alert: ['underline', 'bold', 'red'],
crit: {
label: 'critical'
styles: ['underline', 'red']
},
error: 'red',
warn: {
label: 'warning',
styles: 'yellow'
},
notice: 'green',
info: 'blue'
}
const LogLevelKeys = keyof typeof LOG_LEVELS;
const log = timbr.create<LogLevelKeys>({ /* your options */}, LOG_LEVELS);
NOTE: When NOT using Typescript you can create your logger instance by simply passing your options and log levels/methods (see below).
const log = timbr.create({ /* options */}, LOG_LEVELS);
log.warn('some warning.');
When calling the .init()
method Timbr will initialize with the following default log levels:
error, warn, info, trace, verbose, debug
NOTE: the "debug" method by default is a debugger. A debugger behaves much like a typical log level but emits its events to debug listeners instead of log.
This behavior allows for simple debugging without additional libs or instantiating a debugger. Good for simple projects. If you need multiple debuggers, simply disable and create as many debuggers as needed. See below for creating custom debuggers.
You can change this behavior by setting "debugLevel" in options to another level or false to disable. This allows for custom methods WITHOUT a built in debug method.
const options = {
debugLevel: false
};
When initializing using the .create()
method to create a custom instance you must pass an object containing your desired log levels and their respective configurations.
const LOG_LEVELS = {
info: 'blue'
}
// OR
const LOG_LEVELS = {
info: ['bgBlue', 'white']
}
const LOG_LEVELS = {
info: {
label: 'information', // when null the key is used or false to disable label for this level.
styles: ['blue'] // string or array of string matching colurs styles.,
symbol: 'info' // a named known symbol or a string,
symbolPos: 'after' // or 'before',
symbolStyles: null // same as above 'styles',
indent: 10 // a number of spaces to indent or a string.
}
}
A few logging examples.
log('just some message.');
log.warn('expected value to be of type %s', 'number');
log.trace('starting server...', { host: 'localhost', port: 1337 });
log.error(new Error('Whoops you can\'t do that!'));
log.info('just some important message.').exit();
Writes "----" before and after log message using the .write() method.
log
.writeLn('----')
.info('just some important message.')
.writeLn('----');
Continually outputs to stream without line return.
Results in 'one, two'.
log.write('one, ').write('two');
Timbr supports a few useful methods by default.
Method | Description |
write | writes to output stream inline without line returns. |
writeLn | same as above but with line return. |
symbol | generates a symbol or gets known symbol. |
exit | allows for exiting process ex: log.info().exit(code). |
Timbr has built in support for creating debuggers.
const debug = log.debugger();
// OR
const debug = log.debugger({ /* your options */ });
debug('my debug message.');
You can use one of your log levels for the default debugger. When initializing Timbr options set:
const options {
debugLevel: 'debug'
}
When using .init() or when passing log levels and creating an instance using .create() a log level of 'debug' will be wired up to the default debugger.
log.debug('your debug message.');
// same as instantiating
// const debug = log.debugger();
// debug('your debug message.')
const debugSvr = log.debugger('server', { /* options here */ });
debugSvr('some debug message for %s', 'server');
When Node debug is detected the "default" debugger is automatically enabled. To enable specific debuggers you can pass the debuggers in the "DEBUG" environment variable.
$ DEBUG="debugger1,debugger2" node index.js
NOTE: the above will not work in Windows use the "set" command.
Additionally you can manually enable a debugger in your code.
const debugSvr = log.debugger('server');
debugSvr.enable();
Some times it's useful to check if a debugger is active before firing off some logic.
if (debugSvr.enabled()) {
// do something the server debugger is active.
}
You can pass an environment variable to show ONLY debug messages and skip other messages. This can be handy during development time.
You can also set this in your initialization options using property "debugOnly".
$ DEBUG_ONLY="true" node index.js
To use symbols you can get a known symbol to Timbr and manually add it to your log message or you can specify that known type in your log level config.
By default the following symbols are included: error, warn, info, trace, debug, ok.
Get Warn Symbol
const warnSymbol = log.symbol('warn');
log.warn('some message %s', warnSymbol);
Symbol in Options
Known Symbols
const SYMBOLS = {
error: '✖',
warn: '⚠',
info: 'ℹ',
trace: '◎',
debug: '✱',
ok: '✔'
};
const LOG_LEVELS = {
warn: {
symbol: 'warn', // a known symbol name (see above) to Timbr or custom string.
symbolPos: 'after', // (before or after, default is after)
symbolStyles: undefined // (if undefined above "styles" used)
}
};
Timbr extends Event Emitter allowing you to listen to log or debug events.
Both event listeners and callbacks provide access to the TimbrEventData object which is created when log arguments are parsed.
const event = {
type: 'the primary type like error, warn, info etc',
level: 'this is the log level or debug configuration options',
index: 'the integer or index of the log level being logged',
activeIndex: 'the integer of the active level, what you passed in your init options as the active level',
message: msg, // this gets updated after compile.
timestamp: 'the current timestamp',
meta: 'any metadata or object that was passed in the log message',
args: 'array containing the original arguments.',
error: 'when an error is logged the error instance will be stored here',
stack: 'the stack trace for the message being logged when no error present a stack is generated'
};
log.on('log', (message, event) => {
// do something
})
// Or by type
log.on('log:info', (message, event) => {
// do something
})
log.on('debug', (message, event) => {
// do something
})
// Or by type
log.on('debug:default', (message, event) => {
// do something
})
**Option** | **Description** | **Type** | **Default** |
---|---|---|---|
stream | stream to output to. | WriteableStream | process.stderr |
level | active log level. | string | number | info |
colorize | enables/disables colors. | boolean | true |
labelLevels | when true log messages prefixed with level label. | boolean | true |
padLevels | pads left of level. | boolean | true |
prettyMeta | when true prettifies metadata on new line. | boolean | false |
timestamp | enables/disables or defines timestamp type. | false | time | datetime | iso | Function | time |
timestampStyles | colors/styles for stylizing timestamp | string | string[] | null |
timestampLocale | the timestamp locale | string | en-US |
timestampTimezone | IANA timezone string | string | UTC |
errorLevel | the error level name. | string | error |
errorExit | when true exits on errors. | boolean | false |
errorConvert | if first arg Error instance convet to error log level. | boolean | false |
errorCapture | capture uncaught exceptions. | boolean | false |
errorConstruct | when true on error level and is string convert to Error instance. | boolean | false |
stackTrace | when true full stack trace shown on errors. | boolean | true |
stackDepth | depth of stack trace to display. | number | 0 |
miniStack | when true file, line & column shown on all messages. | boolean | true |
debugLevel | the log level to use for default debugger. | string | false | debug |
debugOnly | when true show only debug messages | boolean | false |
debugElapsed | when true shows elapsed time in ms for debug messages. | boolean | true |
beforeWrite | callback for customizing log output before writing to stream. | Function | null |
Gets the timestamp format.
const currentLogLevel = log.getOption('level');
Sets the timestamp format false disabling it from log messages.
log.setOption('timestamp', false);
See CHANGE.md
See LICENSE.md