X-Git-Url: http://git.squeep.com/?p=squeep-logger-json-console;a=blobdiff_plain;f=lib%2Flogger.js;fp=lib%2Flogger.js;h=e11810e1d312b5efa36478b418a5bdf25c27a728;hp=d5a0c908dae0f417832cbf0fb6864d3c0f34160c;hb=8f067f063e2410dd72bcd51aee69b273b1915c25;hpb=9d6fc078e27013cbb94836d7a9c3a39ba30d216b diff --git a/lib/logger.js b/lib/logger.js index d5a0c90..e11810e 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -90,14 +90,16 @@ class Logger { * @returns {String} JSON string */ payload(level, scope, message, data, ...other) { + const replacer = this.getReplacer(); + if (this.sanitizationNeeded(data)) { // Create copy of data so we are not changing anything important. - data = JSON.parse(JSON.stringify(data, this.jsonReplacer.bind(this))); + data = structuredClone(data, replacer); this.sanitize(data); } const now = new Date(); - return JSON.stringify({ + const logPayload = { ...this.commonObject, timestamp: now.toISOString(), timestampMs: now.getTime(), @@ -107,7 +109,8 @@ class Logger { data: data || {}, ...(other.length && { other }), ...this.asyncLogObject, - }, this.jsonReplacer.bind(this)); + }; + return JSON.stringify(logPayload, replacer); } @@ -131,20 +134,31 @@ class Logger { /** - * Convert data into JSON. - * @param {String} _key - * @param {*} value - * @returns {String} serialized value + * Return a replacer function which does de-cycling, as well as the rest of our replacers. */ - jsonReplacer(key, value) { - let replaced; - - // Try applying all our replacers, until one does something. - this.jsonReplacers.every((replacer) => { - ({ replaced, value } = replacer(key, value)); - return !replaced; - }); - return value; + getReplacer() { + const ancestors = []; + const loggerReplacers = this.jsonReplacers; + return function cycleReplacer(key, value) { + if (typeof value === 'object' && value !== null) { + // this is object where key/value came from + while (ancestors.length > 0 && ancestors.at(-1) !== this) { + ancestors.pop(); + } + if (ancestors.includes(value)) { // eslint-disable-line security/detect-object-injection + return '[Circular]'; + } else { + ancestors.push(value); + } + } + + loggerReplacers.every((replacer) => { + const oldValue = value; + value = replacer(key, value); + return oldValue === value; + }); + return value; + } } }