metalog 3.1.5 → 3.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -1
- package/LICENSE +1 -1
- package/README.md +2 -2
- package/metalog.d.ts +7 -6
- package/metalog.js +106 -62
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased][unreleased]
|
|
4
4
|
|
|
5
|
+
## [3.1.8][] - 2022-03-30
|
|
6
|
+
|
|
7
|
+
- Add support for json-only logs
|
|
8
|
+
|
|
9
|
+
## [3.1.7][] - 2022-03-17
|
|
10
|
+
|
|
11
|
+
- Fix unlink empty files
|
|
12
|
+
- Improve error handling
|
|
13
|
+
- Update dependencies and package maintenance
|
|
14
|
+
|
|
15
|
+
## [3.1.6][] - 2021-12-08
|
|
16
|
+
|
|
17
|
+
- Fix typings
|
|
18
|
+
- Remove useless code from tests
|
|
19
|
+
- Fix unlink file bug
|
|
20
|
+
|
|
5
21
|
## [3.1.5][] - 2021-10-11
|
|
6
22
|
|
|
7
23
|
- Update dependencies and npm audit fix
|
|
@@ -52,7 +68,10 @@
|
|
|
52
68
|
|
|
53
69
|
First generation of Metarhia Logger
|
|
54
70
|
|
|
55
|
-
[unreleased]: https://github.com/metarhia/metalog/compare/v3.1.
|
|
71
|
+
[unreleased]: https://github.com/metarhia/metalog/compare/v3.1.8...HEAD
|
|
72
|
+
[3.1.8]: https://github.com/metarhia/metalog/compare/v3.1.7...v3.1.8
|
|
73
|
+
[3.1.7]: https://github.com/metarhia/metalog/compare/v3.1.6...v3.1.7
|
|
74
|
+
[3.1.6]: https://github.com/metarhia/metalog/compare/v3.1.5...v3.1.6
|
|
56
75
|
[3.1.5]: https://github.com/metarhia/metalog/compare/v3.1.4...v3.1.5
|
|
57
76
|
[3.1.4]: https://github.com/metarhia/metalog/compare/v3.1.3...v3.1.4
|
|
58
77
|
[3.1.3]: https://github.com/metarhia/metalog/compare/v3.1.2...v3.1.3
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Meta Logger for Metarhia
|
|
2
2
|
|
|
3
3
|
[](https://github.com/metarhia/metalog/actions?query=workflow%3A%22Testing+CI%22+branch%3Amaster)
|
|
4
|
-
[](https://www.codacy.com/app/metarhia/metalog)
|
|
5
4
|
[](https://snyk.io/test/github/metarhia/impress)
|
|
6
5
|
[](https://www.npmjs.com/package/metalog)
|
|
7
6
|
[](https://www.npmjs.com/package/metalog)
|
|
@@ -22,6 +21,7 @@ const logger = await metalog.openLog({
|
|
|
22
21
|
writeBuffer: 64 * 1024, // buffer size (default 64kb)
|
|
23
22
|
keepDays: 5, // delete after N days, 0 - disable
|
|
24
23
|
home: process.cwd(), // remove substring from paths
|
|
24
|
+
json: false, // print logs in JSON format, by default false
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
const { console } = logger;
|
|
@@ -31,6 +31,6 @@ await logger.close();
|
|
|
31
31
|
|
|
32
32
|
## License & Contributors
|
|
33
33
|
|
|
34
|
-
Copyright (c) 2017-
|
|
34
|
+
Copyright (c) 2017-2022 [Metarhia contributors](https://github.com/metarhia/metalog/graphs/contributors).
|
|
35
35
|
Metalog is [MIT licensed](./LICENSE).\
|
|
36
36
|
Metalog is a part of [Metarhia](https://github.com/metarhia) technology stack.
|
package/metalog.d.ts
CHANGED
|
@@ -3,13 +3,14 @@ import EventEmitter = require('events');
|
|
|
3
3
|
interface LoggerOptions {
|
|
4
4
|
path: string;
|
|
5
5
|
home: string;
|
|
6
|
-
workerId
|
|
7
|
-
createStream
|
|
6
|
+
workerId?: number;
|
|
7
|
+
createStream?: () => NodeJS.WritableStream;
|
|
8
8
|
writeInterval: number;
|
|
9
9
|
writeBuffer: number;
|
|
10
10
|
keepDays: number;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
json?: boolean;
|
|
12
|
+
toFile?: Array<string>;
|
|
13
|
+
toStdout?: Array<string>;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export class Logger extends EventEmitter {
|
|
@@ -27,9 +28,9 @@ export class Logger extends EventEmitter {
|
|
|
27
28
|
lock: boolean;
|
|
28
29
|
buffer: Array<Buffer>;
|
|
29
30
|
file: string;
|
|
30
|
-
toFile:
|
|
31
|
+
toFile: Record<string, boolean>;
|
|
31
32
|
fsEnabled: boolean;
|
|
32
|
-
toStdout:
|
|
33
|
+
toStdout: Record<string, boolean>;
|
|
33
34
|
console: Console;
|
|
34
35
|
constructor(args: LoggerOptions);
|
|
35
36
|
createLogDir(): Promise<void>;
|
package/metalog.js
CHANGED
|
@@ -77,10 +77,13 @@ const getNextReopen = () => {
|
|
|
77
77
|
return nextDate - curTime + DAY_MILLISECONDS;
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
+
const isError = (val) =>
|
|
81
|
+
Object.prototype.toString.call(val) === '[object Error]';
|
|
82
|
+
|
|
80
83
|
class Console {
|
|
81
84
|
constructor(write) {
|
|
82
85
|
this._write = write;
|
|
83
|
-
this._groupIndent =
|
|
86
|
+
this._groupIndent = 0;
|
|
84
87
|
this._counts = new Map();
|
|
85
88
|
this._times = new Map();
|
|
86
89
|
}
|
|
@@ -89,7 +92,7 @@ class Console {
|
|
|
89
92
|
try {
|
|
90
93
|
console.assert(assertion, ...args);
|
|
91
94
|
} catch (err) {
|
|
92
|
-
this._write('error',
|
|
95
|
+
this._write('error', this._groupIndent, err.stack);
|
|
93
96
|
}
|
|
94
97
|
}
|
|
95
98
|
|
|
@@ -102,7 +105,7 @@ class Console {
|
|
|
102
105
|
let cnt = this._counts.get(label) || 0;
|
|
103
106
|
cnt++;
|
|
104
107
|
this._counts.set(label, cnt);
|
|
105
|
-
this._write('debug',
|
|
108
|
+
this._write('debug', this._groupIndent, `${label}: ${cnt}`);
|
|
106
109
|
}
|
|
107
110
|
|
|
108
111
|
countReset(label = 'default') {
|
|
@@ -110,23 +113,38 @@ class Console {
|
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
debug(...args) {
|
|
113
|
-
|
|
114
|
-
this._write('debug', `${this._groupIndent}${msg}`);
|
|
116
|
+
this._write('debug', this._groupIndent, ...args);
|
|
115
117
|
}
|
|
116
118
|
|
|
117
119
|
dir(...args) {
|
|
118
|
-
|
|
119
|
-
this._write('debug', `${this._groupIndent}${msg}`);
|
|
120
|
+
this._write('debug', this._groupIndent, ...args);
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
|
|
123
|
+
trace(...args) {
|
|
123
124
|
const msg = util.format(...args);
|
|
124
|
-
|
|
125
|
+
const err = new Error(msg);
|
|
126
|
+
this._write('debug', this._groupIndent, `Trace${err.stack}`);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
info(...args) {
|
|
130
|
+
this._write('info', this._groupIndent, ...args);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
log(...args) {
|
|
134
|
+
this._write('log', this._groupIndent, ...args);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
warn(...args) {
|
|
138
|
+
this._write('warn', this._groupIndent, ...args);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
error(...args) {
|
|
142
|
+
this._write('error', this._groupIndent, ...args);
|
|
125
143
|
}
|
|
126
144
|
|
|
127
145
|
group(...args) {
|
|
128
146
|
if (args.length !== 0) this.log(...args);
|
|
129
|
-
this._groupIndent
|
|
147
|
+
this._groupIndent += INDENT;
|
|
130
148
|
}
|
|
131
149
|
|
|
132
150
|
groupCollapsed(...args) {
|
|
@@ -135,21 +153,11 @@ class Console {
|
|
|
135
153
|
|
|
136
154
|
groupEnd() {
|
|
137
155
|
if (this._groupIndent.length === 0) return;
|
|
138
|
-
this._groupIndent
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
info(...args) {
|
|
142
|
-
const msg = util.format(...args);
|
|
143
|
-
this._write('info', `${this._groupIndent}${msg}`);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
log(...args) {
|
|
147
|
-
const msg = util.format(...args);
|
|
148
|
-
this._write('log', `${this._groupIndent}${msg}`);
|
|
156
|
+
this._groupIndent -= INDENT;
|
|
149
157
|
}
|
|
150
158
|
|
|
151
159
|
table(tabularData) {
|
|
152
|
-
this._write('log', JSON.stringify(tabularData));
|
|
160
|
+
this._write('log', 0, JSON.stringify(tabularData));
|
|
153
161
|
}
|
|
154
162
|
|
|
155
163
|
time(label = 'default') {
|
|
@@ -160,31 +168,18 @@ class Console {
|
|
|
160
168
|
const startTime = this._times.get(label);
|
|
161
169
|
const totalTime = process.hrtime(startTime);
|
|
162
170
|
const totalTimeMs = totalTime[0] * 1e3 + totalTime[1] / 1e6;
|
|
163
|
-
|
|
164
|
-
this.timeLog(label, msg);
|
|
171
|
+
this.timeLog(label, `${label}: ${totalTimeMs}ms`);
|
|
165
172
|
this._times.delete(label);
|
|
166
173
|
}
|
|
167
174
|
|
|
168
175
|
timeLog(label, ...args) {
|
|
169
176
|
const startTime = this._times.get(label);
|
|
170
177
|
if (startTime === undefined) {
|
|
171
|
-
const msg =
|
|
172
|
-
this._write('warn', msg);
|
|
178
|
+
const msg = `Warning: No such label '${label}'`;
|
|
179
|
+
this._write('warn', this._groupIndent, msg);
|
|
173
180
|
return;
|
|
174
181
|
}
|
|
175
|
-
|
|
176
|
-
this._write('debug', msg);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
trace(...args) {
|
|
180
|
-
const msg = util.format(...args);
|
|
181
|
-
const err = new Error(msg);
|
|
182
|
-
this._write('debug', `${this._groupIndent}Trace${err.stack}`);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
warn(...args) {
|
|
186
|
-
const msg = util.format(...args);
|
|
187
|
-
this._write('warn', `${this._groupIndent}${msg}`);
|
|
182
|
+
this._write('debug', this._groupIndent, ...args);
|
|
188
183
|
}
|
|
189
184
|
}
|
|
190
185
|
|
|
@@ -192,7 +187,7 @@ class Logger extends events.EventEmitter {
|
|
|
192
187
|
constructor(args) {
|
|
193
188
|
super();
|
|
194
189
|
const { workerId = 0, createStream = fs.createWriteStream } = args;
|
|
195
|
-
const { writeInterval, writeBuffer, keepDays, home } = args;
|
|
190
|
+
const { writeInterval, writeBuffer, keepDays, home, json } = args;
|
|
196
191
|
const { toFile, toStdout } = args;
|
|
197
192
|
this.active = false;
|
|
198
193
|
this.path = args.path;
|
|
@@ -202,6 +197,7 @@ class Logger extends events.EventEmitter {
|
|
|
202
197
|
this.writeBuffer = writeBuffer || DEFAULT_BUFFER_SIZE;
|
|
203
198
|
this.keepDays = keepDays || DEFAULT_KEEP_DAYS;
|
|
204
199
|
this.home = home;
|
|
200
|
+
this.json = Boolean(json);
|
|
205
201
|
this.stream = null;
|
|
206
202
|
this.reopenTimer = null;
|
|
207
203
|
this.flushTimer = null;
|
|
@@ -211,7 +207,7 @@ class Logger extends events.EventEmitter {
|
|
|
211
207
|
this.toFile = logTypes(toFile);
|
|
212
208
|
this.fsEnabled = Object.keys(this.toFile).length !== 0;
|
|
213
209
|
this.toStdout = logTypes(toStdout);
|
|
214
|
-
this.console = new Console((
|
|
210
|
+
this.console = new Console((...args) => this.write(...args));
|
|
215
211
|
return this.open();
|
|
216
212
|
}
|
|
217
213
|
|
|
@@ -224,7 +220,8 @@ class Logger extends events.EventEmitter {
|
|
|
224
220
|
resolve();
|
|
225
221
|
return;
|
|
226
222
|
}
|
|
227
|
-
|
|
223
|
+
const error = new Error(`Can not create directory: ${this.path}\n`);
|
|
224
|
+
this.emit('error', error);
|
|
228
225
|
reject();
|
|
229
226
|
});
|
|
230
227
|
});
|
|
@@ -246,7 +243,10 @@ class Logger extends events.EventEmitter {
|
|
|
246
243
|
this.once('close', () => {
|
|
247
244
|
this.open();
|
|
248
245
|
});
|
|
249
|
-
this.close()
|
|
246
|
+
this.close().catch((err) => {
|
|
247
|
+
process.stdout.write(`${err.stack}\n`);
|
|
248
|
+
this.emit('error', err);
|
|
249
|
+
});
|
|
250
250
|
}, nextReopen);
|
|
251
251
|
if (this.keepDays) await this.rotate();
|
|
252
252
|
const options = { flags: 'a', bufferSize: this.writeBuffer };
|
|
@@ -278,8 +278,6 @@ class Logger extends events.EventEmitter {
|
|
|
278
278
|
return new Promise((resolve, reject) => {
|
|
279
279
|
this.flush((err) => {
|
|
280
280
|
if (err) {
|
|
281
|
-
process.stdout.write(`${err.stack}\n`);
|
|
282
|
-
this.emit('error', err);
|
|
283
281
|
reject(err);
|
|
284
282
|
return;
|
|
285
283
|
}
|
|
@@ -291,11 +289,11 @@ class Logger extends events.EventEmitter {
|
|
|
291
289
|
this.reopenTimer = null;
|
|
292
290
|
const fileName = this.file;
|
|
293
291
|
this.emit('close');
|
|
294
|
-
resolve();
|
|
295
292
|
fs.stat(fileName, (err, stats) => {
|
|
296
293
|
if (!err && stats.size === 0) {
|
|
297
|
-
fsp.unlink(
|
|
294
|
+
fsp.unlink(fileName).catch(() => {});
|
|
298
295
|
}
|
|
296
|
+
resolve();
|
|
299
297
|
});
|
|
300
298
|
});
|
|
301
299
|
});
|
|
@@ -321,25 +319,63 @@ class Logger extends events.EventEmitter {
|
|
|
321
319
|
}
|
|
322
320
|
}
|
|
323
321
|
|
|
324
|
-
|
|
325
|
-
const date = new Date();
|
|
326
|
-
const dateTime = date.toISOString();
|
|
322
|
+
format(type, indent, ...args) {
|
|
327
323
|
const normalize = type === 'error' || type === 'debug';
|
|
328
|
-
const
|
|
324
|
+
const s = `${' '.repeat(indent)}${util.format(...args)}`;
|
|
325
|
+
return normalize ? this.normalizeStack(s) : s;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
formatPretty(type, indent, ...args) {
|
|
329
|
+
const dateTime = new Date().toISOString();
|
|
330
|
+
const message = this.format(type, indent, ...args);
|
|
331
|
+
const normalColor = TEXT_COLOR[type];
|
|
332
|
+
const markColor = TYPE_COLOR[type];
|
|
333
|
+
const time = normalColor(dateTime.substring(TIME_START, TIME_END));
|
|
334
|
+
const id = normalColor(this.workerId);
|
|
335
|
+
const mark = markColor(' ' + type.padEnd(TYPE_LENGTH));
|
|
336
|
+
const msg = normalColor(message);
|
|
337
|
+
return `${time} ${id} ${mark} ${msg}`;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
formatFile(type, indent, ...args) {
|
|
341
|
+
const dateTime = new Date().toISOString();
|
|
342
|
+
const message = this.format(type, indent, ...args);
|
|
343
|
+
const msg = metautil.replace(message, '\n', LINE_SEPARATOR);
|
|
344
|
+
return `${dateTime} [${type}] ${msg}`;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
formatJson(type, indent, ...args) {
|
|
348
|
+
const log = {
|
|
349
|
+
timestamp: new Date().toISOString(),
|
|
350
|
+
workerId: this.workerId,
|
|
351
|
+
level: type,
|
|
352
|
+
message: null,
|
|
353
|
+
};
|
|
354
|
+
if (isError(args[0])) {
|
|
355
|
+
log.err = this.expandError(args[0]);
|
|
356
|
+
args = args.slice(1);
|
|
357
|
+
} else if (typeof args[0] === 'object') {
|
|
358
|
+
Object.assign(log, args[0]);
|
|
359
|
+
if (isError(log.err)) log.err = this.expandError(log.err);
|
|
360
|
+
if (isError(log.error)) log.error = this.expandError(log.error);
|
|
361
|
+
args = args.slice(1);
|
|
362
|
+
}
|
|
363
|
+
log.message = util.format(...args);
|
|
364
|
+
return JSON.stringify(log);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
write(type, indent, ...args) {
|
|
329
368
|
if (this.toStdout[type]) {
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const mark = markColor(' ' + type.padEnd(TYPE_LENGTH));
|
|
335
|
-
const msg = normalColor(message);
|
|
336
|
-
const line = `${time} ${id} ${mark} ${msg}\n`;
|
|
337
|
-
process.stdout.write(line);
|
|
369
|
+
const line = this.json
|
|
370
|
+
? this.formatJson(type, indent, ...args)
|
|
371
|
+
: this.formatPretty(type, indent, ...args);
|
|
372
|
+
process.stdout.write(line + '\n');
|
|
338
373
|
}
|
|
339
374
|
if (this.toFile[type]) {
|
|
340
|
-
const
|
|
341
|
-
|
|
342
|
-
|
|
375
|
+
const line = this.json
|
|
376
|
+
? this.formatJson(type, indent, ...args)
|
|
377
|
+
: this.formatFile(type, indent, ...args);
|
|
378
|
+
const buffer = Buffer.from(line + '\n');
|
|
343
379
|
this.buffer.push(buffer);
|
|
344
380
|
}
|
|
345
381
|
}
|
|
@@ -375,6 +411,14 @@ class Logger extends events.EventEmitter {
|
|
|
375
411
|
if (this.home) res = metautil.replace(res, this.home, '');
|
|
376
412
|
return res;
|
|
377
413
|
}
|
|
414
|
+
|
|
415
|
+
expandError(err) {
|
|
416
|
+
return {
|
|
417
|
+
message: err.message,
|
|
418
|
+
stack: this.normalizeStack(err.stack),
|
|
419
|
+
...err,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
378
422
|
}
|
|
379
423
|
|
|
380
424
|
const openLog = async (args) => new Logger(args);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metalog",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.8",
|
|
4
4
|
"author": "Timur Shemsedinov <timur.shemsedinov@gmail.com>",
|
|
5
5
|
"description": "Logger for Metarhia",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,21 +49,21 @@
|
|
|
49
49
|
"fmt": "prettier --write \"**/*.js\" \"**/*.json\" \"**/*.md\" \"**/.*rc\" \"**/*.ts\""
|
|
50
50
|
},
|
|
51
51
|
"engines": {
|
|
52
|
-
"node": "^12.10 || 14 || 16"
|
|
52
|
+
"node": "^12.10 || 14 || 16 || 17"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"concolor": "^1.0.2",
|
|
56
|
-
"metautil": "^3.5.
|
|
56
|
+
"metautil": "^3.5.19"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@types/node": "^
|
|
60
|
-
"eslint": "^
|
|
59
|
+
"@types/node": "^17.0.21",
|
|
60
|
+
"eslint": "^8.11.0",
|
|
61
61
|
"eslint-config-metarhia": "^7.0.0",
|
|
62
|
-
"eslint-config-prettier": "^8.
|
|
63
|
-
"eslint-plugin-import": "^2.
|
|
62
|
+
"eslint-config-prettier": "^8.5.0",
|
|
63
|
+
"eslint-plugin-import": "^2.25.4",
|
|
64
64
|
"eslint-plugin-prettier": "^4.0.0",
|
|
65
|
-
"metatests": "^0.
|
|
66
|
-
"prettier": "^2.
|
|
67
|
-
"typescript": "^4.
|
|
65
|
+
"metatests": "^0.8.2",
|
|
66
|
+
"prettier": "^2.6.0",
|
|
67
|
+
"typescript": "^4.6.2"
|
|
68
68
|
}
|
|
69
69
|
}
|