diff --git a/lib/loggly/common.js b/lib/loggly/common.js index 633f715..361c890 100644 --- a/lib/loggly/common.js +++ b/lib/loggly/common.js @@ -148,10 +148,18 @@ common.loggly = function () { // ### function serialize (obj, key) // #### @obj {Object|literal} Object to serialize // #### @key {string} **Optional** Optional key represented by obj in a larger object +// #### @stack {Array} **Optional** Internal array used to avoid cycles // Performs simple comma-separated, `key=value` serialization for Loggly when // logging for non-JSON values. // -common.serialize = function (obj, key) { +common.serialize = function (obj, key, stack) { + if (stack && stack.includes(obj)) { + return (key ? key + '=' : '') + ''; + } + + var updatedStack = stack ? stack.slice() : []; + updatedStack.unshift(obj); + if (obj === null) { obj = 'null'; } @@ -175,7 +183,7 @@ common.serialize = function (obj, key) { msg += keys[i] + '=['; for (var j = 0, l = obj[keys[i]].length; j < l; j++) { - msg += common.serialize(obj[keys[i]][j]); + msg += common.serialize(obj[keys[i]][j], null, updatedStack); if (j < l - 1) { msg += ', '; } @@ -184,7 +192,7 @@ common.serialize = function (obj, key) { msg += ']'; } else { - msg += common.serialize(obj[keys[i]], keys[i]); + msg += common.serialize(obj[keys[i]], keys[i], updatedStack); } if (i < length - 1) { diff --git a/test/common-test.js b/test/common-test.js index ac5d3f4..76dfcc0 100644 --- a/test/common-test.js +++ b/test/common-test.js @@ -27,6 +27,20 @@ vows.describe('node-loggly/common').addBatch({ "should return a deep clone of the object": function (clone) { assert.isFalse(this.obj.deep === clone.deep); } + }, + + "the serialize() method": { + topic: function () { + this.obj = { + name: 'cyclical', + }; + + this.obj.cycle = this.obj; + return common.serialize(this.obj); + }, + "should handle objects containing cyclical references": function (serialized) { + assert.equal("name=cyclical, cycle=", serialized); + } } } }).export(module); \ No newline at end of file