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

winston

Package Overview
Dependencies
Maintainers
6
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 1.1.2 to 2.0.0

32

CHANGELOG.md

@@ -0,1 +1,33 @@

## v2.0.0 / 2015-10-29
### OMG IT'S MY SISTER'S BIRTHDAY EDITION
#### Breaking changes
**Most important**
- **[0f82204](https://github.com/winstonjs/winston/commit/0f82204) Move `winston.transports.DailyRotateFile` [into a separate module](https://github.com/winstonjs/winston-daily-rotate-file)**: `require('winston-daily-rotate-file');`
- **[fb9eec0](https://github.com/winstonjs/winston/commit/fb9eec0) Reverse log levels in `npm` and `cli` configs to conform to [RFC524](https://tools.ietf.org/html/rfc5424). Fixes [#424](https://github.com/winstonjs/winston/pull/424) [#406](https://github.com/winstonjs/winston/pull/406) [#290](https://github.com/winstonjs/winston/pull/290)**
- **[8cd8368](https://github.com/winstonjs/winston/commit/8cd8368) Change the method signature to a `filter` function to be consistent with `rewriter` and log functions:**
``` js
function filter (level, msg, meta, inst) {
// Filter logic goes here...
}
```
**Other breaking changes**
- [e0c9dde](https://github.com/winstonjs/winston/commit/e0c9dde) Remove `winston.transports.Webhook`. Use `winston.transports.Http` instead.
- [f71e638](https://github.com/winstonjs/winston/commit/f71e638) Remove `Logger.prototype.addRewriter` and `Logger.prototype.addFilter` since they just push to an Array of functions. Use `logger.filters.push` or `logger.rewriters.push` explicitly instead.
- [a470ab5](https://github.com/winstonjs/winston/commit/a470ab5) No longer respect the `handleExceptions` option to `new winston.Logger`. Instead just pass in the `exceptionHandlers` option itself.
- [8cb7048](https://github.com/winstonjs/winston/commit/8cb7048) Removed `Logger.prototype.extend` functionality
#### New features
- [3aa990c](https://github.com/winstonjs/winston/commit/3aa990c) Added `Logger.prototype.configure` which now contains all logic previously in the `winston.Logger` constructor function. (`indexzero`)
- [#726](https://github.com/winstonjs/winston/pull/726) Update .npmignore (`coreybutler`)
- [#700](https://github.com/winstonjs/winston/pull/700) Add an `eol` option to the `Console` transport. (`aquavitae`)
- [#731](https://github.com/winstonjs/winston/pull/731) Update `lib/transports.js` for better static analysis. (`indexzero`)
#### Fixes, refactoring, and optimizations. OH MY!
- [#632](https://github.com/winstonjs/winston/pull/632) Allow `File` transport to be an `objectMode` writable stream. (`stambata`)
- [#527](https://github.com/winstonjs/winston/issues/527), [163f4f9](https://github.com/winstonjs/winston/commit/163f4f9), [3747ccf](https://github.com/winstonjs/winston/commit/3747ccf) Performance optimizations and string interpolation edge cases (`indexzero`)
- [f0edafd](https://github.com/winstonjs/winston/commit/f0edafd) Code cleanup for reability, ad-hoc styleguide enforcement (`indexzero`)
## v1.1.1 - v1.1.2 / 2015-10

@@ -2,0 +34,0 @@ ### MINOR FIXES EDITION

7

lib/winston/config.js

@@ -26,3 +26,4 @@ /*

}
} else if (allColors[level].match(/\s/)) {
}
else if (allColors[level].match(/\s/)) {
var colorArr = allColors[level].split(/\s+/);

@@ -33,5 +34,7 @@ for (var i = 0; i < colorArr.length; ++i) {

allColors[level] = colorArr;
} else {
}
else {
colorized = colors[allColors[level]](colorized);
}
return colorized;

@@ -38,0 +41,0 @@ };

@@ -12,25 +12,25 @@ /*

cliConfig.levels = {
silly: 0,
input: 1,
verbose: 2,
prompt: 3,
debug: 4,
info: 5,
data: 6,
help: 7,
warn: 8,
error: 9
error: 0,
warn: 1,
help: 2,
data: 3,
info: 4,
debug: 5,
prompt: 6,
verbose: 7,
input: 8,
silly: 9,
};
cliConfig.colors = {
silly: 'magenta',
error: 'red',
warn: 'yellow',
help: 'cyan',
data: 'grey',
info: 'green',
debug: 'blue',
prompt: 'grey',
verbose: 'cyan',
input: 'grey',
verbose: 'cyan',
prompt: 'grey',
debug: 'blue',
info: 'green',
data: 'grey',
help: 'cyan',
warn: 'yellow',
error: 'red'
};
silly: 'magenta'
};

@@ -12,17 +12,17 @@ /*

npmConfig.levels = {
silly: 0,
debug: 1,
verbose: 2,
info: 3,
warn: 4,
error: 5
error: 0,
warn: 1,
info: 2,
verbose: 3,
debug: 4,
silly: 5
};
npmConfig.colors = {
silly: 'magenta',
error: 'red',
warn: 'yellow',
info: 'green',
verbose: 'cyan',
debug: 'blue',
info: 'green',
warn: 'yellow',
error: 'red'
};
silly: 'magenta'
};

@@ -19,3 +19,3 @@ /*

info: 6,
debug: 7,
debug: 7
};

@@ -31,3 +31,3 @@

info: 'green',
debug: 'blue',
};
debug: 'blue'
};

@@ -17,2 +17,4 @@ /*

const formatRegExp = /%[sdj%]/g;
//

@@ -26,6 +28,37 @@ // ### function Logger (options)

events.EventEmitter.call(this);
this.configure(options);
};
//
// Inherit from `events.EventEmitter`.
//
util.inherits(Logger, events.EventEmitter);
//
// ### function configure (options)
// This will wholesale reconfigure this instance by:
// 1. Resetting all transports. Older transports will be removed implicitly.
// 2. Set all other options including levels, colors, rewriters, filters,
// exceptionHandlers, etc.
//
Logger.prototype.configure = function (options) {
var self = this;
//
// If we have already been setup with transports
// then remove them before proceeding.
//
if (Array.isArray(this._names) && this._names.length) {
this.clear();
}
options = options || {};
this.transports = {};
this._names = [];
var self = this,
handleExceptions = false;
if (options.transports) {
options.transports.forEach(function (transport) {
self.add(transport, null, true);
});
}

@@ -52,64 +85,20 @@ //

//
// Setup other intelligent default settings.
// Setup internal state as empty Objects even though it is
// defined lazily later to ensure a strong existential API contract.
//
this.transports = {};
this.rewriters = [];
this.filters = [];
this.exceptionHandlers = {};
this.profilers = {};
this._names = [];
this._hnames = [];
if (options.transports) {
options.transports.forEach(function (transport) {
self.add(transport, null, true);
['rewriters', 'filters'].forEach(function (kind) {
self[kind] = Array.isArray(options[kind])
? options[kind]
: [];
});
if (transport.handleExceptions) {
handleExceptions = true;
}
});
}
if (options.rewriters) {
options.rewriters.forEach(function (rewriter) {
self.addRewriter(rewriter);
});
}
if (options.exceptionHandlers) {
handleExceptions = true;
options.exceptionHandlers.forEach(function (handler) {
self._hnames.push(handler.name);
self.exceptionHandlers[handler.name] = handler;
});
this.handleExceptions(options.exceptionHandlers);
}
if (options.handleExceptions || handleExceptions) {
this.handleExceptions();
}
};
//
// Inherit from `events.EventEmitter`.
//
util.inherits(Logger, events.EventEmitter);
//
// ### function extend (target)
// #### @target {Object} Target to extend.
// Extends the target object with a 'log' method
// along with a method for each level in this instance.
//
Logger.prototype.extend = function (target) {
var self = this;
['log', 'profile', 'startTimer'].concat(Object.keys(this.levels)).forEach(function (method) {
target[method] = function () {
return self[method].apply(self, arguments);
};
});
return this;
};
//
// ### function log (level, msg, [meta], callback)

@@ -123,19 +112,24 @@ // #### @level {string} Level at which to log the message.

Logger.prototype.log = function (level) {
var self = this,
args = Array.prototype.slice.call(arguments, 1);
var args = Array.prototype.slice.call(arguments, 1),
self = this,
transports;
while(args[args.length - 1] === null) {
while (args[args.length - 1] === null) {
args.pop();
}
var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null,
meta = typeof args[args.length - 1] === 'object' && Object.prototype.toString.call(args[args.length - 1]) !== '[object RegExp]' ? args.pop() : {},
msg = util.format.apply(null, args);
//
// Determining what is `meta` and what are arguments for string interpolation
// turns out to be VERY tricky. e.g. in the cases like this:
//
// logger.info('No interpolation symbols', 'ok', 'why', { meta: 'is-this' });
//
var callback = typeof args[args.length - 1] === 'function'
? args.pop()
: null;
// If we should pad for levels, do so
if (this.padLevels) {
msg = new Array(this.levelLength - level.length + 1).join(' ') + msg;
}
function onError (err) {
//
// Handle errors appropriately.
//
function onError(err) {
if (callback) {

@@ -149,4 +143,3 @@ callback(err);

if (Object.keys(this.transports).length === 0) {
if (this._names.length === 0) {
return onError(new Error('Cannot log with no transports.'));

@@ -158,2 +151,53 @@ }

//
// If there are no transports that match the level
// then be eager and return. This could potentially be calculated
// during `setLevels` for more performance gains.
//
var targets = this._names.filter(function (name) {
var transport = self.transports[name];
return (transport.level && self.levels[transport.level] >= self.levels[level])
|| (!transport.level && self.levels[self.level] >= self.levels[level]);
});
if (!targets.length) {
if (callback) { callback(); }
return;
}
//
// Determining what is `meta` and what are arguments for string interpolation
// turns out to be VERY tricky. e.g. in the cases like this:
//
// logger.info('No interpolation symbols', 'ok', 'why', { meta: 'is-this' });
//
var metaType = Object.prototype.toString.call(args[args.length - 1]),
fmtMatch = args[0].match && args[0].match(formatRegExp),
isFormat = fmtMatch && fmtMatch.length,
validMeta = !isFormat
? metaType === '[object Object]' || metaType === '[object Error]' || metaType === '[object Array]'
: metaType === '[object Object]',
meta = validMeta ? args.pop() : {},
msg = util.format.apply(null, args);
//
// Respond to the callback.
//
function finish(err) {
if (callback) {
if (err) return callback(err);
callback(null, level, msg, meta);
}
callback = null;
if (!err) {
self.emit('logged', level, msg, meta);
}
}
// If we should pad for levels, do so
if (this.padLevels) {
msg = new Array(this.levelLength - level.length + 1).join(' ') + msg;
}
this.rewriters.forEach(function (rewriter) {

@@ -164,3 +208,3 @@ meta = rewriter(level, msg, meta, self);

this.filters.forEach(function(filter) {
var filtered = filter(msg, meta, level, self);
var filtered = filter(level, msg, meta, self);
if (typeof filtered === 'string')

@@ -189,36 +233,17 @@ msg = filtered;

//
function emit(name, next) {
function transportLog(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 {
transport.log(level, msg, meta, function (err) {
if (err) {
err.transport = transport;
finish(err);
return next();
}
self.emit('logging', transport, level, msg, meta);
next();
}
});
}
//
// Respond to the callback
//
function cb(err) {
if (callback) {
if (err) return callback(err);
callback(null, level, msg, meta);
}
callback = null;
if (!err) {
self.emit('logged', level, msg, meta);
}
}
async.forEach(this._names, emit, cb);
async.forEach(targets, transportLog, finish);
return this;

@@ -268,3 +293,3 @@ };

//
function addResults (transport, next) {
function addResults(transport, next) {
queryTransport(transport, function (err, result) {

@@ -391,4 +416,5 @@ //

//
// ### function handleExceptions ()
// Handles `uncaughtException` events for the current process
// ### function handleExceptions ([tr0, tr1...] || tr0, tr1, ...)
// Handles `uncaughtException` events for the current process by
// ADDING any handlers passed in.
//

@@ -409,2 +435,3 @@ Logger.prototype.handleExceptions = function () {

this.exceptionHandlers = this.exceptionHandlers || {};
handlers.forEach(function (handler) {

@@ -491,25 +518,2 @@ self.exceptionHandlers[handler.name] = handler;

//
// ### function addRewriter (transport, [options])
// #### @transport {Transport} Prototype of the Transport object to add.
// #### @options {Object} **Optional** Options for the Transport to add.
// #### @instance {Boolean} **Optional** Value indicating if `transport` is already instantiated.
// Adds a transport of the specified type to this instance.
//
Logger.prototype.addRewriter = function (rewriter) {
this.rewriters.push(rewriter);
}
//
// ### function addFilter (filter)
// #### @filter {function} Filter function, called with the message and
// optional metadata as the two arguments.
// Expected to return either the filtered message or an object with properties:
// - msg = the filtered message string
// - meta = the filtered metadata object
//
Logger.prototype.addFilter = function (filter) {
this.filters.push(filter);
}
//
// ### function clear ()

@@ -519,5 +523,5 @@ // Remove all transports from this instance

Logger.prototype.clear = function () {
for (var name in this.transports) {
Object.keys(this.transports).forEach(function (name) {
this.remove({ name: name });
}
}, this);
};

@@ -553,22 +557,15 @@

var ProfileHandler = function (logger) {
this.logger = logger;
this.start = Date.now();
this.done = function (msg) {
var args, callback, meta;
args = Array.prototype.slice.call(arguments);
callback = typeof args[args.length - 1] === 'function' ? args.pop() : null;
meta = typeof args[args.length - 1] === 'object' ? args.pop() : {};
meta.durationMs = (Date.now()) - this.start;
return this.logger.info(msg, meta, callback);
}
}
//
// ### function startTimer ()
// Returns an object corresponding to a specific timing. When done
// is called the timer will finish and log the duration. e.g.:
//
// timer = winston.startTimer()
// setTimeout(function(){
// timer.done("Logging message");
// }, 1000);
//
Logger.prototype.startTimer = function () {
return new ProfileHandler(this);
}
};

@@ -716,1 +713,26 @@ //

};
//
// ### @private ProfileHandler
// Constructor function for the ProfileHandler instance used by
// `Logger.prototype.startTimer`. When done is called the timer
// will finish and log the duration.
//
function ProfileHandler(logger) {
this.logger = logger;
this.start = Date.now();
}
//
// ### function done (msg)
// Ends the current timer (i.e. ProfileHandler) instance and
// logs the `msg` along with the duration since creation.
//
ProfileHandler.prototype.done = function (msg) {
var args = Array.prototype.slice.call(arguments),
callback = typeof args[args.length - 1] === 'function' ? args.pop() : null,
meta = typeof args[args.length - 1] === 'object' ? args.pop() : {};
meta.duration = (Date.now()) - this.start + 'ms';
return this.logger.info(msg, meta, callback);
};

@@ -9,27 +9,22 @@ /*

var fs = require('fs'),
path = require('path'),
common = require('./common');
var path = require('path');
var transports = exports;
//
// Setup all transports as lazy-loaded getters.
//
fs.readdirSync(path.join(__dirname, 'transports')).forEach(function (file) {
var transport = file.replace('.js', ''),
name = common.capitalize(transport);
Object.defineProperties(
exports,
['Console', 'File', 'Http', 'Memory']
.reduce(function (acc, name) {
acc[name] = {
configurable: true,
enumerable: true,
get: function () {
var fullpath = path.join(__dirname, 'transports', name.toLowerCase());
return exports[name] = require(fullpath)[name];
}
};
if (transport === 'transport') {
return;
}
else if (~transport.indexOf('-')) {
name = transport.split('-').map(function (part) {
return common.capitalize(part);
}).join('');
}
transports.__defineGetter__(name, function () {
return require('./transports/' + transport)[name];
});
});
return acc;
}, {})
);

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

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

@@ -35,2 +36,3 @@ common = require('../common'),

this.stderrLevels = setStderrLevels(options.stderrLevels, options.debugStdout);
this.eol = options.eol || os.EOL;

@@ -121,3 +123,3 @@ if (this.json) {

} else {
process.stdout.write(output + '\n');
process.stdout.write(output + this.eol);
}

@@ -124,0 +126,0 @@

@@ -162,4 +162,7 @@ /*

humanReadableUnhandledException: this.humanReadableUnhandledException
}) + this.eol;
});
if (typeof output === 'string') {
output += this.eol;
}

@@ -166,0 +169,0 @@ if (!this.filename) {

{
"name": "winston",
"description": "A multi-transport async logging library for Node.js",
"version": "1.1.2",
"version": "2.0.0",
"author": "Charlie Robbins <charlie.robbins@gmail.com>",
"maintainers": [
"indexzero <charlie@nodejitsu.com>"
"Jarrett Cruger <jcrugzz@gmail.com>",
"Alberto Pose <albertopose@gmail.com>"
],

@@ -14,2 +15,3 @@ "repository": {

"keywords": [
"winston",
"logging",

@@ -16,0 +18,0 @@ "sysadmin",

@@ -41,3 +41,2 @@ # winston [![Build Status](https://secure.travis-ci.org/winstonjs/winston.svg?branch=master)](http://travis-ci.org/winstonjs/winston)

* [Using winston in a CLI tool](#using-winston-in-a-cli-tool)
* [Extending another object with Logging](#extending-another-object-with-logging)
* [Filters and Rewriters](#filters-and-rewriters)

@@ -51,2 +50,4 @@ * [Adding Custom Transports](#adding-custom-transports)

Logging levels in `winston` conform to the severity ordering specified by [RFC524](https://tools.ietf.org/html/rfc5424): _severity of all levels is assumed to be numerically **ascending** from most important to least important._
### Using the Default Logger

@@ -99,6 +100,31 @@ 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:

//
logger.add(winston.transports.File)
.remove(winston.transports.Console);
logger
.add(winston.transports.File)
.remove(winston.transports.Console);
```
You can also wholesale reconfigure a `winston.Logger` instance using the `configure` method:
``` js
var logger = new winston.Logger({
level: 'info',
transports: [
new (winston.transports.Console)(),
new (winston.transports.File)({ filename: 'somefile.log' })
]
});
//
// Replaces the previous transports with those in the
// new configuration wholesale.
//
logger.configure({
level: 'verbose',
transports: [
new require('winston-daily-rotate-file')(opts)
]
});
```
### Logging with Metadata

@@ -333,2 +359,16 @@ In addition to logging string messages, winston will also optionally log additional JSON metadata objects. Adding metadata is simple:

Each `level` is given a specific integer priority. The higher the priority the more important the message is considered to be, and the lower the corresponding integer priority. For example, `npm` logging levels are prioritized from 0 to 5 (highest to lowest):
``` js
{ error: 0, warn: 1, info: 2, verbose: 3, debug: 4, silly: 5 }
```
Similarly, as specified exactly in RFC524 the `syslog` levels are prioritized from 0 to 7 (highest to lowest).
```js
{ emerg: 0, alert: 1, crit: 2, error: 3, warning: 4, notice: 5, info: 6, debug: 7 }
```
If you do not explicitly define the levels that `winston` should use the `npm` levels above will be used.
### Using Logging Levels

@@ -358,3 +398,3 @@ 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.

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 (note that the default level of a transport is `info`):
`winston` allows you to define a `level` property on each transport which specifies the **maximum** level of messages that a transport should log. For example, using the `npm` levels you could log only `error` messages to the console and everything `info` and below to a file (which includes `error` messages):

@@ -365,3 +405,6 @@ ``` js

new (winston.transports.Console)({ level: 'error' }),
new (winston.transports.File)({ filename: 'somefile.log' })
new (winston.transports.File)({
filename: 'somefile.log',
level: 'info'
})
]

@@ -629,21 +672,18 @@ });

### Extending another object with Logging
Often in a given code base with lots of Loggers it is useful to add logging methods to a different object so that these methods can be called with less syntax. Winston exposes this functionality via the 'extend' method:
### Filters and Rewriters
Filters allow modifying the contents of **log messages**, and Rewriters allow modifying the contents of **log meta** e.g. to mask data that should not appear in logs.
Both filters and rewriters are simple Arrays of functions which can be provided when creating a `new winston.Logger(options)`. e.g.:
``` js
var myObject = {};
logger.extend(myObject);
//
// You can now call logger methods on 'myObject'
//
myObject.info("127.0.0.1 - there's no place like home");
var logger = new winston.Logger({
rewriters: [function (level, msg, meta) { /* etc etc */ }]
filters: [function (level, msg, meta) { /* etc etc */ }]
})
```
### Filters and Rewriters
Filters allow modifying the contents of **log messages**, and Rewriters allow modifying the contents of **log meta** e.g. to mask data that should not appear in logs.
Like any Array they can also be modified at runtime with no adverse side-effects to the `winston` internals.
``` js
logger.addFilter(function(msg, meta, level) {
logger.filters.push(function(level, msg, meta) {
return meta.production

@@ -666,3 +706,3 @@ ? maskCardNumbers(msg)

``` js
logger.addRewriter(function(level, msg, meta) {
logger.rewriters.push(function(level, msg, meta) {
if (meta.creditCard) {

@@ -669,0 +709,0 @@ meta.creditCard = maskCardNumbers(meta.creditCard)

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