logster

0.0.5 • Public • Published

logster

NPM version

logster provides a simple, but extensible node logging facility that can write to various destinations. logster supports syslog severity levels, categories, and custom data and tags. It is easy to add new loggers and formatters.

There are quite a few log packages for node. logster strives to provide the same simplicity as the tiniest of these packages with "batteries included," while also providing a design that makes it easy to add new loggers.

logster provides the following loggers:

  • consolelogger
  • streamlogger
  • mongologger

logster can easily log to multiple destinations simultaneously, as this snippet demonstrates:

var log = new Log(severity.DEBUG, consoleLogger, mongoLogger, ...);

Installation

NPM

$ npm install logster

Creating your own logger

Loggers are objects that have a name property a log function, and optionally a drain function.

Although logster already comes with a console logger, here is an example of how you could create your own:

consolelogger.js

var format = require('logster').textFormatter.format;

module.exports = {
  name: 'consolelogger',
  log: function(logEntry) {
    console.log(format(logEntry));
  }
};

As the example indicates, logster comes with a default formatter (textformatter) that standardizes the look of log entries for text-based output. Both consolelogger and streamlogger have a formatter property set to this. You can set this formatter property to your own object that has a format function.

   var customTextFormatter = {
     format: function (logEntry) {
       // optionally handle extra args
       // return formatted string
     }
   };

Log entry properties

  • timestamp
  • message
  • level
  • levelCode
  • category
  • data
  • tags

Async loggers

The log interface does not require callbacks; however, log writes still need to be properly serialized. loggers that write asynchronously, such as mongologger use the async package to queue log entries. Async loggers should provide a drain callback that can be used to check if the queue has been drained. This is important to ensure the process does not exit with pending writes.

To implement your own async logger, take a look at the source for mongologger.js.

Log Severity levels

logster uses the same values as syslog. When creating a new log, set the severity level using values defined in severity.js.

Note: the first parameter to the Log constructor can be the number value or the level name (case-insensitive).

The following are all equivalent:

var severity = require('logster').severity;

log = new Log(severity.DEBUG, consoleLogger);

log = new Log('DEBUG', consoleLogger);

log = new Log('debug', consoleLogger);

log = new Log(7, consoleLogger);

console.log(severity.str(7)); // => 'DEBUG'

Severity Levels

level value purpose
NONE -1 don't log
EMERGENCY 0 system is unusable
ALERT 1 action must be taken immediately
CRITICAL 2 critical conditions
ERROR 3 error conditions
WARNING 4 warning conditions
NOTICE 5 normal but significant condition
INFO 6 informational messages
DEBUG 7 debug-level messages

Examples

Creating a console log

var Log = require('logster').Log
  , severity = require('logster').severity
  , consoleLogger = require('logster').consoleLogger
  , log
  ;

log = new Log(severity.DEBUG, consoleLogger);

Creating a stream log

var Log = require('logster').Log
  , severity = require('logster').severity
  , streamLogger = require('logster').streamLogger
  , log
  ;

streamLogger.stream = fs.createWriteStream(__dirname + '/stream.log');

log = new Log(severity.DEBUG, streamLogger);

Creating a mongo log

var Log = require('logster').Log
  , severity = require('logster').severity
  , mongoLogger = require('logster').mongoLogger
  , mongodb = require('mongodb')
  , mongoUri = '...'
  ;

mongodb.MongoClient.connect(mongoUri, function(err, client) {

  mongoLogger.db = client;

  var log = new Log('debug', mongoLogger);
  
  log.info('hello');

  // check that async loggers have finished draining
  // the log queue before exiting the process...
  
  log.drain(function() {
    console.log('finished writing all log entries to mongo');
    process.exit(0);
  });

});

Create a log with multiple loggers

var log = new Log(severity.DEBUG, consoleLogger, mongoLogger, ...);

Note: this version doesn't support different logger severity levels.

Log a simple message

log.info('hello');

Output:

[Mon Jan 13 2014 06:42:54 GMT-0800 (PST)] INFO hello

Log a message with placeholders like console.log and util.format

Extra parameters are either used as custom tags and data (see section below) or for message formatting just like with console.log and util.format, depending on the presence of the following placeholders in the log message:

  • %s string
  • %d number
  • %j json
log.info('Hello %s', 'World');

Output:

[Mon Jan 13 2014 06:42:54 GMT-0800 (PST)] INFO Hello World

However, unlike console.log and util.format, any extra parameters that do not have corresponding placeholders are not appended to the formatted string. Instead, they are considered to be custom tags and data, as described in another section below.

log.info('Hello', 'World');

Output:

[Mon Jan 13 2014 06:42:54 GMT-0800 (PST)] INFO Hello { tags: [ 'World' ] }

For complex log entries with a large number of parameters, it may be less confusing to format the message separately than trying to keep track of placeholders:

var message = util.format('Hello %s, %s is the %s of %s', 'Bob', 'today', 'first', 'the rest of your life!');
log.info(message, 'silly', 'greetings', 'bob');

Output:

[Mon Jan 13 2014 06:42:54 GMT-0800 (PST)] INFO Hello Bob, today is the first day of the rest of your life!,
  { tags: [ 'silly', 'greetings', 'bob' ] }

Log a message for a specific category

log.info({ category: 'api' }, 'hello');

Define constants to make using categories easier:

var API = { category: 'api' }
  , DATA = { category: 'data' }
  ;

...

log.info(API, 'received GET request');
log.info(DATA, 'retrieved some data');

Output:

[Mon Jan 13 2014 06:42:54 GMT-0800 (PST)] INFO (api) hello

Log with custom data and tags

After filling in any placholders in the message (as described previously), any extra parameters are either added to a data property or to a tags property array, depending on whether they are objects or primitive values.

log.info('a log entry with lots of custom data attributes',
  'interesting',
  'cool',
  'stuff',
  { userid: 'tester' },
  { moredata: true, stuff: 'lots' });

Output:

[Mon Jan 13 2014 13:20:20 GMT-0800 (PST)] INFO a log entry with lots of custom data attributes {
  data:  { userid: 'tester', moredata: true, stuff: 'lots' },
  tags:  [ 'interesting', 'cool', 'stuff' ] }

Mongo document (using mongologger)

{
    "timestamp" : ISODate("2014-01-13T21:23:49.744Z"),
    "category" : "",
    "level" : "INFO",
    "levelCode" : 6,
    "message" : "a log entry with lots of custom data attributes",
    "data" : {
        "userid" : "tester",
        "moredata" : true,
        "stuff" : "lots"
    },
    "tags" : [
        "interesting",
        "cool",
        "stuff"
    ],
    "_id" : ObjectId("52d45965b565194aa9b39676")
}

License

MIT License
Copyright (c) 2014, Tony Pujals (http://tonypujals.io/contact/)

Readme

Keywords

none

Package Sidebar

Install

npm i logster

Weekly Downloads

1

Version

0.0.5

License

MIT

Last publish

Collaborators

  • subfuzion