Skip to content

Commit

Permalink
[api] Allow for transports to be removed by their string name
Browse files Browse the repository at this point in the history
[test fix] Add test coverage for multiple transports of the same type added in #187.
[doc] Document using multiple transports of the same type

Fixes #101 (again), Fixes #301
  • Loading branch information
indexzero committed Jan 6, 2015
1 parent 4084617 commit 270be86
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 16 deletions.
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ There are two different ways to use winston: directly via the default logger, or
* [Using the Default Logger](#using-the-default-logger)
* [Instantiating your own Logger](#instantiating-your-own-logger)
* [Logging with Metadata](#logging-with-metadata)
* [String interpolation ](#string-interpolation)
* [String interpolation](#string-interpolation)
* [Transports](https://github.com/flatiron/winston/blob/master/docs/transports.md)
* [Multiple transports of the same type](#multiple-transports-of-the-same-type)
* [Profiling](#profiling)
* [Streaming Logs](#streaming-logs)
* [Querying Logs](#querying-logs)
Expand Down Expand Up @@ -104,6 +105,41 @@ The way these objects are stored varies from transport to transport (to best sup
1. __Console:__ Logged via util.inspect(meta)
2. __File:__ Logged via util.inspect(meta)

## Multiple transports of the same type

It is possible to use multiple transports of the same type e.g. `winston.transports.File` by passing in a custom `name` when you construct the transport.

``` js
var logger = new (winston.Logger)({
transports: [
new (winston.transports.File)({
name: 'info-file',
filename: 'filelog-info.log',
level: 'info'
}),
new (winston.transports.File)({
name: 'error-file',
filename: 'filelog-error.log',
level: 'error'
})
]
});
```

If you later want to remove one of these transports you can do so by using the string name. e.g.:

``` js
logger.remove('info-file');
```

In this example one could also remove by passing in the instance of the Transport itself. e.g. this is equivalent to the string example above;

```
// Notice it was first in the Array above
var infoFile = logger.transports[0];
logger.remove(infoFile);
```

## Profiling
In addition to logging messages and metadata, winston also has a simple profiling mechanism implemented for any logger:

Expand Down
8 changes: 5 additions & 3 deletions lib/winston/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ Logger.prototype.log = function (level) {
}
}


if (Object.keys(this.transports).length === 0) {
return onError(new Error('Cannot log with no transports.'));
}
Expand Down Expand Up @@ -484,11 +484,13 @@ Logger.prototype.clear = function () {

//
// ### function remove (transport)
// #### @transport {Transport} Transport to remove.
// #### @transport {Transport|String} Transport or Name to remove.
// Removes a transport of the specified type from this instance.
//
Logger.prototype.remove = function (transport) {
var name = transport.name || transport.prototype.name;
var name = typeof transport !== 'string'
? transport.name || transport.prototype.name
: transport;

if (!this.transports[name]) {
throw new Error('Transport ' + name + ' not attached to this instance');
Expand Down
12 changes: 6 additions & 6 deletions lib/winston/transports/transport.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ var events = require('events'),
var Transport = exports.Transport = function (options) {
events.EventEmitter.call(this);

options = options || {};
this.level = options.level === undefined ? 'info' : options.level;
this.silent = options.silent || false;
this.raw = options.raw || false;
this.name = options.name || this.name;
options = options || {};
this.level = options.level === undefined ? 'info' : options.level;
this.silent = options.silent || false;
this.raw = options.raw || false;
this.name = options.name || this.name;

this.handleExceptions = options.handleExceptions || false;
this.exceptionsLevel = options.exceptionsLevel || 'error';
this.exceptionsLevel = options.exceptionsLevel || 'error';
};

//
Expand Down
32 changes: 26 additions & 6 deletions test/logger-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,14 +381,34 @@ vows.describe('winton/logger').addBatch({
}
}).addBatch({
"Building a logger with two file transports": {
topic: function() { new (winston.Logger)({
topic: new (winston.Logger)({
transports: [
new (winston.transports.File)({ filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-info.log' ), level: 'info'}),
new (winston.transports.File)({ filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-error.log' ), level: 'error'})
new (winston.transports.File)({
name: 'filelog-info.log',
filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-info.log'),
level: 'info'
}),
new (winston.transports.File)({
name: 'filelog-error.log',
filename: path.join(__dirname, 'fixtures', 'logs', 'filelog-error.log'),
level: 'error'
})
]
})},
"should not throw an exception": function (f) {
assert.doesNotThrow(f, Error)
}),
"should respond with a proper logger": function (logger) {
assert.include(logger._names, 'filelog-info.log');
assert.include(logger._names, 'filelog-error.log');
assert.lengthOf(logger.transports, 2);
},
"when one is removed": {
topic: function (logger) {
logger.remove('filelog-error.log');
return logger;
},
"should only have one transport": function (logger) {
assert.include(logger._names, 'filelog-info.log');
assert.lengthOf(logger.transports, 1);
}
}
}
}).export(module);

0 comments on commit 270be86

Please sign in to comment.