Logger
Logger implementation for command line interfaces.
Install
npm install cli-logger
Test
npm test
Features
- Seamless integration with ttycolor
- JSON output compatible with bunyan
- Bitwise log level support
- 100% code coverage
Examples
Example programs are in the bin directory and there are many usage examples in the test suite.
Usage
Unless streams have been configured all log messages are written to process.stdout
.
Normal
Normal mode uses log levels that correspond to the bunyan log levels and behaviour (log messages are written if they are greater than or equal to the configured log level):
var logger = require('cli-logger');
var conf = {level: log.WARN};
log = logger(conf);
log.warn('mock %s message', 'warn');
log.info('mock %s message', 'info');
Bitwise
Using bitwise log levels allows fine-grained control of how log messages are routed, to enable bitwise mode pass true
as the second argument when creating the logger:
var logger = require('cli-logger');
var conf = {level: log.BW_INFO|log.BW_FATAL};
log = logger(conf, true);
log.info('mock %s message', 'info');
If you just want to disable one or two log levels it is more convenient to use the XOR
operator:
var logger = require('cli-logger');
var conf = {level: log.BW_ALL^log.BW_TRACE};
log = logger(conf, true);
log.info('mock %s message', 'info');
Note that in normal mode you may use string log levels, such as 'trace'
, but in bitwise mode you may only use integer log levels.
Messages
Logging messages is consistent with bunyan:
log.info('info message')
log.warn('%s message', 'warn')
log.debug({foo: 'bar'}, '%s message', 'debug')
log.error(err)
log.fatal(err, '%s error', 'fatal')
Log Levels
The log levels correspond to a method on the logger, the methods and corresponding module constants are shown below:
log.trace()
log.debug()
log.info()
log.warn()
log.error()
log.fatal()
In normal mode the additional constant NONE
(70) may be used to disable logging. In bitwise mode you may also use BW_NONE
(0) and BW_ALL
(63), BW_ALL
is particularly useful for XOR
operations.
The API for getting and setting log levels is consistent with bunyan:
log.info()
log.level()
log.level(INFO)
log.level('info')
log.level(BW_INFO)
log.levels()
log.levels(0)
log.levels('foo')
log.levels(0, INFO)
log.levels(0, 'info')
log.levels(0, BW_INFO)
log.levels('foo', WARN)
Configuration
console
: A boolean indicating that console methods should be used when writing log records, this enables the ttycolor integration, default is false
, see console.json
: Print log records as newline delimited JSON, default is false
, see json.level
: A default log level to use when a stream does not explicitly specify a log level, default is INFO
, see level.name
: The name of the logger, default is basename(process.argv[1])
, see name.prefix
: A function used to prepend a prefix to log messages, default is null
, see prefix.serializers
: Map of log record property names to serialization functions,
default is null
, see serializers.src
: A boolean that indicates that file name, line number and function name (when available) should be included in the log record, default is false
, see source.stack
: A boolean used in conjunction with src
to also include an array of the stack trace caller information, default is false
, see source.stream
: Shortcut for specifying a stream for single stream loggers, default is null
, see streams.streams
: An array or object that configures the streams that log records are written to, by default if this property is not present a single stream is configured for process.stdout
, see streams.writers
: Map of log level string names to console functions, default is
null
. Use this to customize the functions used when console
is true
,
see writers.
If you specify any unknown properties in the configuration then these are considered persistent fields and are added to every log record. This is a convenient way to add labels for sub-components to log records.
Console
Set the console
configuration property to redirect all log messages via console
methods, this enables integration with the ttycolor module.
The default mapping between log methods and console
methods is:
trace
debug
info
warn
error
fatal
Run the color example program to see the default output.
Writers
You may customize the mapping between log methods and console
methods by either specifying the writers
configuration property as a console
function (to set all log methods to the same console
method):
var conf = {console: true, writers: console.error};
Or by mapping inidividual log method names, for example if you would prefer trace
and debug
messages to be printed to stderr
:
var conf = {
console: true,
writers: {
trace: console.error,
debug: console.error
}
}
If required you could define your own function that has the same signature as a console
method (function(message, ...)
) to create different output styles using the ttycolor module methods.
This configuration option should only be used in conjunction with the console
option.
JSON
This module is designed for command line interfaces so JSON output is not enabled by default, you may enable JSON output for all streams by specifying the json
configuration option or enable for specific streams by specifying the json
property on a stream.
Alternatively, you can use createLogger
to set the json
configuration property if it is not defined:
var logger = require('cli-logger');
log = logger.createLogger();
Level
The level
configuration option sets the default log level when a level is not specified on a stream, it may also be used in conjunction with stream
to configure a single stream, see streams for an example.
Name
All loggers must have a name
specified, typically this will be the name of the program so it is determined automatically, however you can override with a different name
if required. Note that when specified this option must be a non-zero length string or an error will be thrown.
Prefix
Sometimes it may be useful to prefix all log messages, possibly with the program name, log level or date. Specify a function as the prefix
configuration option to set a prefix for all log messages. The function has the signature:
function prefix(record)
It should return a string to prepend to all log messages.
The prefix
function is invoked in the scope of the Logger
instance so you may access this.name
, this.names()
etc. See the prefix example program.
Source
Set the src
configuration property when you want information about the file name, line number and function name that invoked a log method, you may also set the stack
property to include a full stack trace.
Caution: do not use this in production, retrieving call site information is slow.
var logger = require('cli-logger');
var conf = {src: true, stack: true};
var log = logger(conf);
log.on('write', function(record, stream, msg, parameters) {
console.log(JSON.stringify(record, undefined, 2));
})
function info() {
log.info('mock %s message', 'info');
}
info();
{
"time": "2014-02-17T16:28:02.573Z",
"pid": 2747,
"hostname": "pearl.local",
"name": "source",
"msg": "mock info message",
"level": 30,
"src": {
"file": "/Users/cyberfunk/git/cli/logger/bin/source",
"line": 16,
"func": "info",
"stack": [
"info (/Users/cyberfunk/git/cli/logger/bin/source:16:7)",
"Object.<anonymous> (/Users/cyberfunk/git/cli/logger/bin/source:18:1)",
"Module._compile (module.js:456:26)",
"Object.Module._extensions..js (module.js:474:10)",
"Module.load (module.js:356:32)",
"Function.Module._load (module.js:312:12)",
"Function.Module.runMain (module.js:497:10)"
]
},
"v": 0
}
See the source example program.
Serializers
Serializers behave the same as bunyan and the same standard serializers are provided via the serializers
module property (also aliased via stdSerializers
for bunyan compatibility).
req
: Serialize an HTTP request.res
: Serialize an HTTP response.err
: Serialize an Error instance.
var logger = require('cli-logger');
var conf = {serializers: {err: logger.serializers.err}};
var log = logger(conf);
log.on('write', function(record, stream, msg, parameters) {
console.log(JSON.stringify(record, undefined, 2));
})
log.info({err: new Error('Mock simple error')});
{
"time": "2014-02-17T15:54:52.830Z",
"err": {
"message": "Mock simple error",
"name": "Error",
"stack": "..."
},
"pid": 65543,
"hostname": "pearl.local",
"name": "write",
"msg": "",
"level": 30,
"v": 0
}
See the serialize example program.
Streams
Configuring output streams is typically done using an array, but as a convenience an object may be specified to configure a single output stream:
var logger = require('cli-logger');
var conf = {streams: {stream: process.stderr, level: log.WARN}}
var log = logger(conf);
Or even more succinctly for single stream loggers you can specify stream
at the configuration level:
var logger = require('cli-logger');
var conf = {stream: process.stderr, level: log.FATAL}
var log = logger(conf);
File
You may configure a file stream by using the path
stream property. For example, to log the INFO
level and above to stdout
and ERROR
and above to a file:
var logger = require('cli-logger');
var conf = {streams: [
{
stream: process.stdout,
level: log.INFO
},
{
path: 'log/errors.log',
level: log.ERROR
}
]};
var log = logger(conf);
When creating file streams the default flags used is a
you may specify the flags
property to change this behaviour:
var logger = require('cli-logger');
var conf = {streams: [
{
path: 'log/errors.log',
flags: 'ax',
level: log.ERROR
}
]};
var log = logger(conf);
The encoding
and mode
options supported by fs.createWriteStream
are also respected if present.
License
Everything is MIT. Read the license if you feel inclined.