@quatrain/log 1.0.3 → 1.1.2
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.md +15 -0
- package/{lib → dist}/AbstractLoggerAdapter.d.ts +15 -12
- package/dist/AbstractLoggerAdapter.d.ts.map +1 -0
- package/dist/AbstractLoggerAdapter.js +65 -0
- package/dist/AbstractLoggerAdapter.js.map +1 -0
- package/{lib → dist}/DefaultLoggerAdapter.d.ts +2 -7
- package/dist/DefaultLoggerAdapter.d.ts.map +1 -0
- package/{lib → dist}/DefaultLoggerAdapter.js +12 -17
- package/dist/DefaultLoggerAdapter.js.map +1 -0
- package/dist/Log.d.ts +19 -0
- package/dist/Log.d.ts.map +1 -0
- package/dist/Log.js +51 -0
- package/dist/Log.js.map +1 -0
- package/{lib → dist}/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/{lib → dist}/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -38
- package/src/AbstractLoggerAdapter.ts +90 -0
- package/src/DefaultLoggerAdapter.test.ts +103 -0
- package/src/DefaultLoggerAdapter.ts +66 -0
- package/src/Log.test.ts +45 -0
- package/src/Log.ts +73 -0
- package/src/index.ts +5 -0
- package/lib/AbstractLoggerAdapter.js +0 -57
- package/lib/Log.d.ts +0 -29
- package/lib/Log.js +0 -61
package/LICENSE.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# LICENSE UPDATE NOTICE
|
|
2
|
+
|
|
3
|
+
As of 01/01/2026, Quatrain Core is licensed under the **GNU Affero General Public License v3.0 (AGPL v3)**.
|
|
4
|
+
Previous versions remain under the MIT License.
|
|
5
|
+
|
|
6
|
+
## Why AGPL?
|
|
7
|
+
|
|
8
|
+
We believe in open collaboration for the development ecosystem. The AGPL ensures that any modification or deployment of this BaaS stack, including over a network, benefits the entire community.
|
|
9
|
+
|
|
10
|
+
## Commercial Services & Enterprise Usage
|
|
11
|
+
|
|
12
|
+
We provide official deployment services, technical training, and certification for Quatrain Core.
|
|
13
|
+
For organizations requiring a non-copyleft license (commercial license) or custom proprietary integrations, please contact the copyright holder: **Quatrain Technologies**.
|
|
14
|
+
|
|
15
|
+
Copyright © 2024-2026 Quatrain Technologies. All Rights Reserved.
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
export declare enum LogLevel {
|
|
2
|
+
TRACE = 0,
|
|
3
|
+
DEBUG = 1,
|
|
4
|
+
INFO = 2,
|
|
5
|
+
WARN = 3,
|
|
6
|
+
ERROR = 4,
|
|
7
|
+
SILENT = 5
|
|
8
|
+
}
|
|
2
9
|
export interface LoggerType {
|
|
3
10
|
log(message: string): void;
|
|
4
11
|
debug(message: string): void;
|
|
@@ -15,15 +22,11 @@ export declare abstract class AbstractLoggerAdapter implements LoggerType {
|
|
|
15
22
|
constructor(prefix?: string, level?: LogLevel);
|
|
16
23
|
logLevel(level: LogLevel): void;
|
|
17
24
|
formatLogMessage: (messages: any[], loglevel?: LogLevel) => string;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
debug(message: any): void;
|
|
25
|
-
warn(message: any): void;
|
|
26
|
-
info(message: any): void;
|
|
27
|
-
error(message: any): void;
|
|
28
|
-
trace(message: any): void;
|
|
25
|
+
log(...messages: any[]): void;
|
|
26
|
+
debug(...messages: any[]): void;
|
|
27
|
+
warn(...messages: any[]): void;
|
|
28
|
+
info(...messages: any[]): void;
|
|
29
|
+
error(...messages: any[]): void;
|
|
30
|
+
trace(...messages: any[]): void;
|
|
29
31
|
}
|
|
32
|
+
//# sourceMappingURL=AbstractLoggerAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbstractLoggerAdapter.d.ts","sourceRoot":"","sources":["../src/AbstractLoggerAdapter.ts"],"names":[],"mappings":"AAAA,oBAAY,QAAQ;IACjB,KAAK,IAAI;IACT,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;IACT,MAAM,IAAI;CACZ;AAED,MAAM,WAAW,UAAU;IACxB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B;AAED,eAAO,MAAM,aAAa,UAOzB,CAAA;AAED,8BAAsB,qBAAsB,YAAW,UAAU;IAC9D,SAAS,CAAC,GAAG,EAAE,MAAM,CAAK;IAC1B,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAgB;IAC7C,SAAS,CAAC,OAAO,EAAE,GAAG,CAAY;gBAEtB,MAAM,SAAK,EAAE,KAAK,GAAE,QAAwB;IAIxD,QAAQ,CAAC,KAAK,EAAE,QAAQ;IAIxB,gBAAgB,aACH,GAAG,EAAE,aACL,QAAQ,KAClB,MAAM,CAgBR;IAOD,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;IAI7B,KAAK,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;IAI/B,IAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;IAI9B,IAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;IAI9B,KAAK,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;IAI/B,KAAK,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;CAGjC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AbstractLoggerAdapter = exports.loglevelNames = exports.LogLevel = void 0;
|
|
4
|
+
var LogLevel;
|
|
5
|
+
(function (LogLevel) {
|
|
6
|
+
LogLevel[LogLevel["TRACE"] = 0] = "TRACE";
|
|
7
|
+
LogLevel[LogLevel["DEBUG"] = 1] = "DEBUG";
|
|
8
|
+
LogLevel[LogLevel["INFO"] = 2] = "INFO";
|
|
9
|
+
LogLevel[LogLevel["WARN"] = 3] = "WARN";
|
|
10
|
+
LogLevel[LogLevel["ERROR"] = 4] = "ERROR";
|
|
11
|
+
LogLevel[LogLevel["SILENT"] = 5] = "SILENT";
|
|
12
|
+
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
|
13
|
+
exports.loglevelNames = [
|
|
14
|
+
'TRACE',
|
|
15
|
+
'DEBUG',
|
|
16
|
+
'INFO',
|
|
17
|
+
'WARN',
|
|
18
|
+
'ERROR',
|
|
19
|
+
'SILENT',
|
|
20
|
+
];
|
|
21
|
+
class AbstractLoggerAdapter {
|
|
22
|
+
_me = '';
|
|
23
|
+
_logLevel = LogLevel.WARN;
|
|
24
|
+
_logger = undefined;
|
|
25
|
+
constructor(prefix = '', level = LogLevel.WARN) {
|
|
26
|
+
this._me = prefix;
|
|
27
|
+
}
|
|
28
|
+
logLevel(level) {
|
|
29
|
+
this._logLevel = level;
|
|
30
|
+
}
|
|
31
|
+
formatLogMessage = (messages, loglevel = LogLevel.INFO) => {
|
|
32
|
+
const flatMessages = messages.flat();
|
|
33
|
+
const prefix = `${new Date().toISOString()} - [${this._me}]`;
|
|
34
|
+
const strs = flatMessages.map((message) => {
|
|
35
|
+
if (message instanceof Error) {
|
|
36
|
+
return message.stack || message.message;
|
|
37
|
+
}
|
|
38
|
+
if (typeof message === 'object' && message !== null) {
|
|
39
|
+
return JSON.stringify(message);
|
|
40
|
+
}
|
|
41
|
+
return String(message);
|
|
42
|
+
});
|
|
43
|
+
return `${prefix} ${strs.join(' ')}`;
|
|
44
|
+
};
|
|
45
|
+
log(...messages) {
|
|
46
|
+
throw new Error(`This method needs to be implemtend in child class`);
|
|
47
|
+
}
|
|
48
|
+
debug(...messages) {
|
|
49
|
+
throw new Error(`This method needs to be implemtend in child class`);
|
|
50
|
+
}
|
|
51
|
+
warn(...messages) {
|
|
52
|
+
throw new Error(`This method needs to be implemtend in child class`);
|
|
53
|
+
}
|
|
54
|
+
info(...messages) {
|
|
55
|
+
throw new Error(`This method needs to be implemtend in child class`);
|
|
56
|
+
}
|
|
57
|
+
error(...messages) {
|
|
58
|
+
throw new Error(`This method needs to be implemtend in child class`);
|
|
59
|
+
}
|
|
60
|
+
trace(...messages) {
|
|
61
|
+
throw new Error(`This method needs to be implemtend in child class`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.AbstractLoggerAdapter = AbstractLoggerAdapter;
|
|
65
|
+
//# sourceMappingURL=AbstractLoggerAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbstractLoggerAdapter.js","sourceRoot":"","sources":["../src/AbstractLoggerAdapter.ts"],"names":[],"mappings":";;;AAAA,IAAY,QAOX;AAPD,WAAY,QAAQ;IACjB,yCAAS,CAAA;IACT,yCAAS,CAAA;IACT,uCAAQ,CAAA;IACR,uCAAQ,CAAA;IACR,yCAAS,CAAA;IACT,2CAAU,CAAA;AACb,CAAC,EAPW,QAAQ,wBAAR,QAAQ,QAOnB;AAWY,QAAA,aAAa,GAAG;IAC1B,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,QAAQ;CACV,CAAA;AAED,MAAsB,qBAAqB;IAC9B,GAAG,GAAW,EAAE,CAAA;IAChB,SAAS,GAAa,QAAQ,CAAC,IAAI,CAAA;IACnC,OAAO,GAAQ,SAAS,CAAA;IAElC,YAAY,MAAM,GAAG,EAAE,EAAE,QAAkB,QAAQ,CAAC,IAAI;QACrD,IAAI,CAAC,GAAG,GAAG,MAAM,CAAA;IACpB,CAAC;IAED,QAAQ,CAAC,KAAe;QACrB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;IACzB,CAAC;IAED,gBAAgB,GAAG,CAChB,QAAe,EACf,WAAqB,QAAQ,CAAC,IAAI,EAC3B,EAAE;QAET,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAA;QAEpC,MAAM,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,OAAO,IAAI,CAAC,GAAG,GAAG,CAAA;QAC5D,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,OAAY,EAAE,EAAE;YAC5C,IAAI,OAAO,YAAY,KAAK,EAAE,CAAC;gBAC5B,OAAO,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,OAAO,CAAA;YAC1C,CAAC;YACD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACnD,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YACjC,CAAC;YACD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAA;QACzB,CAAC,CAAC,CAAA;QAEF,OAAO,GAAG,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;IACvC,CAAC,CAAA;IAOD,GAAG,CAAC,GAAG,QAAe;QACnB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACvE,CAAC;IAED,KAAK,CAAC,GAAG,QAAe;QACrB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACvE,CAAC;IAED,IAAI,CAAC,GAAG,QAAe;QACpB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACvE,CAAC;IAED,IAAI,CAAC,GAAG,QAAe;QACpB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACvE,CAAC;IAED,KAAK,CAAC,GAAG,QAAe;QACrB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACvE,CAAC;IAED,KAAK,CAAC,GAAG,QAAe;QACrB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACvE,CAAC;CACH;AA9DD,sDA8DC"}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import { AbstractLoggerAdapter } from './AbstractLoggerAdapter';
|
|
2
|
-
import { LogLevel } from './Log';
|
|
1
|
+
import { AbstractLoggerAdapter, LogLevel } from './AbstractLoggerAdapter';
|
|
3
2
|
export declare class DefaultLoggerAdapter extends AbstractLoggerAdapter {
|
|
4
3
|
constructor(prefix?: string, level?: LogLevel);
|
|
5
|
-
/**
|
|
6
|
-
* Log message using defined logger
|
|
7
|
-
* @param messages array
|
|
8
|
-
* @param level LogLevel
|
|
9
|
-
*/
|
|
10
4
|
log(messages: any[], level?: LogLevel): void;
|
|
11
5
|
logLevel(level: LogLevel): void;
|
|
12
6
|
debug(...messages: any): void;
|
|
@@ -15,3 +9,4 @@ export declare class DefaultLoggerAdapter extends AbstractLoggerAdapter {
|
|
|
15
9
|
error(...messages: any): void;
|
|
16
10
|
trace(...messages: any): void;
|
|
17
11
|
}
|
|
12
|
+
//# sourceMappingURL=DefaultLoggerAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DefaultLoggerAdapter.d.ts","sourceRoot":"","sources":["../src/DefaultLoggerAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAIzE,qBAAa,oBAAqB,SAAQ,qBAAqB;gBAChD,MAAM,SAAK,EAAE,KAAK,GAAE,QAAyB;IAWzD,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,KAAK,GAAE,QAAyB,GAAG,IAAI;IAyB5D,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAK/B,KAAK,CAAC,GAAG,QAAQ,EAAE,GAAG,GAAG,IAAI;IAI7B,IAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,GAAG,IAAI;IAI5B,IAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,GAAG,IAAI;IAI5B,KAAK,CAAC,GAAG,QAAQ,EAAE,GAAG,GAAG,IAAI;IAI7B,KAAK,CAAC,GAAG,QAAQ,EAAE,GAAG,GAAG,IAAI;CAG/B"}
|
|
@@ -6,35 +6,29 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.DefaultLoggerAdapter = void 0;
|
|
7
7
|
const AbstractLoggerAdapter_1 = require("./AbstractLoggerAdapter");
|
|
8
8
|
const loglevel_1 = __importDefault(require("loglevel"));
|
|
9
|
-
const Log_1 = require("./Log");
|
|
10
9
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
10
|
class DefaultLoggerAdapter extends AbstractLoggerAdapter_1.AbstractLoggerAdapter {
|
|
12
|
-
constructor(prefix = '', level =
|
|
11
|
+
constructor(prefix = '', level = AbstractLoggerAdapter_1.LogLevel.DEBUG) {
|
|
13
12
|
super(prefix, level);
|
|
14
13
|
this._logger = loglevel_1.default;
|
|
15
14
|
this._logger.setLevel(level);
|
|
16
15
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Log message using defined logger
|
|
19
|
-
* @param messages array
|
|
20
|
-
* @param level LogLevel
|
|
21
|
-
*/
|
|
22
16
|
log(messages, level = this._logLevel) {
|
|
23
17
|
const message = this.formatLogMessage(messages);
|
|
24
18
|
switch (level) {
|
|
25
|
-
case
|
|
19
|
+
case AbstractLoggerAdapter_1.LogLevel.TRACE:
|
|
26
20
|
this._logger.trace(chalk_1.default.grey(message));
|
|
27
21
|
break;
|
|
28
|
-
case
|
|
22
|
+
case AbstractLoggerAdapter_1.LogLevel.DEBUG:
|
|
29
23
|
this._logger.debug(chalk_1.default.yellow(message));
|
|
30
24
|
break;
|
|
31
|
-
case
|
|
25
|
+
case AbstractLoggerAdapter_1.LogLevel.INFO:
|
|
32
26
|
this._logger.info(chalk_1.default.green(message));
|
|
33
27
|
break;
|
|
34
|
-
case
|
|
28
|
+
case AbstractLoggerAdapter_1.LogLevel.WARN:
|
|
35
29
|
this._logger.warn(chalk_1.default.red(message));
|
|
36
30
|
break;
|
|
37
|
-
case
|
|
31
|
+
case AbstractLoggerAdapter_1.LogLevel.ERROR:
|
|
38
32
|
this._logger.error(chalk_1.default.bgRedBright(message));
|
|
39
33
|
break;
|
|
40
34
|
default:
|
|
@@ -47,19 +41,20 @@ class DefaultLoggerAdapter extends AbstractLoggerAdapter_1.AbstractLoggerAdapter
|
|
|
47
41
|
this._logger.setLevel(level);
|
|
48
42
|
}
|
|
49
43
|
debug(...messages) {
|
|
50
|
-
this.log(messages
|
|
44
|
+
this.log(messages, AbstractLoggerAdapter_1.LogLevel.DEBUG);
|
|
51
45
|
}
|
|
52
46
|
warn(...messages) {
|
|
53
|
-
this.log(messages
|
|
47
|
+
this.log(messages, AbstractLoggerAdapter_1.LogLevel.WARN);
|
|
54
48
|
}
|
|
55
49
|
info(...messages) {
|
|
56
|
-
this.log(messages
|
|
50
|
+
this.log(messages, AbstractLoggerAdapter_1.LogLevel.INFO);
|
|
57
51
|
}
|
|
58
52
|
error(...messages) {
|
|
59
|
-
this.log(messages
|
|
53
|
+
this.log(messages, AbstractLoggerAdapter_1.LogLevel.ERROR);
|
|
60
54
|
}
|
|
61
55
|
trace(...messages) {
|
|
62
|
-
this.log(messages
|
|
56
|
+
this.log(messages, AbstractLoggerAdapter_1.LogLevel.TRACE);
|
|
63
57
|
}
|
|
64
58
|
}
|
|
65
59
|
exports.DefaultLoggerAdapter = DefaultLoggerAdapter;
|
|
60
|
+
//# sourceMappingURL=DefaultLoggerAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DefaultLoggerAdapter.js","sourceRoot":"","sources":["../src/DefaultLoggerAdapter.ts"],"names":[],"mappings":";;;;;;AAAA,mEAAyE;AACzE,wDAA6B;AAC7B,kDAAyB;AAEzB,MAAa,oBAAqB,SAAQ,6CAAqB;IAC5D,YAAY,MAAM,GAAG,EAAE,EAAE,QAAkB,gCAAQ,CAAC,KAAK;QACtD,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QACpB,IAAI,CAAC,OAAO,GAAG,kBAAM,CAAA;QACrB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC/B,CAAC;IAOD,GAAG,CAAC,QAAe,EAAE,QAAkB,IAAI,CAAC,SAAS;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAA;QAE/C,QAAQ,KAAK,EAAE,CAAC;YACb,KAAK,gCAAQ,CAAC,KAAK;gBAChB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;gBACvC,MAAK;YACR,KAAK,gCAAQ,CAAC,KAAK;gBAChB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAA;gBACzC,MAAK;YACR,KAAK,gCAAQ,CAAC,IAAI;gBACf,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;gBACvC,MAAK;YACR,KAAK,gCAAQ,CAAC,IAAI;gBACf,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;gBACrC,MAAK;YACR,KAAK,gCAAQ,CAAC,KAAK;gBAChB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAA;gBAC9C,MAAK;YACR;gBACG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;gBACzB,MAAK;QACX,CAAC;IACJ,CAAC;IAED,QAAQ,CAAC,KAAe;QACrB,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACrB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC/B,CAAC;IAED,KAAK,CAAC,GAAG,QAAa;QACnB,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,gCAAQ,CAAC,KAAK,CAAC,CAAA;IACrC,CAAC;IAED,IAAI,CAAC,GAAG,QAAa;QAClB,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,gCAAQ,CAAC,IAAI,CAAC,CAAA;IACpC,CAAC;IAED,IAAI,CAAC,GAAG,QAAa;QAClB,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,gCAAQ,CAAC,IAAI,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,GAAG,QAAa;QACnB,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,gCAAQ,CAAC,KAAK,CAAC,CAAA;IACrC,CAAC;IAED,KAAK,CAAC,GAAG,QAAa;QACnB,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,gCAAQ,CAAC,KAAK,CAAC,CAAA;IACrC,CAAC;CACH;AA7DD,oDA6DC"}
|
package/dist/Log.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AbstractLoggerAdapter, LogLevel } from './AbstractLoggerAdapter';
|
|
2
|
+
export type LoggerRegistry<T extends AbstractLoggerAdapter> = {
|
|
3
|
+
[x: string]: T;
|
|
4
|
+
};
|
|
5
|
+
export declare class Log {
|
|
6
|
+
static defaultLogger: string;
|
|
7
|
+
protected static _loggers: LoggerRegistry<any>;
|
|
8
|
+
static timestamp(): string;
|
|
9
|
+
static addLogger(alias: string, logger?: AbstractLoggerAdapter, setDefault?: boolean): any;
|
|
10
|
+
static getLogger<T extends AbstractLoggerAdapter>(alias?: string): T;
|
|
11
|
+
static log(...messages: any[]): void;
|
|
12
|
+
static debug(...messages: any[]): void;
|
|
13
|
+
static warn(...messages: any[]): void;
|
|
14
|
+
static info(...messages: any[]): void;
|
|
15
|
+
static error(...messages: any[]): void;
|
|
16
|
+
static trace(...messages: any[]): void;
|
|
17
|
+
}
|
|
18
|
+
export { LogLevel };
|
|
19
|
+
//# sourceMappingURL=Log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Log.d.ts","sourceRoot":"","sources":["../src/Log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAGzE,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,qBAAqB,IAAI;IAC3D,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAA;CAChB,CAAA;AACD,qBAAa,GAAG;IACb,MAAM,CAAC,aAAa,SAAa;IAEjC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,CAAK;IAGnD,MAAM,CAAC,SAAS;IAIhB,MAAM,CAAC,SAAS,CACb,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,qBAAkD,EAC1D,UAAU,GAAE,OAAe;IAU9B,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,qBAAqB,EAC7C,KAAK,GAAE,MAA2B,GAClC,CAAC;IAgBJ,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;IAIpC,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;IAItC,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;IAIrC,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;IAIrC,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;IAItC,MAAM,CAAC,KAAK,CAAC,GAAG,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI;CAGxC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"}
|
package/dist/Log.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LogLevel = exports.Log = void 0;
|
|
4
|
+
const AbstractLoggerAdapter_1 = require("./AbstractLoggerAdapter");
|
|
5
|
+
Object.defineProperty(exports, "LogLevel", { enumerable: true, get: function () { return AbstractLoggerAdapter_1.LogLevel; } });
|
|
6
|
+
const DefaultLoggerAdapter_1 = require("./DefaultLoggerAdapter");
|
|
7
|
+
class Log {
|
|
8
|
+
static defaultLogger = '@default';
|
|
9
|
+
static _loggers = {};
|
|
10
|
+
static timestamp() {
|
|
11
|
+
return new Date().toISOString();
|
|
12
|
+
}
|
|
13
|
+
static addLogger(alias, logger = new DefaultLoggerAdapter_1.DefaultLoggerAdapter(), setDefault = false) {
|
|
14
|
+
this._loggers[alias] = logger;
|
|
15
|
+
if (setDefault) {
|
|
16
|
+
this.defaultLogger = alias;
|
|
17
|
+
}
|
|
18
|
+
return this._loggers[alias];
|
|
19
|
+
}
|
|
20
|
+
static getLogger(alias = this.defaultLogger) {
|
|
21
|
+
if (alias === '@default' && !this._loggers['@default']) {
|
|
22
|
+
this._loggers['@default'] = new DefaultLoggerAdapter_1.DefaultLoggerAdapter();
|
|
23
|
+
}
|
|
24
|
+
if (this._loggers[alias]) {
|
|
25
|
+
return this._loggers[alias];
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
throw new Error(`Unknown logger alias: '${alias}'`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
static log(...messages) {
|
|
32
|
+
return Log.getLogger().log(...messages);
|
|
33
|
+
}
|
|
34
|
+
static debug(...messages) {
|
|
35
|
+
return Log.getLogger().debug(...messages);
|
|
36
|
+
}
|
|
37
|
+
static warn(...messages) {
|
|
38
|
+
return Log.getLogger().warn(...messages);
|
|
39
|
+
}
|
|
40
|
+
static info(...messages) {
|
|
41
|
+
return Log.getLogger().info(...messages);
|
|
42
|
+
}
|
|
43
|
+
static error(...messages) {
|
|
44
|
+
return Log.getLogger().error(...messages);
|
|
45
|
+
}
|
|
46
|
+
static trace(...messages) {
|
|
47
|
+
return Log.getLogger().trace(...messages);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.Log = Log;
|
|
51
|
+
//# sourceMappingURL=Log.js.map
|
package/dist/Log.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Log.js","sourceRoot":"","sources":["../src/Log.ts"],"names":[],"mappings":";;;AAAA,mEAAyE;AAwEhE,yFAxEuB,gCAAQ,OAwEvB;AAvEjB,iEAA6D;AAK7D,MAAa,GAAG;IACb,MAAM,CAAC,aAAa,GAAG,UAAU,CAAA;IAEvB,MAAM,CAAC,QAAQ,GAAwB,EAAE,CAAA;IAGnD,MAAM,CAAC,SAAS;QACb,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAClC,CAAC;IAED,MAAM,CAAC,SAAS,CACb,KAAa,EACb,SAAgC,IAAI,2CAAoB,EAAE,EAC1D,aAAsB,KAAK;QAE3B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,MAAM,CAAA;QAC7B,IAAI,UAAU,EAAE,CAAC;YACd,IAAI,CAAC,aAAa,GAAG,KAAK,CAAA;QAC7B,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAED,MAAM,CAAC,SAAS,CACb,QAAgB,IAAI,CAAC,aAAa;QAElC,IAAI,KAAK,KAAK,UAAU,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,2CAAoB,EAAE,CAAA;QACzD,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAC9B,CAAC;aAAM,CAAC;YACL,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,GAAG,CAAC,CAAA;QACtD,CAAC;IACJ,CAAC;IAMD,MAAM,CAAC,GAAG,CAAC,GAAG,QAAe;QAC1B,OAAO,GAAG,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,GAAG,QAAe;QAC5B,OAAO,GAAG,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAA;IAC5C,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,GAAG,QAAe;QAC3B,OAAO,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAA;IAC3C,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,GAAG,QAAe;QAC3B,OAAO,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAA;IAC3C,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,GAAG,QAAe;QAC5B,OAAO,GAAG,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAA;IAC5C,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,GAAG,QAAe;QAC5B,OAAO,GAAG,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAA;IAC5C,CAAC;;AA/DJ,kBAgEC"}
|
package/{lib → dist}/index.d.ts
RENAMED
|
@@ -2,3 +2,4 @@ import { Log, LogLevel } from './Log';
|
|
|
2
2
|
import { AbstractLoggerAdapter } from './AbstractLoggerAdapter';
|
|
3
3
|
import { DefaultLoggerAdapter } from './DefaultLoggerAdapter';
|
|
4
4
|
export { Log, LogLevel, AbstractLoggerAdapter, DefaultLoggerAdapter };
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAE7D,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,CAAA"}
|
package/{lib → dist}/index.js
RENAMED
|
@@ -8,3 +8,4 @@ const AbstractLoggerAdapter_1 = require("./AbstractLoggerAdapter");
|
|
|
8
8
|
Object.defineProperty(exports, "AbstractLoggerAdapter", { enumerable: true, get: function () { return AbstractLoggerAdapter_1.AbstractLoggerAdapter; } });
|
|
9
9
|
const DefaultLoggerAdapter_1 = require("./DefaultLoggerAdapter");
|
|
10
10
|
Object.defineProperty(exports, "DefaultLoggerAdapter", { enumerable: true, get: function () { return DefaultLoggerAdapter_1.DefaultLoggerAdapter; } });
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+BAAqC;AAI5B,oFAJA,SAAG,OAIA;AAAE,yFAJA,cAAQ,OAIA;AAHtB,mEAA+D;AAGvC,sGAHf,6CAAqB,OAGe;AAF7C,iEAA6D;AAEd,qGAFtC,2CAAoB,OAEsC"}
|
package/package.json
CHANGED
|
@@ -1,39 +1,36 @@
|
|
|
1
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
|
-
"publish:process": "yarn version patch && yarn build && yarn npm publish --access public && yarn hash:persist"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
2
|
+
"name": "@quatrain/log",
|
|
3
|
+
"version": "1.1.2",
|
|
4
|
+
"description": "Logger for business apps",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bun": "src/index.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"LICENSE.md",
|
|
10
|
+
"dist/",
|
|
11
|
+
"src/",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"author": "Quatrain Développement SAS <developers@quatrain.com>",
|
|
15
|
+
"license": "AGPL-3.0-only",
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@tsconfig/recommended": "^1.0.1",
|
|
18
|
+
"@types/jest": "^30.0.0",
|
|
19
|
+
"@types/node": "^22.10.1",
|
|
20
|
+
"jest": "^30.2.0",
|
|
21
|
+
"trace-unhandled": "^2.0.1",
|
|
22
|
+
"ts-jest": "^29.4.1",
|
|
23
|
+
"ts-node": "^10.9.1",
|
|
24
|
+
"typescript": "^5.2.2"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"chalk": "^4.1.2",
|
|
28
|
+
"loglevel": "^1.9.2"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"test-ci": "jest --runInBand",
|
|
32
|
+
"build": "tsc",
|
|
33
|
+
"wbuild": "tsc --watch",
|
|
34
|
+
"bump-to": "yarn version"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export enum LogLevel {
|
|
2
|
+
TRACE = 0,
|
|
3
|
+
DEBUG = 1,
|
|
4
|
+
INFO = 2,
|
|
5
|
+
WARN = 3,
|
|
6
|
+
ERROR = 4,
|
|
7
|
+
SILENT = 5,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface LoggerType {
|
|
11
|
+
log(message: string): void
|
|
12
|
+
debug(message: string): void
|
|
13
|
+
warn(message: string): void
|
|
14
|
+
info(message: string): void
|
|
15
|
+
error(message: string): void
|
|
16
|
+
trace(message: string): void
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const loglevelNames = [
|
|
20
|
+
'TRACE',
|
|
21
|
+
'DEBUG',
|
|
22
|
+
'INFO',
|
|
23
|
+
'WARN',
|
|
24
|
+
'ERROR',
|
|
25
|
+
'SILENT',
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
export abstract class AbstractLoggerAdapter implements LoggerType {
|
|
29
|
+
protected _me: string = ''
|
|
30
|
+
protected _logLevel: LogLevel = LogLevel.WARN
|
|
31
|
+
protected _logger: any = undefined
|
|
32
|
+
|
|
33
|
+
constructor(prefix = '', level: LogLevel = LogLevel.WARN) {
|
|
34
|
+
this._me = prefix
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
logLevel(level: LogLevel) {
|
|
38
|
+
this._logLevel = level
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
formatLogMessage = (
|
|
42
|
+
messages: any[],
|
|
43
|
+
loglevel: LogLevel = LogLevel.INFO
|
|
44
|
+
): string => {
|
|
45
|
+
// Flatten nested arrays (from rest parameter spreading)
|
|
46
|
+
const flatMessages = messages.flat()
|
|
47
|
+
|
|
48
|
+
const prefix = `${new Date().toISOString()} - [${this._me}]`
|
|
49
|
+
const strs = flatMessages.map((message: any) => {
|
|
50
|
+
if (message instanceof Error) {
|
|
51
|
+
return message.stack || message.message
|
|
52
|
+
}
|
|
53
|
+
if (typeof message === 'object' && message !== null) {
|
|
54
|
+
return JSON.stringify(message)
|
|
55
|
+
}
|
|
56
|
+
return String(message)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
return `${prefix} ${strs.join(' ')}`
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Log message using defined logger
|
|
64
|
+
* @param message string | object
|
|
65
|
+
* @param level string
|
|
66
|
+
*/
|
|
67
|
+
log(...messages: any[]): void {
|
|
68
|
+
throw new Error(`This method needs to be implemtend in child class`)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
debug(...messages: any[]): void {
|
|
72
|
+
throw new Error(`This method needs to be implemtend in child class`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
warn(...messages: any[]): void {
|
|
76
|
+
throw new Error(`This method needs to be implemtend in child class`)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
info(...messages: any[]): void {
|
|
80
|
+
throw new Error(`This method needs to be implemtend in child class`)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
error(...messages: any[]): void {
|
|
84
|
+
throw new Error(`This method needs to be implemtend in child class`)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
trace(...messages: any[]): void {
|
|
88
|
+
throw new Error(`This method needs to be implemtend in child class`)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { DefaultLoggerAdapter } from './DefaultLoggerAdapter'
|
|
2
|
+
import { LogLevel } from './AbstractLoggerAdapter'
|
|
3
|
+
import logger from 'loglevel'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
|
|
6
|
+
jest.mock('loglevel', () => ({
|
|
7
|
+
setLevel: jest.fn(),
|
|
8
|
+
trace: jest.fn(),
|
|
9
|
+
debug: jest.fn(),
|
|
10
|
+
info: jest.fn(),
|
|
11
|
+
warn: jest.fn(),
|
|
12
|
+
error: jest.fn(),
|
|
13
|
+
log: jest.fn(),
|
|
14
|
+
}))
|
|
15
|
+
|
|
16
|
+
jest.mock('chalk', () => ({
|
|
17
|
+
grey: jest.fn((s) => s),
|
|
18
|
+
yellow: jest.fn((s) => s),
|
|
19
|
+
green: jest.fn((s) => s),
|
|
20
|
+
red: jest.fn((s) => s),
|
|
21
|
+
bgRedBright: jest.fn((s) => s),
|
|
22
|
+
}))
|
|
23
|
+
|
|
24
|
+
describe('DefaultLoggerAdapter', () => {
|
|
25
|
+
let adapter: DefaultLoggerAdapter
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
jest.clearAllMocks()
|
|
29
|
+
// Use Jest to mock the global Date
|
|
30
|
+
jest.useFakeTimers().setSystemTime(new Date('2023-01-01T00:00:00.000Z'))
|
|
31
|
+
adapter = new DefaultLoggerAdapter('TEST', LogLevel.DEBUG)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
jest.useRealTimers()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('should initialize and set the log level', () => {
|
|
39
|
+
expect(logger.setLevel).toHaveBeenCalledWith(LogLevel.DEBUG)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('should log debug messages with yellow color', () => {
|
|
43
|
+
adapter.debug('debug message')
|
|
44
|
+
expect(logger.debug).toHaveBeenCalledWith(
|
|
45
|
+
'2023-01-01T00:00:00.000Z - [TEST] debug message'
|
|
46
|
+
)
|
|
47
|
+
expect(chalk.yellow).toHaveBeenCalled()
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('should log info messages with green color', () => {
|
|
51
|
+
adapter.info('info message')
|
|
52
|
+
expect(logger.info).toHaveBeenCalledWith(
|
|
53
|
+
'2023-01-01T00:00:00.000Z - [TEST] info message'
|
|
54
|
+
)
|
|
55
|
+
expect(chalk.green).toHaveBeenCalled()
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('should log multiple arguments correctly', () => {
|
|
59
|
+
adapter.info('msg1', 'msg2', { key: 'val' })
|
|
60
|
+
expect(logger.info).toHaveBeenCalledWith(
|
|
61
|
+
expect.stringContaining('msg1 msg2 {"key":"val"}')
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('should format Error objects correctly', () => {
|
|
66
|
+
const error = new Error('test error')
|
|
67
|
+
adapter.error(error)
|
|
68
|
+
expect(logger.error).toHaveBeenCalledWith(
|
|
69
|
+
expect.stringContaining('test error')
|
|
70
|
+
)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('should not mutate the input messages array', () => {
|
|
74
|
+
const input = ['original message']
|
|
75
|
+
adapter.info(input)
|
|
76
|
+
expect(input).toHaveLength(1)
|
|
77
|
+
expect(input[0]).toBe('original message')
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('should log warn messages with red color', () => {
|
|
81
|
+
adapter.warn('warn message')
|
|
82
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
83
|
+
'2023-01-01T00:00:00.000Z - [TEST] warn message'
|
|
84
|
+
)
|
|
85
|
+
expect(chalk.red).toHaveBeenCalled()
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('should log error messages with bgRedBright color', () => {
|
|
89
|
+
adapter.error('error message')
|
|
90
|
+
expect(logger.error).toHaveBeenCalledWith(
|
|
91
|
+
'2023-01-01T00:00:00.000Z - [TEST] error message'
|
|
92
|
+
)
|
|
93
|
+
expect(chalk.bgRedBright).toHaveBeenCalled()
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('should log trace messages with grey color', () => {
|
|
97
|
+
adapter.trace('trace message')
|
|
98
|
+
expect(logger.trace).toHaveBeenCalledWith(
|
|
99
|
+
'2023-01-01T00:00:00.000Z - [TEST] trace message'
|
|
100
|
+
)
|
|
101
|
+
expect(chalk.grey).toHaveBeenCalled()
|
|
102
|
+
})
|
|
103
|
+
})
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { AbstractLoggerAdapter, LogLevel } from './AbstractLoggerAdapter'
|
|
2
|
+
import logger from 'loglevel'
|
|
3
|
+
import chalk from 'chalk'
|
|
4
|
+
|
|
5
|
+
export class DefaultLoggerAdapter extends AbstractLoggerAdapter {
|
|
6
|
+
constructor(prefix = '', level: LogLevel = LogLevel.DEBUG) {
|
|
7
|
+
super(prefix, level)
|
|
8
|
+
this._logger = logger
|
|
9
|
+
this._logger.setLevel(level)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Log message using defined logger
|
|
14
|
+
* @param messages array
|
|
15
|
+
* @param level LogLevel
|
|
16
|
+
*/
|
|
17
|
+
log(messages: any[], level: LogLevel = this._logLevel): void {
|
|
18
|
+
const message = this.formatLogMessage(messages)
|
|
19
|
+
|
|
20
|
+
switch (level) {
|
|
21
|
+
case LogLevel.TRACE:
|
|
22
|
+
this._logger.trace(chalk.grey(message))
|
|
23
|
+
break
|
|
24
|
+
case LogLevel.DEBUG:
|
|
25
|
+
this._logger.debug(chalk.yellow(message))
|
|
26
|
+
break
|
|
27
|
+
case LogLevel.INFO:
|
|
28
|
+
this._logger.info(chalk.green(message))
|
|
29
|
+
break
|
|
30
|
+
case LogLevel.WARN:
|
|
31
|
+
this._logger.warn(chalk.red(message))
|
|
32
|
+
break
|
|
33
|
+
case LogLevel.ERROR:
|
|
34
|
+
this._logger.error(chalk.bgRedBright(message))
|
|
35
|
+
break
|
|
36
|
+
default:
|
|
37
|
+
this._logger.log(message)
|
|
38
|
+
break
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
logLevel(level: LogLevel): void {
|
|
43
|
+
super.logLevel(level)
|
|
44
|
+
this._logger.setLevel(level)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
debug(...messages: any): void {
|
|
48
|
+
this.log(messages, LogLevel.DEBUG)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
warn(...messages: any): void {
|
|
52
|
+
this.log(messages, LogLevel.WARN)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
info(...messages: any): void {
|
|
56
|
+
this.log(messages, LogLevel.INFO)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
error(...messages: any): void {
|
|
60
|
+
this.log(messages, LogLevel.ERROR)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
trace(...messages: any): void {
|
|
64
|
+
this.log(messages, LogLevel.TRACE)
|
|
65
|
+
}
|
|
66
|
+
}
|
package/src/Log.test.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Log } from './Log'
|
|
2
|
+
import { DefaultLoggerAdapter } from './DefaultLoggerAdapter'
|
|
3
|
+
|
|
4
|
+
jest.mock('./DefaultLoggerAdapter')
|
|
5
|
+
|
|
6
|
+
describe('Log Class (Static Registry)', () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
jest.clearAllMocks()
|
|
9
|
+
// Reset the internal registry for clean tests
|
|
10
|
+
// @ts-ignore - accessing protected member for testing
|
|
11
|
+
Log._loggers = {}
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
it('should lazily initialize the @default logger on first access', () => {
|
|
15
|
+
// Ensure registry is empty
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
expect(Log._loggers['@default']).toBeUndefined()
|
|
18
|
+
|
|
19
|
+
const logger = Log.getLogger('@default')
|
|
20
|
+
|
|
21
|
+
expect(logger).toBeInstanceOf(DefaultLoggerAdapter)
|
|
22
|
+
expect(DefaultLoggerAdapter).toHaveBeenCalled()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('should correctly proxy multiple arguments to the underlying adapter', () => {
|
|
26
|
+
const logger = Log.getLogger('@default')
|
|
27
|
+
const infoSpy = jest.spyOn(logger, 'info').mockImplementation(() => {})
|
|
28
|
+
|
|
29
|
+
Log.info('arg1', 'arg2', { data: 123 })
|
|
30
|
+
|
|
31
|
+
expect(infoSpy).toHaveBeenCalledWith('arg1', 'arg2', { data: 123 })
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('should allow adding a custom logger and setting it as default', () => {
|
|
35
|
+
const customLogger = new DefaultLoggerAdapter('CUSTOM')
|
|
36
|
+
Log.addLogger('custom', customLogger, true)
|
|
37
|
+
|
|
38
|
+
expect(Log.defaultLogger).toBe('custom')
|
|
39
|
+
expect(Log.getLogger()).toBe(customLogger)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('should throw an error when requesting an unknown logger alias', () => {
|
|
43
|
+
expect(() => Log.getLogger('ghost-logger')).toThrow(/Unknown logger alias/)
|
|
44
|
+
})
|
|
45
|
+
})
|
package/src/Log.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { AbstractLoggerAdapter, LogLevel } from './AbstractLoggerAdapter'
|
|
2
|
+
import { DefaultLoggerAdapter } from './DefaultLoggerAdapter'
|
|
3
|
+
|
|
4
|
+
export type LoggerRegistry<T extends AbstractLoggerAdapter> = {
|
|
5
|
+
[x: string]: T
|
|
6
|
+
}
|
|
7
|
+
export class Log {
|
|
8
|
+
static defaultLogger = '@default'
|
|
9
|
+
|
|
10
|
+
protected static _loggers: LoggerRegistry<any> = {}
|
|
11
|
+
|
|
12
|
+
// How timestamp are formatted
|
|
13
|
+
static timestamp() {
|
|
14
|
+
return new Date().toISOString()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static addLogger(
|
|
18
|
+
alias: string,
|
|
19
|
+
logger: AbstractLoggerAdapter = new DefaultLoggerAdapter(),
|
|
20
|
+
setDefault: boolean = false
|
|
21
|
+
) {
|
|
22
|
+
this._loggers[alias] = logger
|
|
23
|
+
if (setDefault) {
|
|
24
|
+
this.defaultLogger = alias
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return this._loggers[alias]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static getLogger<T extends AbstractLoggerAdapter>(
|
|
31
|
+
alias: string = this.defaultLogger
|
|
32
|
+
): T {
|
|
33
|
+
if (alias === '@default' && !this._loggers['@default']) {
|
|
34
|
+
this._loggers['@default'] = new DefaultLoggerAdapter()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (this._loggers[alias]) {
|
|
38
|
+
return this._loggers[alias]
|
|
39
|
+
} else {
|
|
40
|
+
throw new Error(`Unknown logger alias: '${alias}'`)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Log message using defined logger
|
|
46
|
+
* @param message string | object
|
|
47
|
+
*/
|
|
48
|
+
static log(...messages: any[]): void {
|
|
49
|
+
return Log.getLogger().log(...messages)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static debug(...messages: any[]): void {
|
|
53
|
+
return Log.getLogger().debug(...messages)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static warn(...messages: any[]): void {
|
|
57
|
+
return Log.getLogger().warn(...messages)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static info(...messages: any[]): void {
|
|
61
|
+
return Log.getLogger().info(...messages)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static error(...messages: any[]): void {
|
|
65
|
+
return Log.getLogger().error(...messages)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static trace(...messages: any[]): void {
|
|
69
|
+
return Log.getLogger().trace(...messages)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { LogLevel }
|
package/src/index.ts
ADDED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AbstractLoggerAdapter = exports.loglevelNames = void 0;
|
|
4
|
-
const Log_1 = require("./Log");
|
|
5
|
-
exports.loglevelNames = [
|
|
6
|
-
'TRACE',
|
|
7
|
-
'DEBUG',
|
|
8
|
-
'INFO',
|
|
9
|
-
'WARN',
|
|
10
|
-
'ERROR',
|
|
11
|
-
'SILENT',
|
|
12
|
-
];
|
|
13
|
-
class AbstractLoggerAdapter {
|
|
14
|
-
constructor(prefix = '', level = Log_1.LogLevel.WARN) {
|
|
15
|
-
this._me = '';
|
|
16
|
-
this._logLevel = Log_1.LogLevel.WARN;
|
|
17
|
-
this._logger = undefined;
|
|
18
|
-
this.formatLogMessage = (messages, loglevel = 3) => {
|
|
19
|
-
if (!Array.isArray(messages)) {
|
|
20
|
-
messages = [messages];
|
|
21
|
-
}
|
|
22
|
-
messages.unshift(`${Log_1.Log.timestamp()} - [${this._me}]`);
|
|
23
|
-
const strs = messages.map((message) => {
|
|
24
|
-
return typeof message !== 'object' ? message : JSON.stringify(message);
|
|
25
|
-
});
|
|
26
|
-
return strs.join(' ');
|
|
27
|
-
};
|
|
28
|
-
this._me = prefix;
|
|
29
|
-
}
|
|
30
|
-
logLevel(level) {
|
|
31
|
-
this._logLevel = level;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Log message using defined logger
|
|
35
|
-
* @param message string | object
|
|
36
|
-
* @param level string
|
|
37
|
-
*/
|
|
38
|
-
log(...messages) {
|
|
39
|
-
throw new Error(`This method needs to be implemtend in child class`);
|
|
40
|
-
}
|
|
41
|
-
debug(message) {
|
|
42
|
-
throw new Error(`This method needs to be implemtend in child class`);
|
|
43
|
-
}
|
|
44
|
-
warn(message) {
|
|
45
|
-
throw new Error(`This method needs to be implemtend in child class`);
|
|
46
|
-
}
|
|
47
|
-
info(message) {
|
|
48
|
-
throw new Error(`This method needs to be implemtend in child class`);
|
|
49
|
-
}
|
|
50
|
-
error(message) {
|
|
51
|
-
throw new Error(`This method needs to be implemtend in child class`);
|
|
52
|
-
}
|
|
53
|
-
trace(message) {
|
|
54
|
-
throw new Error(`This method needs to be implemtend in child class`);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
exports.AbstractLoggerAdapter = AbstractLoggerAdapter;
|
package/lib/Log.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { AbstractLoggerAdapter } from './AbstractLoggerAdapter';
|
|
2
|
-
export declare enum LogLevel {
|
|
3
|
-
TRACE = 0,
|
|
4
|
-
DEBUG = 1,
|
|
5
|
-
INFO = 2,
|
|
6
|
-
WARN = 3,
|
|
7
|
-
ERROR = 4,
|
|
8
|
-
SILENT = 5
|
|
9
|
-
}
|
|
10
|
-
export type LoggerRegistry<T extends AbstractLoggerAdapter> = {
|
|
11
|
-
[x: string]: T;
|
|
12
|
-
};
|
|
13
|
-
export declare class Log {
|
|
14
|
-
static defaultLogger: string;
|
|
15
|
-
protected static _loggers: LoggerRegistry<any>;
|
|
16
|
-
static timestamp(): string;
|
|
17
|
-
static addLogger(alias: string, logger?: AbstractLoggerAdapter, setDefault?: boolean): any;
|
|
18
|
-
static getLogger<T extends AbstractLoggerAdapter>(alias?: string): T;
|
|
19
|
-
/**
|
|
20
|
-
* Log message using defined logger
|
|
21
|
-
* @param message string | object
|
|
22
|
-
*/
|
|
23
|
-
static log(message: any): void;
|
|
24
|
-
static debug(message: any): void;
|
|
25
|
-
static warn(message: any): void;
|
|
26
|
-
static info(message: any): void;
|
|
27
|
-
static error(message: any): void;
|
|
28
|
-
static trace(message: any): void;
|
|
29
|
-
}
|
package/lib/Log.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Log = exports.LogLevel = void 0;
|
|
4
|
-
const DefaultLoggerAdapter_1 = require("./DefaultLoggerAdapter");
|
|
5
|
-
var LogLevel;
|
|
6
|
-
(function (LogLevel) {
|
|
7
|
-
LogLevel[LogLevel["TRACE"] = 0] = "TRACE";
|
|
8
|
-
LogLevel[LogLevel["DEBUG"] = 1] = "DEBUG";
|
|
9
|
-
LogLevel[LogLevel["INFO"] = 2] = "INFO";
|
|
10
|
-
LogLevel[LogLevel["WARN"] = 3] = "WARN";
|
|
11
|
-
LogLevel[LogLevel["ERROR"] = 4] = "ERROR";
|
|
12
|
-
LogLevel[LogLevel["SILENT"] = 5] = "SILENT";
|
|
13
|
-
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
|
14
|
-
class Log {
|
|
15
|
-
// How timestamp are formatted
|
|
16
|
-
static timestamp() {
|
|
17
|
-
return new Date().toISOString();
|
|
18
|
-
}
|
|
19
|
-
static addLogger(alias, logger = new DefaultLoggerAdapter_1.DefaultLoggerAdapter(), setDefault = false) {
|
|
20
|
-
this._loggers[alias] = logger;
|
|
21
|
-
if (setDefault) {
|
|
22
|
-
this.defaultLogger = alias;
|
|
23
|
-
}
|
|
24
|
-
return this._loggers[alias];
|
|
25
|
-
}
|
|
26
|
-
static getLogger(alias = this.defaultLogger) {
|
|
27
|
-
if (this._loggers[alias]) {
|
|
28
|
-
return this._loggers[alias];
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
throw new Error(`Unknown logger alias: '${alias}'`);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Log message using defined logger
|
|
36
|
-
* @param message string | object
|
|
37
|
-
*/
|
|
38
|
-
static log(message) {
|
|
39
|
-
return Log.getLogger().log(message);
|
|
40
|
-
}
|
|
41
|
-
static debug(message) {
|
|
42
|
-
return Log.getLogger().debug(message);
|
|
43
|
-
}
|
|
44
|
-
static warn(message) {
|
|
45
|
-
return Log.getLogger().warn(message);
|
|
46
|
-
}
|
|
47
|
-
static info(message) {
|
|
48
|
-
return Log.getLogger().info(message);
|
|
49
|
-
}
|
|
50
|
-
static error(message) {
|
|
51
|
-
return Log.getLogger().error(message);
|
|
52
|
-
}
|
|
53
|
-
static trace(message) {
|
|
54
|
-
return Log.getLogger().trace(message);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
exports.Log = Log;
|
|
58
|
-
Log.defaultLogger = '@default';
|
|
59
|
-
Log._loggers = {
|
|
60
|
-
'@default': new DefaultLoggerAdapter_1.DefaultLoggerAdapter(),
|
|
61
|
-
};
|