123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- /* eslint max-classes-per-file: ["error", 2] */
- /* eslint no-underscore-dangle: ["error", { "allow": ["_getLocationKeys"] }] */
- const flatted = require('flatted');
- const levels = require('./levels');
- class SerDe {
- constructor() {
- const deserialise = {
- __LOG4JS_undefined__: undefined,
- __LOG4JS_NaN__: Number('abc'),
- __LOG4JS_Infinity__: 1 / 0,
- '__LOG4JS_-Infinity__': -1 / 0,
- };
- this.deMap = deserialise;
- this.serMap = {};
- Object.keys(this.deMap).forEach((key) => {
- const value = this.deMap[key];
- this.serMap[value] = key;
- });
- }
- canSerialise(key) {
- if (typeof key === 'string') return false;
- return key in this.serMap;
- }
- serialise(key) {
- if (this.canSerialise(key)) return this.serMap[key];
- return key;
- }
- canDeserialise(key) {
- return key in this.deMap;
- }
- deserialise(key) {
- if (this.canDeserialise(key)) return this.deMap[key];
- return key;
- }
- }
- const serde = new SerDe();
- /**
- * @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
- * @param {Error} [error]
- * @author Seth Chisamore
- */
- constructor(categoryName, level, data, context, location, error) {
- 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;
- this.error = error;
- if (typeof location !== 'undefined') {
- if (!location || typeof location !== 'object' || Array.isArray(location))
- throw new TypeError(
- 'Invalid location type passed to LoggingEvent constructor'
- );
- this.constructor._getLocationKeys().forEach((key) => {
- if (typeof location[key] !== 'undefined') this[key] = location[key];
- });
- }
- }
- /** @private */
- static _getLocationKeys() {
- return [
- 'fileName',
- 'lineNumber',
- 'columnNumber',
- 'callStack',
- 'className',
- 'functionName',
- 'functionAlias',
- 'callerName',
- ];
- }
- 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 (semi) correctly.
- if (value instanceof Error) {
- // eslint-disable-next-line prefer-object-spread
- value = Object.assign(
- { message: value.message, stack: value.stack },
- value
- );
- }
- // JSON.stringify({a: Number('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.
- // JSON.stringify([undefined]) returns [null].
- // The following allows us to serialize to undefined correctly.
- return serde.serialise(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 serde.deserialise(value);
- });
- this._getLocationKeys().forEach((key) => {
- if (typeof rehydratedEvent[key] !== 'undefined') {
- if (!rehydratedEvent.location) rehydratedEvent.location = {};
- rehydratedEvent.location[key] = rehydratedEvent[key];
- }
- });
- event = new LoggingEvent(
- rehydratedEvent.categoryName,
- levels.getLevel(rehydratedEvent.level.levelStr),
- rehydratedEvent.data,
- rehydratedEvent.context,
- rehydratedEvent.location,
- rehydratedEvent.error
- );
- event.startTime = new Date(rehydratedEvent.startTime);
- event.pid = rehydratedEvent.pid;
- if (rehydratedEvent.cluster) {
- event.cluster = rehydratedEvent.cluster;
- }
- } catch (e) {
- event = new LoggingEvent('log4js', levels.ERROR, [
- 'Unable to parse log:',
- serialised,
- 'because: ',
- e,
- ]);
- }
- return event;
- }
- }
- module.exports = LoggingEvent;
|