forked from mui/material-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlog.js
146 lines (127 loc) · 3.66 KB
/
log.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* eslint-disable no-console */
// https://github.com/trentm/node-bunyan#levels
const logTypes = {
// Detail on regular operation.
info: { level: 3, method: 'log' },
// A note on something that should probably be looked at by an operator eventually.
warn: { level: 4, method: 'warn' },
// Fatal for a particular request, but the service/app continues servicing other requests.
// An operator should look at this soon(ish).
error: { level: 5, method: 'error' },
// The service/app is going to stop or become unusable now.
// An operator should definitely look into this soon.
fatal: { level: 6, method: 'error' },
};
function serializeErr(msg) {
if (!msg.err.stack) {
return msg.err;
}
return {
...msg,
err: {
message: msg.err.message,
name: msg.err.name,
},
};
}
function serializeDuration(msg) {
return {
...msg,
duration: `${msg.duration.toFixed(2)}ms`,
};
}
function safeCycles() {
const seen = new Set();
return function handleKey(key, val) {
if (!val || typeof val !== 'object') {
return val;
}
if (seen.has(val)) {
return '[Circular]';
}
seen.add(val);
return val;
};
}
/**
* A fast JSON.stringify that handles cycles and getter exceptions (when
* safeJsonStringify is installed).
*
* This function attempts to use the regular JSON.stringify for speed, but on
* error (e.g. JSON cycle detection exception) it falls back to safe stringify
* handlers that can deal with cycles and/or getter exceptions.
*
* From: https://github.com/trentm/node-bunyan/blob/c0932196dd6846189ec82623c12d051eee799d4f/lib/bunyan.js#L1208
*/
function fastAndSafeJsonStringify(object) {
try {
return JSON.stringify(object);
} catch (err) {
try {
return JSON.stringify(object, safeCycles());
} catch (err2) {
console.log('err', err);
console.log('err2', err2);
console.log('object', object);
return 'modules/scripts/log: something is wrong';
}
}
}
function logMethod(process, console, type) {
return (object) => {
const { name, msg, force = false } = object;
let formatedMsg = msg;
if (process.env.NODE_ENV === 'test' && !force) {
return;
}
if (process.env.NODE_ENV !== 'production' && !name) {
throw new Error(`Missing name ${JSON.stringify(object)}`);
}
const format =
process.env.NODE_ENV === 'production' &&
process.env.LOG_FORMAT !== 'human' &&
!process.browser
? 'json'
: 'human';
if (formatedMsg.duration) {
formatedMsg = serializeDuration(formatedMsg);
}
if (format === 'json') {
if (formatedMsg.err) {
formatedMsg = serializeErr(formatedMsg);
}
const message = fastAndSafeJsonStringify({
level: logTypes[type].level,
msg: formatedMsg,
name,
...(process.browser ? {} : { pid: process.pid }),
});
if (process.browser) {
console[logTypes[type].method](message);
return;
}
// Faster than calling console.x.
process.stdout.write(`${message}\n`);
} else {
const messages = [];
if (process.browser) {
messages.push(`${name}:`);
} else {
messages.push(`${type.toUpperCase()} ${process.pid} ${name}:`);
}
if (formatedMsg.err) {
messages.push(formatedMsg.err);
delete formatedMsg.err;
}
messages.push(formatedMsg);
console[logTypes[type].method](...messages);
}
};
}
const log = {
info: logMethod(process, console, 'info'),
warn: logMethod(process, console, 'warn'),
error: logMethod(process, console, 'error'),
fatal: logMethod(process, console, 'fatal'),
};
module.exports = log;