exclude domain keys on error objects for 'err' serializer
This commit is contained in:
parent
b2438ddb2c
commit
f096b303c1
6 changed files with 52 additions and 39 deletions
10
CHANGES.md
10
CHANGES.md
|
@ -8,7 +8,15 @@ Known issues:
|
||||||
|
|
||||||
## bunyan 0.18.3 (not yet released)
|
## bunyan 0.18.3 (not yet released)
|
||||||
|
|
||||||
(nothing yet)
|
- Change the `bunyan.stdSerializers.err` serializer for errors to *exclude*
|
||||||
|
[the "domain*" keys](http://nodejs.org/docs/latest/api/all.html#all_additions_to_error_objects).
|
||||||
|
`err.domain` will include its assigned members which can arbitrarily large
|
||||||
|
objects that are not intended for logging.
|
||||||
|
|
||||||
|
- Make the "dtrace-provider" dependency optional. I hate to do this, but
|
||||||
|
installing bunyan on Windows is made very difficult with this as a required
|
||||||
|
dep. Even though "dtrace-provider" stubs out for non-dtrace-y platforms,
|
||||||
|
without a compiler and Python around, node-gyp just falls over.
|
||||||
|
|
||||||
|
|
||||||
## bunyan 0.18.2
|
## bunyan 0.18.2
|
||||||
|
|
1
TODO.md
1
TODO.md
|
@ -1,3 +1,4 @@
|
||||||
|
- upgrade to dtrace-provider@0.2.8 when it comes for 0.9 compat
|
||||||
- man page for the bunyan CLI (refer to it in the readme)
|
- man page for the bunyan CLI (refer to it in the readme)
|
||||||
- `tail -f`-like support
|
- `tail -f`-like support
|
||||||
- 1.0 with `v: 1` in log records. Fwd/bwd compat in `bunyan` CLI
|
- 1.0 with `v: 1` in log records. Fwd/bwd compat in `bunyan` CLI
|
||||||
|
|
|
@ -786,8 +786,10 @@ function emitRecord(rec, line, opts, stylize) {
|
||||||
client_req.url,
|
client_req.url,
|
||||||
client_req.httpVersion || "1.1",
|
client_req.httpVersion || "1.1",
|
||||||
hostHeaderLine,
|
hostHeaderLine,
|
||||||
Object.keys(headers).map(
|
(headers
|
||||||
function (h) { return h + ': ' + headers[h]; }).join('\n'));
|
? Object.keys(headers).map(
|
||||||
|
function (h) { return h + ': ' + headers[h]; }).join('\n')
|
||||||
|
: ''));
|
||||||
delete client_req.method;
|
delete client_req.method;
|
||||||
delete client_req.url;
|
delete client_req.url;
|
||||||
delete client_req.httpVersion;
|
delete client_req.httpVersion;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 Trent Mick. All rights reserved.
|
* Copyright (c) 2013 Trent Mick. All rights reserved.
|
||||||
*
|
*
|
||||||
* The bunyan logging library for node.js.
|
* The bunyan logging library for node.js.
|
||||||
*/
|
*/
|
||||||
|
@ -627,26 +627,18 @@ Logger.prototype.levels = function levels(name, value) {
|
||||||
* Pre-condition: This is only called if there is at least one serializer.
|
* Pre-condition: This is only called if there is at least one serializer.
|
||||||
*
|
*
|
||||||
* @param fields (Object) The log record fields.
|
* @param fields (Object) The log record fields.
|
||||||
* @param keys (Array) Optional array of keys to which to limit processing.
|
* @param excludeFields (Object) Optional mapping of keys to `true` for
|
||||||
|
* keys to NOT apply a serializer.
|
||||||
*/
|
*/
|
||||||
Logger.prototype._applySerializers = function (fields, keys) {
|
Logger.prototype._applySerializers = function (fields, excludeFields) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// Mapping of keys to potentially serialize.
|
xxx('_applySerializers: excludeFields', excludeFields);
|
||||||
var applyKeys = fields;
|
|
||||||
if (keys) {
|
|
||||||
applyKeys = {};
|
|
||||||
for (var i = 0; i < keys.length; i++) {
|
|
||||||
applyKeys[keys[i]] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xxx('_applySerializers: applyKeys', applyKeys);
|
|
||||||
|
|
||||||
// Check each serializer against these (presuming number of serializers
|
// Check each serializer against these (presuming number of serializers
|
||||||
// is typically less than number of fields).
|
// is typically less than number of fields).
|
||||||
Object.keys(this.serializers).forEach(function (name) {
|
Object.keys(this.serializers).forEach(function (name) {
|
||||||
if (applyKeys[name]) {
|
if (!excludeFields || !excludeFields[name]) {
|
||||||
xxx('_applySerializers; apply to "%s" key', name)
|
xxx('_applySerializers; apply to "%s" key', name)
|
||||||
try {
|
try {
|
||||||
fields[name] = self.serializers[name](fields[name]);
|
fields[name] = self.serializers[name](fields[name]);
|
||||||
|
@ -732,9 +724,11 @@ function mkLogEmitter(minLevel) {
|
||||||
var log = this;
|
var log = this;
|
||||||
|
|
||||||
function mkRecord(args) {
|
function mkRecord(args) {
|
||||||
|
var excludeFields;
|
||||||
if (args[0] instanceof Error) {
|
if (args[0] instanceof Error) {
|
||||||
// `log.<level>(err, ...)`
|
// `log.<level>(err, ...)`
|
||||||
fields = {err: errSerializer(args[0])};
|
fields = {err: errSerializer(args[0])};
|
||||||
|
excludeFields = {err: true};
|
||||||
if (args.length === 1) {
|
if (args.length === 1) {
|
||||||
msgArgs = [fields.err.message];
|
msgArgs = [fields.err.message];
|
||||||
} else {
|
} else {
|
||||||
|
@ -759,7 +753,7 @@ function mkLogEmitter(minLevel) {
|
||||||
var recFields = (fields ? objCopy(fields) : null);
|
var recFields = (fields ? objCopy(fields) : null);
|
||||||
if (recFields) {
|
if (recFields) {
|
||||||
if (log.serializers) {
|
if (log.serializers) {
|
||||||
log._applySerializers(recFields);
|
log._applySerializers(recFields, excludeFields);
|
||||||
}
|
}
|
||||||
Object.keys(recFields).forEach(function (k) {
|
Object.keys(recFields).forEach(function (k) {
|
||||||
rec[k] = recFields[k];
|
rec[k] = recFields[k];
|
||||||
|
@ -885,6 +879,14 @@ function getFullErrorStack(ex)
|
||||||
|
|
||||||
// Serialize an Error object
|
// Serialize an Error object
|
||||||
// (Core error properties are enumerable in node 0.4, not in 0.6).
|
// (Core error properties are enumerable in node 0.4, not in 0.6).
|
||||||
|
var errSkips = {
|
||||||
|
// Skip domain keys. `domain` especially can have huge objects that can
|
||||||
|
// OOM your app when trying to JSON.stringify.
|
||||||
|
domain: true,
|
||||||
|
domain_emitter: true,
|
||||||
|
domain_bound: true,
|
||||||
|
domain_thrown: true
|
||||||
|
};
|
||||||
var errSerializer = Logger.stdSerializers.err = function err(err) {
|
var errSerializer = Logger.stdSerializers.err = function err(err) {
|
||||||
if (!err || !err.stack)
|
if (!err || !err.stack)
|
||||||
return err;
|
return err;
|
||||||
|
@ -894,7 +896,7 @@ var errSerializer = Logger.stdSerializers.err = function err(err) {
|
||||||
stack: getFullErrorStack(err)
|
stack: getFullErrorStack(err)
|
||||||
}
|
}
|
||||||
Object.keys(err).forEach(function (k) {
|
Object.keys(err).forEach(function (k) {
|
||||||
if (err[k] !== undefined) {
|
if (err[k] !== undefined && !errSkips[k]) {
|
||||||
obj[k] = err[k];
|
obj[k] = err[k];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
"keywords": ["log", "logging", "log4j", "json"],
|
"keywords": ["log", "logging", "log4j", "json"],
|
||||||
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dtrace-provider": "0.2.7"
|
|
||||||
},
|
},
|
||||||
"// comment": "'mv' required for RotatingFileStream",
|
"// comment": "'mv' required for RotatingFileStream",
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"mv": "0.0.4"
|
"mv": "0.0.4",
|
||||||
|
"dtrace-provider": "0.2.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"nodeunit": "0.7.4",
|
"nodeunit": "0.7.4",
|
||||||
|
|
|
@ -198,37 +198,37 @@ test('err serializer: long stack', function (t) {
|
||||||
topErr = new verror.VError('top err');
|
topErr = new verror.VError('top err');
|
||||||
log.info(topErr, 'the error');
|
log.info(topErr, 'the error');
|
||||||
var lastRecord = records[records.length-1];
|
var lastRecord = records[records.length-1];
|
||||||
t.equal(lastRecord.err.message, topErr.message);
|
t.equal(lastRecord.err.message, topErr.message, 'Just a VError');
|
||||||
t.equal(lastRecord.err.name, topErr.name);
|
t.equal(lastRecord.err.name, topErr.name, 'Just a VError');
|
||||||
t.equal(lastRecord.err.stack, topErr.stack);
|
t.equal(lastRecord.err.stack, topErr.stack, 'Just a VError');
|
||||||
|
|
||||||
// Just a WError.
|
// Just a WError.
|
||||||
topErr = new verror.WError('top err');
|
topErr = new verror.WError('top err');
|
||||||
log.info(topErr, 'the error');
|
log.info(topErr, 'the error');
|
||||||
var lastRecord = records[records.length-1];
|
var lastRecord = records[records.length-1];
|
||||||
t.equal(lastRecord.err.message, topErr.message);
|
t.equal(lastRecord.err.message, topErr.message, 'Just a WError');
|
||||||
t.equal(lastRecord.err.name, topErr.name);
|
t.equal(lastRecord.err.name, topErr.name, 'Just a WError');
|
||||||
t.equal(lastRecord.err.stack, topErr.stack);
|
t.equal(lastRecord.err.stack, topErr.stack, 'Just a WError');
|
||||||
|
|
||||||
// WError <- TypeError
|
// WError <- TypeError
|
||||||
bottomErr = new TypeError('bottom err');
|
bottomErr = new TypeError('bottom err');
|
||||||
topErr = new verror.WError(bottomErr, 'top err');
|
topErr = new verror.WError(bottomErr, 'top err');
|
||||||
log.info(topErr, 'the error');
|
log.info(topErr, 'the error');
|
||||||
var lastRecord = records[records.length-1];
|
var lastRecord = records[records.length-1];
|
||||||
t.equal(lastRecord.err.message, topErr.message);
|
t.equal(lastRecord.err.message, topErr.message, 'WError <- TypeError');
|
||||||
t.equal(lastRecord.err.name, topErr.name);
|
t.equal(lastRecord.err.name, topErr.name, 'WError <- TypeError');
|
||||||
var expectedStack = topErr.stack + '\nCaused by: ' + bottomErr.stack;
|
var expectedStack = topErr.stack + '\nCaused by: ' + bottomErr.stack;
|
||||||
t.equal(lastRecord.err.stack, expectedStack);
|
t.equal(lastRecord.err.stack, expectedStack, 'WError <- TypeError');
|
||||||
|
|
||||||
// WError <- WError
|
// WError <- WError
|
||||||
bottomErr = new verror.WError('bottom err');
|
bottomErr = new verror.WError('bottom err');
|
||||||
topErr = new verror.WError(bottomErr, 'top err');
|
topErr = new verror.WError(bottomErr, 'top err');
|
||||||
log.info(topErr, 'the error');
|
log.info(topErr, 'the error');
|
||||||
var lastRecord = records[records.length-1];
|
var lastRecord = records[records.length-1];
|
||||||
t.equal(lastRecord.err.message, topErr.message);
|
t.equal(lastRecord.err.message, topErr.message, 'WError <- WError');
|
||||||
t.equal(lastRecord.err.name, topErr.name);
|
t.equal(lastRecord.err.name, topErr.name, 'WError <- WError');
|
||||||
var expectedStack = topErr.stack + '\nCaused by: ' + bottomErr.stack;
|
var expectedStack = topErr.stack + '\nCaused by: ' + bottomErr.stack;
|
||||||
t.equal(lastRecord.err.stack, expectedStack);
|
t.equal(lastRecord.err.stack, expectedStack, 'WError <- WError');
|
||||||
|
|
||||||
// WError <- WError <- TypeError
|
// WError <- WError <- TypeError
|
||||||
bottomErr = new TypeError('bottom err');
|
bottomErr = new TypeError('bottom err');
|
||||||
|
@ -236,12 +236,12 @@ test('err serializer: long stack', function (t) {
|
||||||
topErr = new verror.WError(midErr, 'top err');
|
topErr = new verror.WError(midErr, 'top err');
|
||||||
log.info(topErr, 'the error');
|
log.info(topErr, 'the error');
|
||||||
var lastRecord = records[records.length-1];
|
var lastRecord = records[records.length-1];
|
||||||
t.equal(lastRecord.err.message, topErr.message);
|
t.equal(lastRecord.err.message, topErr.message, 'WError <- WError <- TypeError');
|
||||||
t.equal(lastRecord.err.name, topErr.name);
|
t.equal(lastRecord.err.name, topErr.name, 'WError <- WError <- TypeError');
|
||||||
var expectedStack = (topErr.stack
|
var expectedStack = (topErr.stack
|
||||||
+ '\nCaused by: ' + midErr.stack
|
+ '\nCaused by: ' + midErr.stack
|
||||||
+ '\nCaused by: ' + bottomErr.stack);
|
+ '\nCaused by: ' + bottomErr.stack);
|
||||||
t.equal(lastRecord.err.stack, expectedStack);
|
t.equal(lastRecord.err.stack, expectedStack, 'WError <- WError <- TypeError');
|
||||||
|
|
||||||
// WError <- WError <- WError
|
// WError <- WError <- WError
|
||||||
bottomErr = new verror.WError('bottom err');
|
bottomErr = new verror.WError('bottom err');
|
||||||
|
@ -249,12 +249,12 @@ test('err serializer: long stack', function (t) {
|
||||||
topErr = new verror.WError(midErr, 'top err');
|
topErr = new verror.WError(midErr, 'top err');
|
||||||
log.info(topErr, 'the error');
|
log.info(topErr, 'the error');
|
||||||
var lastRecord = records[records.length-1];
|
var lastRecord = records[records.length-1];
|
||||||
t.equal(lastRecord.err.message, topErr.message);
|
t.equal(lastRecord.err.message, topErr.message, 'WError <- WError <- WError');
|
||||||
t.equal(lastRecord.err.name, topErr.name);
|
t.equal(lastRecord.err.name, topErr.name, 'WError <- WError <- WError');
|
||||||
var expectedStack = (topErr.stack
|
var expectedStack = (topErr.stack
|
||||||
+ '\nCaused by: ' + midErr.stack
|
+ '\nCaused by: ' + midErr.stack
|
||||||
+ '\nCaused by: ' + bottomErr.stack);
|
+ '\nCaused by: ' + bottomErr.stack);
|
||||||
t.equal(lastRecord.err.stack, expectedStack);
|
t.equal(lastRecord.err.stack, expectedStack, 'WError <- WError <- WError');
|
||||||
|
|
||||||
|
|
||||||
t.end();
|
t.end();
|
||||||
|
|
Loading…
Reference in a new issue