-
Notifications
You must be signed in to change notification settings - Fork 775
/
LoggingEvent.js
127 lines (121 loc) · 3.95 KB
/
LoggingEvent.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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
* @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 (location) {
this.fileName = location.fileName;
this.lineNumber = location.lineNumber;
this.columnNumber = location.columnNumber;
this.callStack = location.callStack;
this.className = location.className;
this.functionName = location.functionName;
this.functionAlias = location.functionAlias;
this.callerName = location.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: 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;
});
if (
rehydratedEvent.fileName ||
rehydratedEvent.lineNumber ||
rehydratedEvent.columnNumber ||
rehydratedEvent.callStack ||
rehydratedEvent.className ||
rehydratedEvent.functionName ||
rehydratedEvent.functionAlias ||
rehydratedEvent.callerName
) {
rehydratedEvent.location = {
fileName: rehydratedEvent.fileName,
lineNumber: rehydratedEvent.lineNumber,
columnNumber: rehydratedEvent.columnNumber,
callStack: rehydratedEvent.callStack,
className: rehydratedEvent.className,
functionName: rehydratedEvent.functionName,
functionAlias: rehydratedEvent.functionAlias,
callerName: rehydratedEvent.callerName,
};
}
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;