metalog 3.1.15 → 3.1.17

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017-2024 Metarhia
3
+ Copyright (c) 2017-2025 Metarhia
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -31,6 +31,6 @@ await logger.close();
31
31
 
32
32
  ## License & Contributors
33
33
 
34
- Copyright (c) 2017-2024 [Metarhia contributors](https://github.com/metarhia/metalog/graphs/contributors).
34
+ Copyright (c) 2017-2025 [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
@@ -11,6 +11,28 @@ interface LoggerOptions {
11
11
  json?: boolean;
12
12
  toFile?: Array<string>;
13
13
  toStdout?: Array<string>;
14
+ crash?: string;
15
+ }
16
+
17
+ interface Console {
18
+ assert(assertion: unknown, ...args: unknown[]): void;
19
+ clear(): void;
20
+ count(label?: string): void;
21
+ countReset(label?: string): void;
22
+ debug(...args: unknown[]): void;
23
+ dir(...args: unknown[]): void;
24
+ trace(...args: unknown[]): void;
25
+ info(...args: unknown[]): void;
26
+ log(...args: unknown[]): void;
27
+ warn(...args: unknown[]): void;
28
+ error(...args: unknown[]): void;
29
+ group(...args: unknown[]): void;
30
+ groupCollapsed(...args: unknown[]): void;
31
+ groupEnd(): void;
32
+ table(tabularData: unknown): void;
33
+ time(label?: string): void;
34
+ timeEnd(label?: string): void;
35
+ timeLog(label: string, ...args: unknown[]): void;
14
36
  }
15
37
 
16
38
  export class Logger extends EventEmitter {
@@ -22,6 +44,7 @@ export class Logger extends EventEmitter {
22
44
  writeBuffer: number;
23
45
  keepDays: number;
24
46
  home: string;
47
+ json: boolean;
25
48
  stream: NodeJS.WritableStream;
26
49
  reopenTimer: NodeJS.Timer;
27
50
  flushTimer: NodeJS.Timer;
@@ -38,9 +61,14 @@ export class Logger extends EventEmitter {
38
61
  open(): Promise<Logger>;
39
62
  close(): Promise<void>;
40
63
  rotate(): Promise<void>;
41
- write(type: string, s: string): void;
42
- flush(callback: Function): void;
64
+ format(type: string, indent: number, ...args: unknown[]): string;
65
+ formatPretty(type: string, indent: number, ...args: unknown[]): string;
66
+ formatFile(type: string, indent: number, ...args: unknown[]): string;
67
+ formatJson(type: string, indent: number, ...args: unknown[]): string;
68
+ write(type: string, indent: number, ...args: unknown[]): void;
69
+ flush(callback?: (err?: Error) => void): void;
43
70
  normalizeStack(stack: string): string;
71
+ expandError(err: Error): unknown;
44
72
  }
45
73
 
46
74
  export function openLog(args: LoggerOptions): Promise<Logger>;
package/metalog.js CHANGED
@@ -89,10 +89,10 @@ class Console {
89
89
  }
90
90
 
91
91
  assert(assertion, ...args) {
92
- try {
93
- console.assert(assertion, ...args);
94
- } catch (err) {
95
- this.#write('error', this.#groupIndent, err.stack);
92
+ if (!assertion) {
93
+ const noArgs = args.length === 0;
94
+ const message = noArgs ? 'Assertion failed' : util.format(...args);
95
+ this.#write('error', this.#groupIndent, message);
96
96
  }
97
97
  }
98
98
 
@@ -152,7 +152,7 @@ class Console {
152
152
  }
153
153
 
154
154
  groupEnd() {
155
- if (this.#groupIndent.length === 0) return;
155
+ if (this.#groupIndent === 0) return;
156
156
  this.#groupIndent -= INDENT;
157
157
  }
158
158
 
@@ -184,13 +184,13 @@ class Console {
184
184
  }
185
185
 
186
186
  class Logger extends events.EventEmitter {
187
- constructor(args) {
187
+ constructor(options) {
188
188
  super();
189
- const { workerId = 0, createStream = fs.createWriteStream } = args;
190
- const { writeInterval, writeBuffer, keepDays, home, json } = args;
191
- const { toFile = LOG_TYPES, toStdout = LOG_TYPES } = args;
189
+ const { workerId = 0, createStream = fs.createWriteStream } = options;
190
+ const { writeInterval, writeBuffer, keepDays, home, json } = options;
191
+ const { toFile = LOG_TYPES, toStdout = LOG_TYPES, crash } = options;
192
192
  this.active = false;
193
- this.path = args.path;
193
+ this.path = options.path;
194
194
  this.workerId = `W${workerId}`;
195
195
  this.createStream = createStream;
196
196
  this.writeInterval = writeInterval || DEFAULT_WRITE_INTERVAL;
@@ -209,6 +209,7 @@ class Logger extends events.EventEmitter {
209
209
  this.fsEnabled = toFile.length !== 0;
210
210
  this.toStdout = logTypes(toStdout);
211
211
  this.console = new Console((...args) => this.write(...args));
212
+ if (crash === 'flush') this.#setupCrashHandling();
212
213
  return this.open();
213
214
  }
214
215
 
@@ -386,7 +387,13 @@ class Logger extends events.EventEmitter {
386
387
  return;
387
388
  }
388
389
  if (!this.active) {
389
- const err = new Error('Cannot flush log buffer: logger is not opened');
390
+ const err = new Error('Cannot flush log buffer: logger is not active');
391
+ this.emit('error', err);
392
+ if (callback) callback(err);
393
+ return;
394
+ }
395
+ if (!this.stream || this.stream.destroyed || this.stream.closed) {
396
+ const err = new Error('Cannot flush log buffer: stream is not available');
390
397
  this.emit('error', err);
391
398
  if (callback) callback(err);
392
399
  return;
@@ -416,8 +423,29 @@ class Logger extends events.EventEmitter {
416
423
  ...err,
417
424
  };
418
425
  }
426
+
427
+ #setupCrashHandling() {
428
+ const exitHandler = () => {
429
+ this.flush();
430
+ };
431
+ process.on('SIGTERM', exitHandler);
432
+ process.on('SIGINT', exitHandler);
433
+ process.on('SIGUSR1', exitHandler);
434
+ process.on('SIGUSR2', exitHandler);
435
+ process.on('uncaughtException', (err) => {
436
+ this.write('error', 0, 'Uncaught Exception:', err);
437
+ this.flush();
438
+ });
439
+ process.on('unhandledRejection', (reason) => {
440
+ this.write('error', 0, 'Unhandled Rejection:', reason);
441
+ this.flush();
442
+ });
443
+ process.on('exit', () => {
444
+ this.flush();
445
+ });
446
+ }
419
447
  }
420
448
 
421
- const openLog = async (args) => new Logger(args);
449
+ const openLog = async (options) => new Logger(options);
422
450
 
423
451
  module.exports = { Logger, openLog };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metalog",
3
- "version": "3.1.15",
3
+ "version": "3.1.17",
4
4
  "author": "Timur Shemsedinov <timur.shemsedinov@gmail.com>",
5
5
  "description": "Logger for Metarhia",
6
6
  "license": "MIT",
@@ -49,17 +49,17 @@
49
49
  "fix": "eslint . --fix && prettier --write \"**/*.js\" \"**/*.json\" \"**/*.md\" \"**/*.ts\""
50
50
  },
51
51
  "engines": {
52
- "node": "18 || 20 || 21 || 22"
52
+ "node": ">=18"
53
53
  },
54
54
  "dependencies": {
55
- "concolor": "^1.1.0",
56
- "metautil": "^5.2.3"
55
+ "concolor": "^1.1.3",
56
+ "metautil": "^5.3.0"
57
57
  },
58
58
  "devDependencies": {
59
- "@types/node": "^22.5.1",
60
- "eslint": "^9.9.1",
61
- "eslint-config-metarhia": "^9.0.4",
62
- "prettier": "^3.3.3",
63
- "typescript": "^5.5.4"
59
+ "@types/node": "^24.3.0",
60
+ "eslint": "^9.34.0",
61
+ "eslint-config-metarhia": "^9.1.3",
62
+ "prettier": "^3.6.2",
63
+ "typescript": "^5.9.2"
64
64
  }
65
65
  }