| const flatted = require('flatted'); | |
| const levels = require('./levels'); | |
| /** | |
| * @name LoggingEvent | |
| * @namespace Log4js | |
| */ | |
| class LoggingEvent { | |
| /** | |
| * Models a logging event. | |
| * @constructor | |
| * @param {string} categoryName name of category | |
| * @param {Log4js.Level} level level of message | |
| * @param {Array} data objects to log | |
| * @author Seth Chisamore | |
| */ | |
| constructor(categoryName, level, data, context, location) { | |
| this.startTime = new Date(); | |
| this.categoryName = categoryName; | |
| this.data = data; | |
| this.level = level; | |
| this.context = Object.assign({}, context); // eslint-disable-line prefer-object-spread | |
| this.pid = process.pid; | |
| if (location) { | |
| this.functionName = location.functionName; | |
| this.fileName = location.fileName; | |
| this.lineNumber = location.lineNumber; | |
| this.columnNumber = location.columnNumber; | |
| this.callStack = location.callStack; | |
| } | |
| } | |
| serialise() { | |
| return flatted.stringify(this, (key, value) => { | |
| // JSON.stringify(new Error('test')) returns {}, which is not really useful for us. | |
| // The following allows us to serialize errors correctly. | |
| // duck-typing for Error object | |
| if (value && value.message && value.stack) { | |
| // eslint-disable-next-line prefer-object-spread | |
| value = Object.assign({message: value.message, stack: value.stack}, value); | |
| } | |
| // JSON.stringify({a: parseInt('abc'), b: 1/0, c: -1/0}) returns {a: null, b: null, c: null}. | |
| // The following allows us to serialize to NaN, Infinity and -Infinity correctly. | |
| else if (typeof value === 'number' && (Number.isNaN(value) || !Number.isFinite(value))) { | |
| value = value.toString(); | |
| } | |
| // JSON.stringify([undefined]) returns [null]. | |
| // The following allows us to serialize to undefined correctly. | |
| else if (typeof value === 'undefined') { | |
| value = typeof value; | |
| } | |
| return value; | |
| }); | |
| } | |
| static deserialise(serialised) { | |
| let event; | |
| try { | |
| const rehydratedEvent = flatted.parse(serialised, (key, value) => { | |
| if (value && value.message && value.stack) { | |
| const fakeError = new Error(value); | |
| Object.keys(value).forEach((k) => { fakeError[k] = value[k]; }); | |
| value = fakeError; | |
| } | |
| return value; | |
| }); | |
| rehydratedEvent.location = { | |
| functionName: rehydratedEvent.functionName, | |
| fileName: rehydratedEvent.fileName, | |
| lineNumber: rehydratedEvent.lineNumber, | |
| columnNumber: rehydratedEvent.columnNumber, | |
| callStack: rehydratedEvent.callStack | |
| }; | |
| event = new LoggingEvent( | |
| rehydratedEvent.categoryName, | |
| levels.getLevel(rehydratedEvent.level.levelStr), | |
| rehydratedEvent.data, | |
| rehydratedEvent.context, | |
| rehydratedEvent.location | |
| ); | |
| event.startTime = new Date(rehydratedEvent.startTime); | |
| event.pid = rehydratedEvent.pid; | |
| event.cluster = rehydratedEvent.cluster; | |
| } catch (e) { | |
| event = new LoggingEvent( | |
| 'log4js', | |
| levels.ERROR, | |
| ['Unable to parse log:', serialised, 'because: ', e] | |
| ); | |
| } | |
| return event; | |
| } | |
| } | |
| module.exports = LoggingEvent; |