Merge pull request #138 from andreineculau/patch-1

fix #105: export addStream and addSerializers
This commit is contained in:
Trent Mick 2014-08-25 00:30:16 -07:00
commit eaa88a74b6

View file

@ -338,107 +338,25 @@ function Logger(options, _childOptions, _childSimple) {
} }
// Helpers // Helpers
function addStream(s) {
s = objCopy(s);
// Implicit 'type' from other args.
var type = s.type;
if (!s.type) {
if (s.stream) {
s.type = 'stream';
} else if (s.path) {
s.type = 'file'
}
}
s.raw = (s.type === 'raw'); // PERF: Allow for faster check in `_emit`.
if (s.level) {
s.level = resolveLevel(s.level);
} else if (options.level) {
s.level = resolveLevel(options.level);
} else {
s.level = INFO;
}
if (s.level < self._level) {
self._level = s.level;
}
switch (s.type) {
case 'stream':
if (!s.closeOnExit) {
s.closeOnExit = false;
}
break;
case 'file':
if (!s.stream) {
s.stream = fs.createWriteStream(s.path,
{flags: 'a', encoding: 'utf8'});
s.stream.on('error', function (err) {
self.emit('error', err, s);
});
if (!s.closeOnExit) {
s.closeOnExit = true;
}
} else {
if (!s.closeOnExit) {
s.closeOnExit = false;
}
}
break;
case 'rotating-file':
assert.ok(!s.stream,
'"rotating-file" stream should not give a "stream"');
assert.ok(s.path);
assert.ok(mv, '"rotating-file" stream type is not supported: '
+ 'missing "mv" module');
s.stream = new RotatingFileStream(s);
if (!s.closeOnExit) {
s.closeOnExit = true;
}
break;
case 'raw':
if (!s.closeOnExit) {
s.closeOnExit = false;
}
break;
default:
throw new TypeError('unknown stream type "' + s.type + '"');
}
self.streams.push(s);
}
function addSerializers(serializers) {
if (!self.serializers) {
self.serializers = {};
}
Object.keys(serializers).forEach(function (field) {
var serializer = serializers[field];
if (typeof (serializer) !== 'function') {
throw new TypeError(format(
'invalid serializer for "%s" field: must be a function',
field));
} else {
self.serializers[field] = serializer;
}
});
}
// Handle *config* options (i.e. options that are not just plain data // Handle *config* options (i.e. options that are not just plain data
// for log records). // for log records).
if (options.stream) { if (options.stream) {
addStream({ self.addStream({
type: 'stream', type: 'stream',
stream: options.stream, stream: options.stream,
closeOnExit: false, closeOnExit: false,
level: (options.level ? resolveLevel(options.level) : INFO) level: (options.level ? resolveLevel(options.level) : INFO)
}); });
} else if (options.streams) { } else if (options.streams) {
options.streams.forEach(addStream); options.streams.forEach(function(s) {
s.level = s.level || s.level;
self.addStream(s);
});
} else if (parent && options.level) { } else if (parent && options.level) {
this.level(options.level); this.level(options.level);
} else if (!parent) { } else if (!parent) {
addStream({ self.addStream({
type: 'stream', type: 'stream',
stream: process.stdout, stream: process.stdout,
closeOnExit: false, closeOnExit: false,
@ -446,7 +364,7 @@ function Logger(options, _childOptions, _childSimple) {
}); });
} }
if (options.serializers) { if (options.serializers) {
addSerializers(options.serializers); self.addSerializers(options.serializers);
} }
if (options.src) { if (options.src) {
this.src = true; this.src = true;
@ -481,6 +399,118 @@ function Logger(options, _childOptions, _childSimple) {
util.inherits(Logger, EventEmitter); util.inherits(Logger, EventEmitter);
/**
* Add a stream
*
* @param stream {Object}. Object with these fields:
* - `type`: The stream type. See README.md for full details.
* Often this is implied by the other fields. Examples are
* 'file', 'stream' and "raw".
* - `level`: Defaults to 'info'.
* - `path` or `stream`: The specify the file path or writeable
* stream to which log records are written. E.g.
* `stream: process.stdout`.
* - `closeOnExit` (boolean): Optional. Default is true for a
* 'file' stream when `path` is given, false otherwise.
* See README.md for full details.
*/
Logger.prototype.addStream = function(s) {
var self = this;
s = objCopy(s);
// Implicit 'type' from other args.
var type = s.type;
if (!s.type) {
if (s.stream) {
s.type = 'stream';
} else if (s.path) {
s.type = 'file'
}
}
s.raw = (s.type === 'raw'); // PERF: Allow for faster check in `_emit`.
if (s.level) {
s.level = resolveLevel(s.level);
} else {
s.level = INFO;
}
if (s.level < self._level) {
self._level = s.level;
}
switch (s.type) {
case 'stream':
if (!s.closeOnExit) {
s.closeOnExit = false;
}
break;
case 'file':
if (!s.stream) {
s.stream = fs.createWriteStream(s.path,
{flags: 'a', encoding: 'utf8'});
s.stream.on('error', function (err) {
self.emit('error', err, s);
});
if (!s.closeOnExit) {
s.closeOnExit = true;
}
} else {
if (!s.closeOnExit) {
s.closeOnExit = false;
}
}
break;
case 'rotating-file':
assert.ok(!s.stream,
'"rotating-file" stream should not give a "stream"');
assert.ok(s.path);
assert.ok(mv, '"rotating-file" stream type is not supported: '
+ 'missing "mv" module');
s.stream = new RotatingFileStream(s);
if (!s.closeOnExit) {
s.closeOnExit = true;
}
break;
case 'raw':
if (!s.closeOnExit) {
s.closeOnExit = false;
}
break;
default:
throw new TypeError('unknown stream type "' + s.type + '"');
}
self.streams.push(s);
}
/**
* Add serializers
*
* @param serializers {Object} Optional. Object mapping log record field names to
* serializing functions. See README.md for details.
*/
Logger.prototype.addSerializers = function(serializers) {
var self = this;
if (!self.serializers) {
self.serializers = {};
}
Object.keys(serializers).forEach(function (field) {
var serializer = serializers[field];
if (typeof (serializer) !== 'function') {
throw new TypeError(format(
'invalid serializer for "%s" field: must be a function',
field));
} else {
self.serializers[field] = serializer;
}
});
}
/** /**
* Create a child logger, typically to add a few log record fields. * Create a child logger, typically to add a few log record fields.
* *