Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

winston

Package Overview
Dependencies
Maintainers
4
Versions
89
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

winston - npm Package Compare versions

Comparing version 0.5.11 to 0.6.1

examples/exception.js

38

lib/winston.js

@@ -22,3 +22,3 @@ /*

//
// Expose utility methods
// Expose utility methods
//

@@ -31,3 +31,3 @@ var common = require('./winston/common');

winston.config = require('./winston/config');
winston.addColors = winston.config.addColors;
winston.addColors = winston.config.addColors;

@@ -42,3 +42,3 @@ //

//
// We create and expose a default `Container` to `winston.loggers` so that the
// We create and expose a default `Container` to `winston.loggers` so that the
// programmer may manage multiple `winston.Logger` instances without any additional overhead.

@@ -62,6 +62,6 @@ //

// winston.log('info', 'some message');
// winston.error('some error');
// winston.error('some error');
//
var defaultLogger = new winston.Logger({
transports: [new winston.transports.Console()]
var defaultLogger = new winston.Logger({
transports: [new winston.transports.Console()]
});

@@ -73,10 +73,12 @@

var methods = [
'log',
'add',
'remove',
'profile',
'log',
'query',
'stream',
'add',
'remove',
'profile',
'startTimer',
'extend',
'cli',
'handleExceptions',
'extend',
'cli',
'handleExceptions',
'unhandleExceptions'

@@ -102,3 +104,3 @@ ];

winston.config.addColors(winston.config.cli.colors);
if (defaultLogger.transports.console) {

@@ -108,3 +110,3 @@ defaultLogger.transports.console.colorize = true;

}
return winston;

@@ -124,3 +126,3 @@ };

//
// Define getters / setters for appropriate properties of the
// Define getters / setters for appropriate properties of the
// default logger which need to be exposed by winston.

@@ -140,4 +142,4 @@ //

//
// @default {Object}
// The default transports and exceptionHandlers for
// @default {Object}
// The default transports and exceptionHandlers for
// the default winston logger.

@@ -144,0 +146,0 @@ //

@@ -11,2 +11,3 @@ /*

crypto = require('crypto'),
cycle = require('cycle'),
config = require('./config');

@@ -19,3 +20,3 @@

// #### @current {Object} Current levels to set on target.
// Create functions on the target objects for each level
// Create functions on the target objects for each level
// in current.levels. If past is defined, remove functions

@@ -35,3 +36,3 @@ // for each of those levels.

}
//

@@ -50,3 +51,3 @@ // Define prototype methods for each log level

});
return target;

@@ -101,5 +102,5 @@ };

// #### @options {Object} All information about the log serialization.
// Generic logging function for returning timestamped strings
// Generic logging function for returning timestamped strings
// with the following options:
//
//
// {

@@ -114,5 +115,7 @@ // level: 'level to add to serialized message',

exports.log = function (options) {
var timestampFn = typeof options.timestamp === 'function' ? options.timestamp : exports.timestamp,
var timestampFn = typeof options.timestamp === 'function'
? options.timestamp
: exports.timestamp,
timestamp = options.timestamp ? timestampFn() : null,
meta = options.meta ? exports.clone(options.meta) : null,
meta = options.meta ? exports.clone(cycle.decycle(options.meta)) : null,
output;

@@ -124,3 +127,6 @@

if (options.raw) {
output = meta || {};
if (typeof meta !== 'object' && meta != null) {
meta = { meta: meta };
}
output = exports.clone(meta) || {};
output.level = options.level;

@@ -135,6 +141,9 @@ output.message = options.message.stripColors;

if (options.json) {
output = meta || {};
if (typeof meta !== 'object' && meta != null) {
meta = { meta: meta };
}
output = exports.clone(meta) || {};
output.level = options.level;
output.message = options.message;
if (timestamp) {

@@ -144,5 +153,5 @@ output.timestamp = timestamp;

return typeof options.stringify === 'function'
return typeof options.stringify === 'function'
? options.stringify(output)
: JSON.stringify(output, function(key, value) {
: JSON.stringify(output, function (key, value) {
if (value instanceof Buffer) {

@@ -166,3 +175,3 @@ return value.toString('base64');

}
}
}

@@ -187,11 +196,2 @@ return output;

//
// ## Borrowed from node.js core
// I wanted a universal lowercase header message, as opposed to the `DEBUG`
// (i.e. all uppercase header) used only in `util.debug()`
//
var months = ['Jan', 'Feb', 'Mar', 'Apr',
'May', 'Jun', 'Jul', 'Aug',
'Sep', 'Oct', 'Nov', 'Dec'];
//
// ### function pad (n)

@@ -209,10 +209,3 @@ // Returns a padded string if `n < 10`.

exports.timestamp = function () {
var d = new Date();
var time = [
exports.pad(d.getHours()),
exports.pad(d.getMinutes()),
exports.pad(d.getSeconds())
].join(':');
return [d.getDate(), months[d.getMonth()], time].join(' ');
return new Date().toISOString();
};

@@ -224,3 +217,3 @@

// #### @key {string} **Optional** Optional key represented by obj in a larger object
// Performs simple comma-separated, `key=value` serialization for Loggly when
// Performs simple comma-separated, `key=value` serialization for Loggly when
// logging to non-JSON inputs.

@@ -238,3 +231,3 @@ //

}
if (typeof obj !== 'object') {

@@ -251,7 +244,7 @@ return key ? key + '=' + obj : obj;

length = keys.length;
for (var i = 0; i < length; i++) {
if (Array.isArray(obj[keys[i]])) {
msg += keys[i] + '=[';
for (var j = 0, l = obj[keys[i]].length; j < l; j++) {

@@ -263,3 +256,3 @@ msg += exports.serialize(obj[keys[i]][j]);

}
msg += ']';

@@ -272,4 +265,4 @@ }

msg += exports.serialize(obj[keys[i]], keys[i]);
}
}
if (i < length - 1) {

@@ -279,4 +272,4 @@ msg += ', ';

}
return msg;
};
/*
* config.js: Default settings for all levels that winston knows about
* config.js: Default settings for all levels that winston knows about
*

@@ -11,3 +11,3 @@ * (C) 2010 Charlie Robbins

var config = exports,
var config = exports,
allColors = exports.allColors = {};

@@ -14,0 +14,0 @@

/*
* cli-config.js: Config that conform to commonly used CLI logging levels.
* cli-config.js: Config that conform to commonly used CLI logging levels.
*

@@ -8,3 +8,3 @@ * (C) 2010 Charlie Robbins

*/
var cliConfig = exports;

@@ -11,0 +11,0 @@

/*
* npm-config.js: Config that conform to npm logging levels.
* npm-config.js: Config that conform to npm logging levels.
*

@@ -8,11 +8,11 @@ * (C) 2010 Charlie Robbins

*/
var npmConfig = exports;
npmConfig.levels = {
silly: 0,
verbose: 1,
info: 2,
silly: 0,
verbose: 1,
info: 2,
warn: 3,
debug: 4,
debug: 4,
error: 5

@@ -19,0 +19,0 @@ };

/*
* syslog-config.js: Config that conform to syslog logging levels.
* syslog-config.js: Config that conform to syslog logging levels.
*

@@ -8,11 +8,11 @@ * (C) 2010 Charlie Robbins

*/
var syslogConfig = exports;
syslogConfig.levels = {
debug: 0,
info: 1,
notice: 2,
debug: 0,
info: 1,
notice: 2,
warning: 3,
error: 4,
error: 4,
crit: 5,

@@ -28,3 +28,3 @@ alert: 6,

warning: 'red',
error: 'red',
error: 'red',
crit: 'red',

@@ -31,0 +31,0 @@ alert: 'yellow',

@@ -36,3 +36,3 @@ /*

// Retreives a `winston.Logger` instance for the specified `id`. If
// an instance does not exist, one is created.
// an instance does not exist, one is created.
//

@@ -52,3 +52,3 @@ Container.prototype.get = Container.prototype.add = function (id, options) {

}
var name = common.capitalize(key);

@@ -59,3 +59,3 @@

}
var namedOptions = options[key];

@@ -85,3 +85,3 @@ namedOptions.id = id;

// #### @id {string} **Optional** Id of the Logger instance to close
// Closes a `Logger` instance with the specified `id` if it exists.
// Closes a `Logger` instance with the specified `id` if it exists.
// If no `id` is supplied then all Loggers are closed.

@@ -91,3 +91,3 @@ //

var self = this;
function _close (id) {

@@ -101,3 +101,3 @@ if (!self.loggers[id]) {

}
return id ? _close(id) : Object.keys(this.loggers).forEach(function (id) {

@@ -104,0 +104,0 @@ _close(id);

@@ -8,6 +8,6 @@ /*

*/
var os = require('os'),
stackTrace = require('stack-trace');
var exception = exports;

@@ -17,2 +17,3 @@

return {
date: new Date().toString(),
process: exception.getProcessInfo(),

@@ -28,4 +29,4 @@ os: exception.getOsInfo(),

pid: process.pid,
uid: process.getuid(),
gid: process.getgid(),
uid: process.getuid ? process.getuid() : null,
gid: process.getgid ? process.getgid() : null,
cwd: process.cwd(),

@@ -58,2 +59,2 @@ execPath: process.execPath,

});
};
};

@@ -8,3 +8,3 @@ /*

*/
var events = require('events'),

@@ -15,3 +15,4 @@ util = require('util'),

common = require('./common'),
exception = require('./exception');
exception = require('./exception'),
Stream = require('stream').Stream;

@@ -32,6 +33,6 @@ //

options = options || {};
var self = this,
handleExceptions = false;
//

@@ -45,3 +46,3 @@ // Set Levels and default logging level

}
//

@@ -53,6 +54,6 @@ // Hoist other options onto this instance.

this.stripColors = options.stripColors || false;
this.exitOnError = typeof options.exitOnError !== 'undefined'
? options.exitOnError
this.exitOnError = typeof options.exitOnError !== 'undefined'
? options.exitOnError
: true;
//

@@ -71,3 +72,3 @@ // Setup other intelligent default settings.

self.add(transport, null, true);
if (transport.handleExceptions) {

@@ -78,9 +79,9 @@ handleExceptions = true;

}
if (options.rewriters) {
options.rewriters.forEach(function(rewriter) {
options.rewriters.forEach(function (rewriter) {
self.addRewriter(rewriter);
});
}
if (options.exceptionHandlers) {

@@ -93,3 +94,3 @@ handleExceptions = true;

}
if (options.handleExceptions || handleExceptions) {

@@ -118,3 +119,3 @@ this.handleExceptions();

});
return this;

@@ -132,6 +133,6 @@ };

Logger.prototype.log = function (level, msg) {
var self = this,
var self = this,
callback,
meta;
if (arguments.length === 3) {

@@ -164,3 +165,3 @@ if (typeof arguments[2] === 'function') {

}
if (this.transports.length === 0) {

@@ -172,10 +173,10 @@ return onError(new Error('Cannot log with no transports.'));

}
this.rewriters.forEach(function(rewriter) {
this.rewriters.forEach(function (rewriter) {
meta = rewriter(level, msg, meta);
});
//
// For consideration of terminal 'color" programs like colors.js,
// which can add ANSI escape color codes to strings, we destyle the
// which can add ANSI escape color codes to strings, we destyle the
// ANSI color escape codes when `this.stripColors` is set.

@@ -186,23 +187,40 @@ //

if (this.stripColors) {
var code = /\u001b\[\d+m/g;
var code = /\u001b\[\d+(?:;\d+)*m/g;
msg = ('' + msg).replace(code, '');
}
for (var i = 0, l = this._names.length; i < l; i++) {
var transport = this.transports[this._names[i]];
//
// Log for each transport and emit 'logging' event
//
function emit(name, next) {
var transport = self.transports[name];
if ((transport.level && self.levels[transport.level] <= self.levels[level])
|| (!transport.level && self.levels[self.level] <= self.levels[level])) {
transport.log(level, msg, meta, function (err) {
if (err) {
err.transport = transport;
cb(err);
return next();
}
self.emit('logging', transport, level, msg, meta);
next();
});
} else {
next();
}
}
//
// Immediately respond to the callback
// Respond to the callback
//
if (callback) {
callback(null, level, msg, meta);
function cb(err) {
if (callback) {
if (err) return callback(err);
callback(null, level, msg, meta);
}
callback = null;
}
async.forEach(this._names, emit, cb);
return this;

@@ -212,2 +230,137 @@ };

//
// ### function query (options, callback)
// #### @options {Object} Query options for this instance.
// #### @callback {function} Continuation to respond to when complete.
// Queries the all transports for this instance with the specified `options`.
// This will aggregate each transport's results into one object containing
// a property per transport.
//
Logger.prototype.query = function (options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
var self = this,
options = options || {},
results = {},
query = common.clone(options.query) || {},
transports;
//
// Helper function to query a single transport
//
function queryTransport(transport, next) {
if (options.query) {
options.query = transport.formatQuery(query);
}
transport.query(options, function (err, results) {
if (err) {
return next(err);
}
next(null, transport.formatResults(results, options.format));
});
}
//
// Helper function to accumulate the results from
// `queryTransport` into the `results`.
//
function addResults (transport, next) {
queryTransport(transport, function (err, result) {
result = err || result;
if (result) {
results[transport.name] = result;
}
next();
});
}
//
// If an explicit transport is being queried then
// respond with the results from only that transport
//
if (options.transport) {
options.transport = options.transport.toLowerCase();
return queryTransport(this.transports[options.transport], callback);
}
//
// Create a list of all transports for this instance.
//
transports = this._names.map(function (name) {
return self.transports[name];
}).filter(function (transport) {
return !!transport.query;
});
//
// Iterate over the transports in parallel setting the
// appropriate key in the `results`
//
async.forEach(transports, addResults, function () {
callback(null, results);
});
};
//
// ### function stream (options)
// #### @options {Object} Stream options for this instance.
// Returns a log stream for all transports. Options object is optional.
//
Logger.prototype.stream = function (options) {
var self = this,
options = options || {},
out = new Stream,
streams = [],
transports;
if (options.transport) {
var transport = this.transports[options.transport];
delete options.transport;
if (transport && transport.stream) {
return transport.stream(options);
}
}
out._streams = streams;
out.destroy = function () {
var i = streams.length;
while (i--) streams[i].destroy();
};
//
// Create a list of all transports for this instance.
//
transports = this._names.map(function (name) {
return self.transports[name];
}).filter(function (transport) {
return !!transport.stream;
});
transports.forEach(function (transport) {
var stream = transport.stream(options);
if (!stream) return;
streams.push(stream);
stream.on('log', function (log) {
log.transport = log.transport || [];
log.transport.push(transport.name);
out.emit('log', log);
});
stream.on('error', function (err) {
err.transport = err.transport || [];
err.transport.push(transport.name);
out.emit('error', err);
});
});
return out;
};
//
// ### function close ()

@@ -219,3 +372,3 @@ // Cleans up resources (streams, event listeners) for all

var self = this;
this._names.forEach(function (name) {

@@ -230,3 +383,3 @@ var transport = self.transports[name];

//
// ### function handleExceptions ()
// ### function handleExceptions ()
// Handles `uncaughtException` events for the current process

@@ -238,3 +391,3 @@ //

self = this;
args.forEach(function (a) {

@@ -248,9 +401,9 @@ if (Array.isArray(a)) {

});
handlers.forEach(function (handler) {
self.exceptionHandlers[handler.name] = handler;
});
this._hnames = Object.keys(self.exceptionHandlers);
if (!this.catchExceptions) {

@@ -263,3 +416,3 @@ this.catchExceptions = this._uncaughtException.bind(this);

//
// ### function unhandleExceptions ()
// ### function unhandleExceptions ()
// Removes any handlers to `uncaughtException` events

@@ -270,3 +423,3 @@ // for the current process

var self = this;
if (this.catchExceptions) {

@@ -278,3 +431,3 @@ Object.keys(this.exceptionHandlers).forEach(function (name) {

});
this.exceptionHandlers = {};

@@ -287,5 +440,5 @@ Object.keys(this.transports).forEach(function (name) {

})
process.removeListener('uncaughtException', this.catchExceptions);
this.catchExceptions = false;
this.catchExceptions = false;
}

@@ -303,3 +456,3 @@ };

var instance = created ? transport : (new (transport)(options));
if (!instance.name && !instance.log) {

@@ -311,6 +464,6 @@ throw new Error('Unknown transport with no log() method');

}
this.transports[instance.name] = instance;
this._names = Object.keys(this.transports);
//

@@ -321,3 +474,3 @@ // Listen for the `error` event on the new Transport

instance.on('error', instance._onError);
//

@@ -341,3 +494,3 @@ // If this transport has `handleExceptions` set to `true`

//
Logger.prototype.addRewriter = function(rewriter) {
Logger.prototype.addRewriter = function (rewriter) {
this.rewriters.push(rewriter);

@@ -357,3 +510,3 @@ }

//
// ### function remove (transport)
// ### function remove (transport)
// #### @transport {Transport} Transport to remove.

@@ -364,15 +517,15 @@ // Removes a transport of the specified type from this instance.

var name = transport.name || transport.prototype.name;
if (!this.transports[name]) {
throw new Error('Transport ' + name + ' not attached to this instance');
}
var instance = this.transports[name];
delete this.transports[name];
this._names = Object.keys(this.transports);
if (instance.close) {
instance.close();
}
instance.removeListener('error', instance._onError);

@@ -392,3 +545,3 @@ return this;

meta = typeof args[args.length - 1] === 'object' ? args.pop() : {};
meta.duration = (Date.now()) - this.start + 'ms';

@@ -406,3 +559,3 @@

// ### function profile (id, [msg, meta, callback])
// #### @id {string} Unique id of the profiler
// #### @id {string} Unique id of the profiler
// #### @msg {string} **Optional** Message to log

@@ -418,7 +571,7 @@ // #### @meta {Object} **Optional** Additional metadata to attach

msg, meta, callback;
if (this.profilers[id]) {
then = this.profilers[id];
delete this.profilers[id];
// Support variable arguments: msg, meta, callback

@@ -428,6 +581,6 @@ args = Array.prototype.slice.call(arguments);

meta = typeof args[args.length - 1] === 'object' ? args.pop() : {};
msg = args.length === 2 ? args[1] : id;
msg = args.length === 2 ? args[1] : id;
// Set the duration property of the metadata
meta.duration = now - then + 'ms';
meta.duration = now - then + 'ms';
return this.info(msg, meta, callback);

@@ -438,3 +591,3 @@ }

}
return this;

@@ -462,3 +615,3 @@ };

config.addColors(config.cli.colors);
if (this.transports.console) {

@@ -468,3 +621,3 @@ this.transports.console.colorize = true;

}
return this;

@@ -474,3 +627,3 @@ };

//
// ### @private function _uncaughtException (err)
// ### @private function _uncaughtException (err)
// #### @err {Error} Error to handle

@@ -487,3 +640,3 @@ // Logs all relevant information around the `err` and

doExit;
//

@@ -495,7 +648,7 @@ // Calculate if we should exit on this error

: this.exitOnError;
function logAndWait(transport, next) {
transport.logException('uncaughtException', info, next, err);
}
function gracefulExit() {

@@ -512,7 +665,7 @@ if (doExit && !responded) {

}
if (!handlers || handlers.length === 0) {
return gracefulExit();
}
//

@@ -519,0 +672,0 @@ // Log to all transports and allow the operation to take

@@ -21,7 +21,7 @@ /*

name = common.capitalize(transport);
if (transport === 'transport') {
return;
}
transports.__defineGetter__(name, function () {

@@ -28,0 +28,0 @@ return require('./transports/' + transport)[name];

@@ -24,3 +24,3 @@ /*

options = options || {};
this.name = 'console';

@@ -30,3 +30,3 @@ this.json = options.json || false;

this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false;
if (this.json) {

@@ -66,3 +66,3 @@ this.stringify = options.stringify || function (obj) {

output = common.log({
colorize: this.colorize,
colorize: this.colorize,
json: this.json,

@@ -78,7 +78,6 @@ level: level,

if (level === 'error' || level === 'debug') {
util.error(output);
console.error(output);
} else {
console.log(output);
}
else {
util.puts(output);
}

@@ -85,0 +84,0 @@ //

@@ -15,4 +15,5 @@ /*

common = require('../common'),
Transport = require('./transport').Transport;
Transport = require('./transport').Transport,
Stream = require('stream').Stream;
//

@@ -26,6 +27,6 @@ // ### function File (options)

Transport.call(this, options);
//
// Helper function which throws an `Error` in the event
// that any of the rest of the arguments is present in `options`.
// that any of the rest of the arguments is present in `options`.
//

@@ -39,3 +40,3 @@ function throwIf (target /*, illegal... */) {

}
if (options.filename || options.dirname) {

@@ -45,7 +46,14 @@ throwIf('filename or dirname', 'stream');

this.dirname = options.dirname || path.dirname(options.filename);
this.options = options.options || { flags: 'a' };
this.options = options.options || { flags: 'a' };
}
else if (options.stream) {
throwIf('stream', 'filename', 'maxsize');
this.stream = options.stream;
this._stream = options.stream;
//
// We need to listen for drain events when
// write() returns false. This can make node
// mad at times.
//
this._stream.setMaxListeners(Infinity);
}

@@ -55,3 +63,3 @@ else {

}
this.json = options.json !== false;

@@ -61,3 +69,3 @@ this.colorize = options.colorize || false;

this.maxFiles = options.maxFiles || null;
this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false;
this.timestamp = options.timestamp != null ? options.timestamp : true;

@@ -98,3 +106,5 @@ //

var self = this, output = common.log({
var self = this;
var output = common.log({
level: level,

@@ -107,5 +117,5 @@ message: msg,

}) + '\n';
this._size += output.length;
if (!this.filename) {

@@ -117,4 +127,4 @@ //

//
this.stream.write(output);
self._lazyDrain();
this._write(output, callback);
this._lazyDrain();
}

@@ -127,10 +137,28 @@ else {

//
return self._buffer.push(output);
return self._buffer.push([output, callback]);
}
self.stream.write(output);
self._write(output, callback);
self._lazyDrain();
});
}
};
//
// ### function _write (data, cb)
// #### @data {String|Buffer} Data to write to the instance's stream.
// #### @cb {function} Continuation to respond to when complete.
// Write to the stream, ensure execution of a callback on completion.
//
File.prototype._write = function(data, callback) {
// If this is a file write stream, we could use the builtin
// callback functionality, however, the stream is not guaranteed
// to be an fs.WriteStream.
var ret = this._stream.write(data);
if (!callback) return;
if (ret === false) {
return this._stream.once('drain', function() {
callback(null, true);
});
}
callback(null, true);

@@ -140,2 +168,200 @@ };

//
// ### function query (options, callback)
// #### @options {Object} Loggly-like query options for this instance.
// #### @callback {function} Continuation to respond to when complete.
// Query the transport. Options object is optional.
//
File.prototype.query = function (options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
var file = path.join(this.dirname, this.filename),
options = this.normalizeQuery(options),
buff = '',
results = [],
row = 0;
var stream = fs.createReadStream(file, {
encoding: 'utf8'
});
stream.on('error', function (err) {
if (stream.readable) {
stream.destroy();
}
if (!callback) return;
return err.code !== 'ENOENT'
? callback(err)
: callback(null, results);
});
stream.on('data', function (data) {
var data = (buff + data).split(/\n+/),
l = data.length - 1,
i = 0;
for (; i < l; i++) {
if (!options.start || row >= options.start) {
add(data[i]);
}
row++;
}
buff = data[l];
});
stream.on('close', function () {
if (buff) add(buff, true);
if (options.order === 'desc') {
results = results.reverse();
}
if (callback) callback(null, results);
});
function add(buff, attempt) {
try {
var log = JSON.parse(buff);
if (check(log)) push(log);
} catch (e) {
if (!attempt) {
stream.emit('error', e);
}
}
}
function push(log) {
if (options.rows && results.length >= options.rows) {
if (stream.readable) {
stream.destroy();
}
return;
}
if (options.fields) {
var obj = {};
options.fields.forEach(function (key) {
obj[key] = log[key];
});
log = obj;
}
results.push(log);
}
function check(log) {
if (!log) return;
if (typeof log !== 'object') return;
var time = new Date(log.timestamp);
if ((options.from && time < options.from)
|| (options.until && time > options.until)) {
return;
}
return true;
}
};
//
// ### function _tail (options, callback)
// #### @options {Object} Options for tail.
// #### @callback {function} Callback to execute on every line.
// `tail -f` a file. Options must include file.
//
File.prototype._tail = function tail(options, callback) {
var stream = fs.createReadStream(options.file, { encoding: 'utf8' }),
buff = '',
destroy,
row = 0;
destroy = stream.destroy.bind(stream);
stream.destroy = function () {};
if (options.start === -1) {
delete options.start;
}
if (options.start == null) {
stream.once('end', bind);
} else {
bind();
}
function bind() {
stream.on('data', function (data) {
var data = (buff + data).split(/\n+/),
l = data.length - 1,
i = 0;
for (; i < l; i++) {
if (options.start == null || row > options.start) {
stream.emit('line', data[i]);
}
row++;
}
buff = data[l];
});
stream.on('line', function (data) {
if (callback) callback(data);
});
stream.on('error', function (err) {
destroy();
});
stream.on('end', function () {
if (buff) {
stream.emit('line', buff);
buff = '';
}
resume();
});
resume();
}
function resume() {
setTimeout(function () {
stream.resume();
}, 1000);
}
return destroy;
};
//
// ### function stream (options)
// #### @options {Object} Stream options for this instance.
// Returns a log stream for this transport. Options object is optional.
//
File.prototype.stream = function (options) {
var file = path.join(this.dirname, this.filename),
options = options || {},
stream = new Stream;
var tail = {
file: file,
start: options.start
};
stream.destroy = this._tail(tail, function (line) {
try {
stream.emit('data', line);
line = JSON.parse(line);
stream.emit('log', line);
} catch (e) {
stream.emit('error', e);
}
});
return stream;
};
//
// ### function open (callback)

@@ -155,6 +381,6 @@ // #### @callback {function} Continuation to respond to when complete

}
else if (!this.stream || (this.maxsize && this._size >= this.maxsize)) {
else if (!this._stream || (this.maxsize && this._size >= this.maxsize)) {
//
// If we dont have a stream or have exceeded our size, then create
// the next stream and respond with a value indicating that
// the next stream and respond with a value indicating that
// the message should be buffered.

@@ -165,3 +391,3 @@ //

}
//

@@ -180,7 +406,7 @@ // Otherwise we have a valid (and ready) stream.

if (this.stream) {
this.stream.end();
this.stream.destroySoon();
this.stream.once('drain', function () {
if (this._stream) {
this._stream.end();
this._stream.destroySoon();
this._stream.once('drain', function () {
self.emit('flush');

@@ -202,11 +428,14 @@ self.emit('closed');

// Iterate over the `_buffer` of enqueued messaged
// and then write them to the newly created stream.
// and then write them to the newly created stream.
//
this._buffer.forEach(function (str) {
this._buffer.forEach(function (item) {
var str = item[0],
callback = item[1];
process.nextTick(function () {
self.stream.write(str);
self._write(str, callback);
self._size += str.length;
});
});
//

@@ -217,3 +446,3 @@ // Quickly truncate the `_buffer` once the write operations

self._buffer.length = 0;
//

@@ -223,3 +452,3 @@ // When the stream has drained we have flushed

//
self.stream.once('drain', function () {
self._stream.once('drain', function () {
self.emit('flush');

@@ -238,6 +467,6 @@ self.emit('logged');

this.opening = true;
(function checkFile (target) {
var fullname = path.join(self.dirname, target);
//

@@ -248,14 +477,21 @@ // Creates the `WriteStream` and then flushes any

function createAndFlush (size) {
if (self.stream) {
self.stream.end();
self.stream.destroySoon();
if (self._stream) {
self._stream.end();
self._stream.destroySoon();
}
self._size = size;
self.filename = target;
self.stream = fs.createWriteStream(fullname, self.options);
self._stream = fs.createWriteStream(fullname, self.options);
//
// When the current stream has finished flushing
// then we can be sure we have finished opening
// We need to listen for drain events when
// write() returns false. This can make node
// mad at times.
//
self._stream.setMaxListeners(Infinity);
//
// When the current stream has finished flushing
// then we can be sure we have finished opening
// and thus can emit the `open` event.

@@ -282,17 +518,17 @@ //

}
return createAndFlush(0);
}
if (!stats || (self.maxsize && stats.size >= self.maxsize)) {
//
// If `stats.size` is greater than the `maxsize` for
// this instance then try again
// If `stats.size` is greater than the `maxsize` for
// this instance then try again
//
return checkFile(self._getFile(true));
}
createAndFlush(stats.size);
});
})(this._getFile());
})(this._getFile());
};

@@ -310,6 +546,6 @@

remaining;
if (inc) {
//
// Increment the number of files created or
// Increment the number of files created or
// checked by this instance.

@@ -327,7 +563,7 @@ //

}
this._created += 1;
}
return this._created
return this._created
? basename + this._created + ext

@@ -339,3 +575,3 @@ : basename + ext;

// ### @private function _lazyDrain ()
// Lazily attempts to emit the `logged` event when `this.stream` has
// Lazily attempts to emit the `logged` event when `this.stream` has
// drained. This is really just a simple mutex that only works because

@@ -346,11 +582,11 @@ // Node.js is single-threaded.

var self = this;
if (!this._draining && this.stream) {
if (!this._draining && this._stream) {
this._draining = true;
this.stream.once('drain', function () {
this._stream.once('drain', function () {
this._draining = false;
self.emit('logged');
});
}
};
}
};

@@ -10,3 +10,3 @@ /*

var events = require('events'),
util = require('util');
util = require('util');

@@ -21,4 +21,4 @@ //

events.EventEmitter.call(this);
options = options || {};
options = options || {};
this.level = options.level || 'info';

@@ -37,3 +37,64 @@ this.silent = options.silent || false;

//
// ### function logException (msg, meta, callback)
// ### function formatQuery (query)
// #### @query {string|Object} Query to format
// Formats the specified `query` Object (or string) to conform
// with the underlying implementation of this transport.
//
Transport.prototype.formatQuery = function (query) {
return query;
};
//
// ### function normalizeQuery (query)
// #### @options {string|Object} Query to normalize
// Normalize options for query
//
Transport.prototype.normalizeQuery = function (options) {
//
// Use options similar to loggly.
// [See Loggly Search API](http://wiki.loggly.com/retrieve_events#optional)
//
options = options || {};
// limit
options.rows = options.rows || options.limit || 10;
// starting row offset
options.start = options.start || 0;
// now - 24
options.from = options.from || new Date - (24 * 60 * 60 * 1000);
if (typeof options.from !== 'object') {
options.from = new Date(options.from);
}
// now
options.until = options.until || new Date;
if (typeof options.until !== 'object') {
options.until = new Date(options.until);
}
// 'asc' or 'desc'
options.order = options.order || 'desc';
// which fields to select
options.fields = options.fields;
return options;
};
//
// ### function formatResults (results, options)
// #### @results {Object|Array} Results returned from `.query`.
// #### @options {Object} **Optional** Formatting options
// Formats the specified `results` with the given `options` accordinging
// to the implementation of this transport.
//
Transport.prototype.formatResults = function (results, options) {
return results;
};
//
// ### function logException (msg, meta, callback)
// #### @msg {string} Message to log

@@ -48,3 +109,3 @@ // #### @meta {Object} **Optional** Additional metadata to attach

var self = this;
function onLogged () {

@@ -54,3 +115,3 @@ self.removeListener('error', onError);

}
function onError () {

@@ -60,6 +121,6 @@ self.removeListener('logged', onLogged);

}
this.once('logged', onLogged);
this.once('error', onError);
this.once('error', onError);
this.log('error', msg, meta, function () { });
};
};

@@ -13,4 +13,5 @@ /*

util = require('util'),
cycle = require('cycle'),
common = require('../common'),
Transport = require('./transport').Transport;
Transport = require('./transport').Transport;

@@ -27,3 +28,3 @@ //

this.name = 'webhook';
this.name = 'webhook';
this.host = options.host || 'localhost';

@@ -39,3 +40,3 @@ this.port = options.port || 8080;

}
if (options.ssl) {

@@ -71,10 +72,8 @@ this.ssl = {};

}
var self = this,
meta = cycle.decycle(meta),
message = common.clone(meta),
options,
req;
message.level = level;
message.message = msg;

@@ -95,3 +94,3 @@ // Prepare options for outgoing HTTP request

}
if (this.auth) {

@@ -106,7 +105,8 @@ // Encode `Authorization` header used by Basic Auth

req = (self.ssl ? https : http).request(options, function (res) {
//
// No callback on request, fire and forget about the response
//
// TODO: emit 'logged' correctly,
// keep track of pending logs.
self.emit('logged');
});
if (callback) callback(null, true);
callback = null;
});

@@ -119,25 +119,25 @@ req.on('error', function (err) {

self.emit('error', err);
if (callback) callback(err, false);
callback = null;
});
//
// Write logging event to the outgoing request body
//
// jsonMessage is currently conforming to JSON-RPC v1.0,
// but without the unique id since there is no anticipated response
// jsonMessage is currently conforming to JSON-RPC v1.0,
// but without the unique id since there is no anticipated response
// see: http://en.wikipedia.org/wiki/JSON-RPC
//
req.write(JSON.stringify({
method: 'log',
params: {
timestamp: new Date(),
msg: msg,
level: level,
meta: meta
}
//
var params = common.clone(meta) || {};
params.timestamp = new Date();
params.message = msg;
params.level = level;
req.write(JSON.stringify({
method: 'log',
params: params
}));
req.end();
// Always return true, regardless of any errors
callback(null, true);
};
{
"name": "winston",
"description": "A multi-transport async logging library for Node.js",
"version": "0.5.11",
"author": "Charlie Robbins <charlie.robbins@gmail.com>",
"contributors": [
{ "name": "Matthew Bergman", "email": "mzbphoto@gmail.com" },
{ "name": "Marak Squires", "email": "marak@nodejitsu.com" }
"version": "0.6.1",
"author": "Nodejitsu Inc. <info@nodejitsu.com>",
"maintainers": [
"indexzero <charlie@nodejitsu.com>"
],

@@ -14,3 +13,7 @@ "repository": {

},
"keywords": ["logging", "sysadmin", "tools"],
"keywords": [
"logging",
"sysadmin",
"tools"
],
"dependencies": {

@@ -20,5 +23,6 @@ "async": "0.1.x",

"eyes": "0.1.x",
"loggly": "0.3.x >=0.3.7",
"pkginfo": "0.2.x",
"stack-trace": "0.0.x"
"stack-trace": "0.0.x",
"cycle": "1.0.x",
"request": "2.9.x"
},

@@ -29,4 +33,8 @@ "devDependencies": {

"main": "./lib/winston",
"scripts": { "test": "vows --spec --isolate" },
"engines": { "node": ">= 0.4.0" }
"scripts": {
"test": "vows --spec --isolate"
},
"engines": {
"node": ">= 0.4.0"
}
}

@@ -5,16 +5,4 @@ # winston [![Build Status](https://secure.travis-ci.org/flatiron/winston.png)](http://travis-ci.org/flatiron/winston)

## Installation
### Installing npm (node package manager)
```
curl http://npmjs.org/install.sh | sh
```
### Installing winston
```
[sudo] npm install winston
```
## Motivation
Winston is designed to be a simple and universal logging library with support for multiple transports. A transport is essentially a storage device for your logs. Each instance of a winston logger can have multiple transports configured at different levels. For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file.
Winston is designed to be a simple and universal logging library with support for multiple transports. A transport is essentially a storage device for your logs. Each instance of a winston logger can have multiple transports configured at different levels. For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file.

@@ -24,4 +12,27 @@ There also seemed to be a lot of logging libraries out there that coupled their implementation of logging (i.e. how the logs are stored / indexed) to the API that they exposed to the programmer. This library aims to decouple those parts of the process to make it more flexible and extensible.

## Usage
There are two different ways to use winston: directly via the default logger, or by instantiating your own Logger. The former is merely intended to be a convenient shared logger to use throughout your application if you so choose.
There are two different ways to use winston: directly via the default logger, or by instantiating your own Logger. The former is merely intended to be a convenient shared logger to use throughout your application if you so choose.
* [Logging](#logging)
* [Using the Default Logger](#using-the-default-logger)
* [Instantiating your own Logger](#instantiating-your-own-logger)
* [Logging with Metadata](#logging-with-metadata)
* [Transports](https://github.com/flatiron/winston/tree/query_stream/docs/transports.md)
* [Profiling](#profiling)
* [Streaming Logs](#streaming-logs)
* [Querying Logs](#querying-logs)
* [Exceptions](#exceptions)
* [Handling Uncaught Exceptions with winston](#handling-uncaught-exceptions-with-winston)
* [To Exit or Not to Exit](#to-exit-or-not-to-exit)
* [Logging Levels](#logging-levels)
* [Using Logging Levels](#using-logging-levels)
* [Using Custom Logging Levels](#using-custom-logging-levels)
* [Further Reading](#further-reading)
* [Events and Callbacks in Winston](#events-and-callbacks-in-winston)
* [Working with multiple Loggers in winston](#working-with-multiple-loggers-in-winston)
* [Using winston in a CLI tool](#using-winston-in-a-cli-tool)
* [Extending another object with Logging](#extending-another-object-with-logging)
* [Adding Custom Transports](#adding-custom-transports)
## Logging
### Using the Default Logger

@@ -32,3 +43,3 @@ The default logger is accessible through the winston module directly. Any method that you could call on an instance of a logger is available on the default logger:

var winston = require('winston');
winston.log('info', 'Hello distributed log files!');

@@ -45,3 +56,3 @@ winston.info('Hello again distributed logs');

For more documenation about working with each individual transport supported by Winston see the "Working with Transports" section below.
For more documenation about working with each individual transport supported by Winston see the "Working with Transports" section below.

@@ -60,3 +71,3 @@ ### Instantiating your own Logger

You can work with this logger in the same way that you work with the default logger:
You can work with this logger in the same way that you work with the default logger:

@@ -69,3 +80,3 @@ ``` js

logger.info('Hello again distributed logs');
//

@@ -79,2 +90,72 @@ // Adding / Removing Transports

### Logging with Metadata
In addition to logging string messages, winston will also optionally log additional JSON metadata objects. Adding metadata is simple:
``` js
winston.log('info', 'Test Log Message', { anything: 'This is metadata' });
```
The way these objects is stored varies from transport to transport (to best support the storage mechanisms offered). Here's a quick summary of how each transports handles metadata:
1. __Console:__ Logged via util.inspect(meta)
2. __File:__ Logged via util.inspect(meta)
## Profiling
In addition to logging messages and metadata, winston also has a simple profiling mechanism implemented for any logger:
``` js
//
// Start profile of 'test'
// Remark: Consider using Date.now() with async operations
//
winston.profile('test');
setTimeout(function () {
//
// Stop profile of 'test'. Logging will now take place:
// "17 Jan 21:00:00 - info: test duration=1000ms"
//
winston.profile('test');
}, 1000);
```
All profile messages are set to the 'info' by default and both message and metadata are optional There are no plans in the Roadmap to make this configurable, but I'm open to suggestions / issues.
## Querying Logs
Winston supports querying of logs with Loggly-like options.
Specifically: `File`, `Couchdb`, `Redis`, `Loggly`, `Nssocket`, and `Http`.
``` js
var options = {
from: new Date - 24 * 60 * 60 * 1000,
until: new Date
};
//
// Find items logged between today and yesterday.
//
winston.query(options, function (err, results) {
if (err) {
throw err;
}
console.log(results);
});
```
## Streaming Logs
Streaming allows you to stream your logs back from your chosen transport.
``` js
//
// Start at the end.
//
winston.stream({ start: -1 }).on('log', function(log) {
console.log(log);
});
```
## Exceptions
### Handling Uncaught Exceptions with winston

@@ -91,13 +172,13 @@

winston.handleExceptions(new winston.transports.File({ filename: 'path/to/exceptions.log' }))
//
// Alternatively you can set `.handleExceptions` to true when adding transports to winston
//
winston.add(winston.transports.File, {
filename: 'path/to/all-logs.log',
handleExceptions: true
winston.add(winston.transports.File, {
filename: 'path/to/all-logs.log',
handleExceptions: true
});
```
## to exit or not to exit
### To Exit or Not to Exit

@@ -144,4 +225,6 @@ by default, winston will exit after logging an uncaughtException. if this is not the behavior you want,

## Logging Levels
### Using Logging Levels
Setting the level for your logging message can be accomplished in one of two ways. You can pass a string representing the logging level to the log() method or use the level specified methods defined on every winston Logger.
Setting the level for your logging message can be accomplished in one of two ways. You can pass a string representing the logging level to the log() method or use the level specified methods defined on every winston Logger.

@@ -154,3 +237,3 @@ ``` js

logger.info("127.0.0.1 - there's no place like home");
//

@@ -163,2 +246,13 @@ // Default logger

Winston allows you to set a `level` on each transport that specifies the level of messages this transport should log. For example, you could log only errors to the console, with the full logs in a file:
``` js
var logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)({ level: 'error' }),
new (winston.transports.File)({ filename: 'somefile.log' })
]
});
```
As of 0.2.0, winston supports customizable logging levels, defaulting to [npm][0] style logging levels. Changing logging levels is easy:

@@ -171,3 +265,3 @@

winston.setLevels(winston.config.syslog.levels);
//

@@ -183,3 +277,3 @@ // Change levels on an instance of a logger

//
// Logger does not have 'silly' defined since that level is not in the syslog levels
// Logger does not have 'silly' defined since that level is not in the syslog levels
//

@@ -207,4 +301,4 @@ logger.silly('some silly message');

};
var customLevelLogger = new (winston.Logger)({ levels: myCustomLevels.levels });
var customLevelLogger = new (winston.Logger)({ levels: myCustomLevels.levels });
customLevelLogger.foobar('some foobar level-ed message');

@@ -224,2 +318,4 @@ ```

## Further Reading
### Events and Callbacks in Winston

@@ -232,3 +328,3 @@ Each instance of winston.Logger is also an instance of an [EventEmitter][1]. A log event will be raised each time a transport successfully logs a message:

});
logger.info('CHILL WINSTON!', { seriously: true });

@@ -244,3 +340,3 @@ ```

logger.on('error', function (err) { /* Do Something */ });
//

@@ -266,3 +362,3 @@ // Or just suppress them.

var winston = require('winston');
//

@@ -280,3 +376,3 @@ // Configure the logger for `category1`

});
//

@@ -297,3 +393,3 @@ // Configure the logger for `category2`

var winston = require('winston');
//

@@ -303,3 +399,3 @@ // Grab your preconfigured logger

var category1 = winston.loggers.get('category1');
category1.info('logging from your IoC container-based logger');

@@ -313,3 +409,3 @@ ```

container = new winston.Container();
container.add('category1', {

@@ -337,3 +433,3 @@ console: {

// 2. By passing `transports` into the constructor function of winston.Container
// 3. By passing `transports` into the `.get()` or `.add()` methods
// 3. By passing `transports` into the `.get()` or `.add()` methods
//

@@ -358,4 +454,4 @@

//
// 3. By passing `transports` into the `.get()` or `.add()` methods
//
// 3. By passing `transports` into the `.get()` or `.add()` methods
//
winston.loggers.add('some-category', {

@@ -374,38 +470,4 @@ transports: [

### Logging with Metadata
In addition to logging string messages, winston will also optionally log additional JSON metadata objects. Adding metadata is simple:
``` js
winston.log('info', 'Test Log Message', { anything: 'This is metadata' });
```
The way these objects is stored varies from transport to transport (to best support the storage mechanisms offered). Here's a quick summary of how each transports handles metadata:
1. __Console:__ Logged via util.inspect(meta)
2. __File:__ Logged via util.inspect(meta)
3. __Loggly:__ Logged in suggested [Loggly format][2]
### Profiling with Winston
In addition to logging messages and metadata, winston also has a simple profiling mechanism implemented for any logger:
``` js
//
// Start profile of 'test'
// Remark: Consider using Date.now() with async operations
//
winston.profile('test');
setTimeout(function () {
//
// Stop profile of 'test'. Logging will now take place:
// "17 Jan 21:00:00 - info: test duration=1000ms"
//
winston.profile('test');
}, 1000);
```
All profile messages are set to the 'info' by default and both message and metadata are optional There are no plans in the Roadmap to make this configurable, but I'm open to suggestions / issues.
### Using winston in a CLI tool
A common use-case for logging is output to a CLI tool. Winston has a special helper method which will pretty print output from your CLI tool. Here's an example from the [require-analyzer][15] written by [Nodejitsu][5]:
A common use-case for logging is output to a CLI tool. Winston has a special helper method which will pretty print output from your CLI tool. Here's an example from the [require-analyzer][2] written by [Nodejitsu][3]:

@@ -434,3 +496,3 @@ ```

var winston = require('winston');
//

@@ -440,3 +502,3 @@ // Configure CLI output on the default logger

winston.cli();
//

@@ -450,7 +512,7 @@ // Configure CLI on an instance of winston.Logger

});
logger.cli();
```
### Extending another object with Logging functionality
### Extending another object with Logging
Often in a given code base with lots of Loggers it is useful to add logging methods a different object so that these methods can be called with less syntax. Winston exposes this functionality via the 'extend' method:

@@ -460,5 +522,5 @@

var myObject = {};
logger.extend(myObject);
//

@@ -484,3 +546,3 @@ // You can now call logger methods on 'myObject'

* __level:__ Level of messages that this transport should log (default 'debug').
* __level:__ Level of messages that this transport should log (default 'info').
* __silent:__ Boolean flag indicating whether to suppress output (default false).

@@ -604,11 +666,12 @@ * __colorize:__ Boolean flag indicating if we should colorize output (default false).

The Mail transport uses [node-mail][20] behind the scenes. Options are the following, `to` and `host` are required:
The Mail transport uses [emailjs](https://github.com/eleith/emailjs) behind the scenes. Options are the following:
* __to:__ The address(es) you want to send to. *[required]*
* __from:__ The address you want to send from. (default: `winston@[server-host-name]`)
* __host:__ SMTP server hostname
* __host:__ SMTP server hostname (default: localhost)
* __port:__ SMTP port (default: 587 or 25)
* __secure:__ Use secure
* __username__ User for server auth
* __password__ Password for server auth
* __ssl:__ Use SSL (boolean or object { key, ca, cert })
* __tls:__ Boolean (if true, use starttls)
* __level:__ Level of messages that this transport should log.

@@ -666,3 +729,3 @@ * __silent:__ Boolean flag indicating whether to suppress output.

winston = require('winston');
var CustomLogger = winston.transports.CustomerLogger = function (options) {

@@ -673,3 +736,3 @@ //

this.name = 'customLogger';
//

@@ -679,3 +742,3 @@ // Set the level from your options

this.level = options.level || 'info';
//

@@ -685,3 +748,3 @@ // Configure your storage backing as you see fit

};
//

@@ -692,3 +755,3 @@ // Inherit from `winston.Transport` so you can take advantage

util.inherits(CustomLogger, winston.Transport);
CustomLogger.prototype.log = function (level, msg, meta, callback) {

@@ -699,45 +762,32 @@ //

//
callback(null, true);
callback(null, true);
};
```
## What's Next?
Winston is stable and under active development. It is supported by and used at [Nodejitsu][5].
### Inspirations
1. [npm][0]
2. [log.js][9]
3. [socket.io][10]
4. [node-rlog][11]
5. [BigBrother][12]
6. [Loggly][7]
2. [log.js][4]
3. [socket.io][5]
4. [node-rlog][6]
5. [BigBrother][7]
6. [Loggly][8]
### Road Map
1. Improve support for adding custom Transports not defined in Winston core.
2. Create API for reading from logs across all transports.
3. Add more transports: Redis
## Installation
## Run Tests
All of the winston tests are written in [vows][13], and cover all of the use cases described above. You will need to add valid credentials for the various transports included to test/fixtures/test-config.json before running tests:
### Installing npm (node package manager)
```
curl http://npmjs.org/install.sh | sh
```
``` js
{
"transports": {
"loggly": {
"subdomain": "your-subdomain",
"inputToken": "really-long-token-you-got-from-loggly",
"auth": {
"username": "your-username",
"password": "your-password"
}
}
}
}
### Installing winston
```
[sudo] npm install winston
```
Once you have valid configuration and credentials you can run tests with [vows][13]:
## Run Tests
All of the winston tests are written in [vows][9], and designed to be run with npm.
``` bash
$ npm test
```
vows --spec --isolate
```

@@ -749,22 +799,9 @@ #### Author: [Charlie Robbins](http://twitter.com/indexzero)

[1]: http://nodejs.org/docs/v0.3.5/api/events.html#events.EventEmitter
[2]: http://wiki.loggly.com/loggingfromcode
[3]: http://riakjs.org
[4]: https://github.com/frank06/riak-js/blob/master/src/http_client.coffee#L10
[5]: http://nodejitsu.com
[6]: http://github.com/nodejitsu/node-loggly
[7]: http://loggly.com
[8]: http://www.loggly.com/product/
[9]: https://github.com/visionmedia/log.js
[10]: http://socket.io
[11]: https://github.com/jbrisbin/node-rlog
[12]: https://github.com/feisty/BigBrother
[13]: http://vowsjs.org
[14]: http://nodejs.org/docs/v0.3.5/api/streams.html#writable_Stream
[15]: http://github.com/nodejitsu/require-analyzer
[16]: http://github.com/indexzero/winston-mongodb
[17]: http://github.com/indexzero/winston-riak
[18]: http://github.com/appsattic/winston-simpledb
[19]: http://github.com/wavded/winston-mail
[20]: https://github.com/weaver/node-mail
[21]: https://github.com/jesseditson/winston-sns
[22]: https://github.com/flite/winston-graylog2
[2]: http://github.com/nodejitsu/require-analyzer
[3]: http://nodejitsu.com
[4]: https://github.com/visionmedia/log.js
[5]: http://socket.io
[6]: https://github.com/jbrisbin/node-rlog
[7]: https://github.com/feisty/BigBrother
[8]: http://loggly.com
[9]: http://vowsjs.org

@@ -40,2 +40,3 @@ /*

assert.isArray(info.stack);
helpers.assertDateInfo(info.date);
helpers.assertProcessInfo(info.process);

@@ -47,2 +48,2 @@ helpers.assertOsInfo(info.os);

}
}).export(module);
}).export(module);

@@ -14,3 +14,2 @@ /*

util = require('util'),
loggly = require('loggly'),
vows = require('vows'),

@@ -21,18 +20,2 @@ winston = require('../lib/winston');

helpers.loadConfig = function (dir) {
try {
if (helpers.config) return helpers.config;
var configFile = path.join(dir || __dirname, 'fixtures', 'test-config.json'),
stats = fs.statSync(configFile),
config = JSON.parse(fs.readFileSync(configFile).toString());
helpers.config = config;
return config;
}
catch (ex) {
console.error('test/fixtures/test-config.json must be created with valid data before running tests');
return false;
}
};
helpers.size = function (obj) {

@@ -54,2 +37,6 @@ var size = 0, key;

helpers.assertDateInfo = function (info) {
assert.isNumber(Date.parse(info));
};
helpers.assertProcessInfo = function (info) {

@@ -103,7 +90,2 @@ assert.isNumber(info.pid);

helpers.assertLoggly = function (transport) {
assert.instanceOf(transport, winston.transports.Loggly);
assert.isFunction(transport.log);
};
helpers.assertWebhook = function (transport) {

@@ -182,3 +164,15 @@ assert.instanceOf(transport, winston.transports.Webhook);

var circmetadata = { };
circmetadata['metadata'] = circmetadata;
var circmetadatatest = {
topic: function () {
transport.log('info', 'test message', circmetadata, this.callback.bind(this, null));
}
};
circmetadatatest[assertMsg] = assertFn;
tests['when passed circular metadata'] = circmetadatatest;
return tests;
};

@@ -20,4 +20,4 @@ /*

"the addRewriter() method": {
topic: function(logger) {
logger.addRewriter(function(level, msg, meta) {
topic: function (logger) {
logger.addRewriter(function (level, msg, meta) {
meta.level = level;

@@ -30,11 +30,11 @@ meta.msg = msg;

},
"should add the rewriter": function(logger) {
"should add the rewriter": function (logger) {
assert.equal(helpers.size(logger.rewriters), 1);
},
"the log() method": {
topic: function(logger) {
topic: function (logger) {
logger.once('logging', this.callback);
logger.log('info', 'test message', {"a": "b"});
},
"should run the rewriter": function(transport, level, msg, meta) {
"should run the rewriter": function (transport, level, msg, meta) {
assert.equal(meta.a, 'b');

@@ -53,3 +53,3 @@ assert.equal(meta.level, 'info');

], rewriters: [
function(level, msg, meta) {
function (level, msg, meta) {
meta.level = level;

@@ -59,13 +59,13 @@ meta.msg = msg;

return meta;
}
}
]}),
"should add the rewriter": function(logger) {
"should add the rewriter": function (logger) {
assert.equal(helpers.size(logger.rewriters), 1);
},
"the log() method": {
topic: function(logger) {
topic: function (logger) {
logger.once('logging', this.callback);
logger.log('info', 'test message', {"a": "b"});
},
"should run the rewriter": function(transport, level, msg, meta) {
"should run the rewriter": function (transport, level, msg, meta) {
assert.equal(meta.a, 'b');

@@ -83,7 +83,7 @@ assert.equal(meta.level, 'info');

], rewriters: [
function(level, msg, meta) {
function (level, msg, meta) {
meta.numbers.push(1);
return meta;
},
function(level, msg, meta) {
function (level, msg, meta) {
meta.numbers.push(2);

@@ -94,7 +94,7 @@ return meta;

"the log() method": {
topic: function(logger) {
topic: function (logger) {
logger.once('logging', this.callback);
logger.log('info', 'test message', {"numbers": [0]});
},
"should run the rewriters in correct order": function(transport, level, msg, meta) {
"should run the rewriters in correct order": function (transport, level, msg, meta) {
assert.deepEqual(meta.numbers, [0, 1, 2]);

@@ -101,0 +101,0 @@ }

@@ -13,7 +13,8 @@ /*

winston = require('../lib/winston'),
helpers = require('./helpers');
helpers = require('./helpers'),
transport = require('./transports/transport');
vows.describe('winton/logger').addBatch({
"An instance of winston.Logger": {
topic: new (winston.Logger)({ transports: [new (winston.transports.Console)({ level: 'info' })] }),
topic: new (winston.Logger)({ transports: [new (winston.transports.Console)({ level: 'info' })] }),
"should have the correct methods / properties defined": function (logger) {

@@ -47,4 +48,4 @@ helpers.assertLogger(logger);

"the add() method with a supported transport": {
topic: function (logger) {
return logger.add(winston.transports.Console);
topic: function (logger) {
return logger.add(winston.transports.Console);
},

@@ -131,3 +132,3 @@ "should add the console Transport onto transports": function (logger) {

assert.match(meta.duration, /(\d+)ms/);
var duration = parseInt(meta.duration);

@@ -140,6 +141,6 @@ assert.isNumber(duration);

"and adding an additional transport": {
topic: function (logger) {
return logger.add(winston.transports.File, {
filename: path.join(__dirname, 'fixtures', 'logs', 'testfile2.log')
});
topic: function (logger) {
return logger.add(winston.transports.File, {
filename: path.join(__dirname, 'fixtures', 'logs', 'testfile2.log')
});
},

@@ -156,7 +157,7 @@ "should be able to add multiple transports": function (logger) {

"The winston logger": {
topic: new (winston.Logger)({
topic: new (winston.Logger)({
transports: [
new (winston.transports.Console)(),
new (winston.transports.File)({ filename: path.join(__dirname, 'fixtures', 'logs', 'filelog.log' )})
]
]
}),

@@ -168,3 +169,3 @@ "should return have two transports": function (logger) {

"should throw an Error": function (logger) {
assert.throws(function () { logger.remove(winston.transports.Loggly) }, Error);
assert.throws(function () { logger.remove(winston.transports.Webhook) }, Error);
}

@@ -174,3 +175,3 @@ },

topic: function (logger) {
return logger.remove(winston.transports.Console);
return logger.remove(winston.transports.Console);
},

@@ -183,3 +184,3 @@ "should remove the Console transport from transports": function (logger) {

topic: function (logger) {
return logger.remove(winston.transports.File);
return logger.remove(winston.transports.File);
},

@@ -186,0 +187,0 @@ "should remove File transport from transports": function (logger) {

@@ -16,4 +16,10 @@ /*

var stream = fs.createWriteStream(path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log')),
fileTransport = new (winston.transports.File)({ filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfilename.log') }),
var transport = require('./transport');
var stream = fs.createWriteStream(
path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log')
),
fileTransport = new (winston.transports.File)({
filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfilename.log')
}),
streamTransport = new (winston.transports.File)({ stream: stream });

@@ -51,2 +57,6 @@

}
}).export(module);
}).addBatch({
"An instance of the File Transport": transport(winston.transports.File, {
filename: path.join(__dirname, '..', 'fixtures', 'logs', 'testfile.log')
})
}).export(module);

@@ -18,3 +18,3 @@ /*

var webhookTransport = new (winston.transports.Webhook)({
var webhookTransport = new (winston.transports.Webhook)({
"host": "localhost",

@@ -107,3 +107,3 @@ "port": 8080,

//
// Delay destruction of the server since the
// Delay destruction of the server since the
// WebHook transport responds before the request

@@ -121,2 +121,8 @@ // has actually be completed.

}
}).addBatch({
// "An instance of the Webhook Transport": transport(winston.transports.Webhook, {
// "host": "localhost",
// "port": 8080,
// "path": "/winston-test"
// })
}).export(module);

@@ -29,3 +29,2 @@ /*

assert.isFunction(winston.transports.File);
assert.isFunction(winston.transports.Loggly);
assert.isFunction(winston.transports.Webhook);

@@ -77,3 +76,2 @@ assert.isObject(winston.default.transports.console);

assert.isFunction(winston.transports.Console);
assert.isFunction(winston.transports.Loggly);
assert.isFunction(winston.transports.Webhook);

@@ -80,0 +78,0 @@ assert.isObject(winston.default.transports.console);

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc