@hg-ts/logger 0.7.27 → 0.8.1
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/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/logger/base.formatter.d.ts +4 -1
- package/dist/logger/base.formatter.d.ts.map +1 -1
- package/dist/logger/base.formatter.js +29 -20
- package/dist/logger/base.formatter.js.map +1 -1
- package/dist/logger/base.logger.d.ts +20 -9
- package/dist/logger/base.logger.d.ts.map +1 -1
- package/dist/logger/base.logger.js +114 -22
- package/dist/logger/base.logger.js.map +1 -1
- package/dist/logger/console.logger.d.ts.map +1 -1
- package/dist/logger/console.logger.js +8 -1
- package/dist/logger/console.logger.js.map +1 -1
- package/dist/logger/console.logger.test.d.ts +9 -0
- package/dist/logger/console.logger.test.d.ts.map +1 -0
- package/dist/logger/console.logger.test.js +42 -0
- package/dist/logger/console.logger.test.js.map +1 -0
- package/dist/logger/index.d.ts +1 -1
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +1 -1
- package/dist/logger/index.js.map +1 -1
- package/dist/logger/json.logger.test.d.ts +8 -0
- package/dist/logger/json.logger.test.d.ts.map +1 -0
- package/dist/logger/json.logger.test.js +45 -0
- package/dist/logger/json.logger.test.js.map +1 -0
- package/dist/logger/logger.d.ts +18 -8
- package/dist/logger/logger.d.ts.map +1 -1
- package/dist/logger/logger.js.map +1 -1
- package/dist/nest-wrapped.logger.d.ts.map +1 -1
- package/dist/nest-wrapped.logger.js +15 -6
- package/dist/nest-wrapped.logger.js.map +1 -1
- package/package.json +15 -8
- package/src/index.ts +3 -0
- package/src/logger/base.formatter.ts +43 -24
- package/src/logger/base.logger.ts +198 -23
- package/src/logger/console.logger.test.ts +56 -0
- package/src/logger/console.logger.ts +10 -1
- package/src/logger/index.ts +6 -1
- package/src/logger/json.logger.test.ts +59 -0
- package/src/logger/logger.ts +26 -8
- package/src/nest-wrapped.logger.ts +17 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nest-wrapped.logger.d.ts","sourceRoot":"","sources":["../src/nest-wrapped.logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"nest-wrapped.logger.d.ts","sourceRoot":"","sources":["../src/nest-wrapped.logger.ts"],"names":[],"mappings":"AACA,OAAO,EAGN,aAAa,EACb,YAAY,EACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,qBAAa,iBAAkB,YAAW,aAAa,EAAE,YAAY;IAEpE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAE3B,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG;IAK1C,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG;IAe1D,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG;IAKxC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG;IAK5C,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG;IAMnC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ1C,OAAO,CAAC,kBAAkB;CAG1B"}
|
|
@@ -1,27 +1,36 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import { BaseException } from '@hg-ts/exception';
|
|
2
3
|
import { Inject, Logger as NestLogger, } from '@nestjs/common';
|
|
3
4
|
import { Logger } from './logger/index.js';
|
|
4
5
|
export class NestWrappedLogger {
|
|
5
6
|
logger;
|
|
6
7
|
debug(message, context) {
|
|
7
8
|
this.setOptionalContext(context);
|
|
8
|
-
this.logger.debug(message);
|
|
9
|
+
this.logger.debug(String(message));
|
|
9
10
|
}
|
|
10
11
|
error(message, trace, context) {
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
if (message instanceof Error) {
|
|
13
|
+
this.setOptionalContext(context);
|
|
14
|
+
const exception = message instanceof BaseException
|
|
15
|
+
? message
|
|
16
|
+
: BaseException.fromError(message);
|
|
17
|
+
this.logger.error(exception, trace ?? message.message);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
this.setOptionalContext(trace);
|
|
21
|
+
this.logger.error(String(message));
|
|
13
22
|
}
|
|
14
23
|
log(message, context) {
|
|
15
24
|
this.setOptionalContext(context);
|
|
16
|
-
this.logger.info(message);
|
|
25
|
+
this.logger.info(String(message));
|
|
17
26
|
}
|
|
18
27
|
verbose(message, context) {
|
|
19
28
|
this.setOptionalContext(context);
|
|
20
|
-
this.logger.notice(message);
|
|
29
|
+
this.logger.notice(String(message));
|
|
21
30
|
}
|
|
22
31
|
warn(message, context) {
|
|
23
32
|
this.setOptionalContext(context);
|
|
24
|
-
this.logger.warning(message);
|
|
33
|
+
this.logger.warning(String(message));
|
|
25
34
|
}
|
|
26
35
|
async onModuleInit() {
|
|
27
36
|
this.logger.setContext(null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nest-wrapped.logger.js","sourceRoot":"","sources":["../src/nest-wrapped.logger.ts"],"names":[],"mappings":";AAAA,OAAO,EACN,MAAM,EACN,MAAM,IAAI,UAAU,GAGpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,MAAM,OAAO,iBAAiB;IAEV,MAAM,CAAS;IAE3B,KAAK,CAAC,OAAY,EAAE,OAAgB;QAC1C,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"nest-wrapped.logger.js","sourceRoot":"","sources":["../src/nest-wrapped.logger.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACN,MAAM,EACN,MAAM,IAAI,UAAU,GAGpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,MAAM,OAAO,iBAAiB;IAEV,MAAM,CAAS;IAE3B,KAAK,CAAC,OAAY,EAAE,OAAgB;QAC1C,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACpC,CAAC;IAEM,KAAK,CAAC,OAAY,EAAE,KAAc,EAAE,OAAgB;QAC1D,IAAI,OAAO,YAAY,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACjC,MAAM,SAAS,GAAG,OAAO,YAAY,aAAa;gBACjD,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAEpC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;YACvD,OAAO;QACR,CAAC;QAED,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACpC,CAAC;IAEM,GAAG,CAAC,OAAY,EAAE,OAAgB;QACxC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACnC,CAAC;IAEM,OAAO,CAAC,OAAY,EAAE,OAAgB;QAC5C,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACrC,CAAC;IAEM,IAAI,CAAC,OAAY,EAAE,OAAgB;QACzC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACtC,CAAC;IAGM,KAAK,CAAC,YAAY;QACxB,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC7B,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAChC,UAAU,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACxE,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAChC,UAAU,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAEO,kBAAkB,CAAC,UAA4B,IAAI;QAC1D,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;CACD;AAjDmB;IADlB,MAAM,EAAE;8BACkB,MAAM;iDAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hg-ts/logger",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -13,27 +13,33 @@
|
|
|
13
13
|
"build": "tsc",
|
|
14
14
|
"build:dev": "tsc-watch",
|
|
15
15
|
"lint:ts": "lint-ts",
|
|
16
|
-
"lint:ts:fix": "lint-ts --fix"
|
|
16
|
+
"lint:ts:fix": "lint-ts --fix",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:dev": "vitest watch"
|
|
17
19
|
},
|
|
18
20
|
"devDependencies": {
|
|
19
|
-
"@hg-ts-config/typescript": "0.
|
|
20
|
-
"@hg-ts/async-context": "0.
|
|
21
|
-
"@hg-ts/execution-mode": "0.
|
|
22
|
-
"@hg-ts/linter": "0.
|
|
23
|
-
"@hg-ts/
|
|
21
|
+
"@hg-ts-config/typescript": "0.8.1",
|
|
22
|
+
"@hg-ts/async-context": "0.8.1",
|
|
23
|
+
"@hg-ts/execution-mode": "0.8.1",
|
|
24
|
+
"@hg-ts/linter": "0.8.1",
|
|
25
|
+
"@hg-ts/tests": "0.8.1",
|
|
26
|
+
"@hg-ts/types": "0.8.1",
|
|
24
27
|
"@nestjs/common": "11.1.0",
|
|
25
28
|
"@nestjs/core": "11.1.0",
|
|
26
29
|
"@types/node": "22.19.1",
|
|
27
30
|
"@types/triple-beam": "1.3.5",
|
|
31
|
+
"@vitest/coverage-v8": "4.0.14",
|
|
28
32
|
"eslint": "9.18.0",
|
|
29
33
|
"reflect-metadata": "0.2.2",
|
|
30
34
|
"rxjs": "7.8.1",
|
|
31
35
|
"tsc-watch": "6.3.0",
|
|
32
36
|
"tslib": "2.8.1",
|
|
33
|
-
"typescript": "5.7.3"
|
|
37
|
+
"typescript": "5.7.3",
|
|
38
|
+
"vitest": "4.0.14"
|
|
34
39
|
},
|
|
35
40
|
"peerDependencies": {
|
|
36
41
|
"@hg-ts/async-context": "*",
|
|
42
|
+
"@hg-ts/exception": "*",
|
|
37
43
|
"@hg-ts/execution-mode": "*",
|
|
38
44
|
"@hg-ts/types": "*",
|
|
39
45
|
"@nestjs/common": "*",
|
|
@@ -43,6 +49,7 @@
|
|
|
43
49
|
"tslib": "*"
|
|
44
50
|
},
|
|
45
51
|
"dependencies": {
|
|
52
|
+
"@hg-ts/exception": "0.8.1",
|
|
46
53
|
"triple-beam": "1.4.1",
|
|
47
54
|
"winston": "3.17.0",
|
|
48
55
|
"winston-syslog": "2.7.1"
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import * as assert from 'node:assert';
|
|
2
|
+
import {
|
|
3
|
+
BaseException,
|
|
4
|
+
type JSONBaseException,
|
|
5
|
+
} from '@hg-ts/exception';
|
|
2
6
|
import winston from 'winston';
|
|
3
7
|
import {
|
|
4
8
|
LogLevel,
|
|
@@ -9,21 +13,43 @@ export type LogMessage = winston.Logform.TransformableInfo & {
|
|
|
9
13
|
context: Nullable<string>;
|
|
10
14
|
message: string;
|
|
11
15
|
level: LogLevel;
|
|
16
|
+
meta?: Record<string, unknown>;
|
|
17
|
+
error?: JSONBaseException;
|
|
18
|
+
traceId?: string;
|
|
12
19
|
process: {
|
|
13
20
|
pid: number;
|
|
14
21
|
title: Nullable<string>;
|
|
15
22
|
};
|
|
16
23
|
timestamp: Date;
|
|
17
|
-
items: unknown[];
|
|
18
24
|
};
|
|
19
25
|
|
|
26
|
+
function serializeMeta(meta: unknown): Nullable<Record<string, unknown>> {
|
|
27
|
+
if (!meta || typeof meta !== 'object' || Array.isArray(meta)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return meta as Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function serializeError(error: unknown): Nullable<JSONBaseException> {
|
|
35
|
+
if (!(error instanceof BaseException)) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return error.toJSON();
|
|
40
|
+
}
|
|
41
|
+
|
|
20
42
|
function getLogData(info: winston.Logform.TransformableInfo): LogMessage {
|
|
21
43
|
const level = syslogToLoggerMap.get(info.level) ?? info.level as LogLevel;
|
|
22
44
|
const context = info['context'] ?? null;
|
|
45
|
+
const meta = serializeMeta(info['meta']);
|
|
46
|
+
const error = serializeError(info['error']);
|
|
47
|
+
const { traceId } = info;
|
|
23
48
|
|
|
24
49
|
assert.ok(typeof context === 'string' || context === null);
|
|
50
|
+
assert.ok(typeof traceId === 'string' || typeof traceId === 'undefined');
|
|
25
51
|
|
|
26
|
-
|
|
52
|
+
const logData: LogMessage = {
|
|
27
53
|
level,
|
|
28
54
|
context,
|
|
29
55
|
process: {
|
|
@@ -31,32 +57,25 @@ function getLogData(info: winston.Logform.TransformableInfo): LogMessage {
|
|
|
31
57
|
title: process.title.endsWith('node') ? null : process.title,
|
|
32
58
|
},
|
|
33
59
|
message: info.message as string,
|
|
34
|
-
items: Array.isArray(info['items']) ? info['items'] : [info['items']],
|
|
35
60
|
timestamp: new Date(),
|
|
36
61
|
};
|
|
37
|
-
}
|
|
38
62
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
message: item.message,
|
|
52
|
-
stack: item.stack,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return item;
|
|
57
|
-
});
|
|
63
|
+
if (meta) {
|
|
64
|
+
logData.meta = meta;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (error) {
|
|
68
|
+
logData.error = error;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (traceId) {
|
|
72
|
+
logData.traceId = traceId;
|
|
73
|
+
}
|
|
74
|
+
|
|
58
75
|
return logData;
|
|
59
|
-
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const baseFormatter = winston.format(info => getLogData(info));
|
|
60
79
|
|
|
61
80
|
export function createFormatter(formatter: (info: LogMessage) => LogMessage): winston.Logform.FormatWrap {
|
|
62
81
|
return winston.format(formatter as any);
|
|
@@ -1,10 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseException } from '@hg-ts/exception';
|
|
2
2
|
import winston from 'winston';
|
|
3
3
|
import { TraceContext } from '../trace.context.js';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
InlineMeta,
|
|
7
|
+
InlineMetaPrimitive,
|
|
8
|
+
Logger,
|
|
9
|
+
LogMeta,
|
|
10
|
+
} from './logger.js';
|
|
6
11
|
|
|
7
12
|
type Transport = winston.Logger['add'] extends (transport: infer R) => void ? R : never;
|
|
13
|
+
type LogOptions = {
|
|
14
|
+
error?: BaseException;
|
|
15
|
+
meta: Optional<LogMeta>;
|
|
16
|
+
inlineMeta: Optional<InlineMeta>;
|
|
17
|
+
};
|
|
18
|
+
type ErrorLogOptions = {
|
|
19
|
+
errorOrMessage: BaseException | string;
|
|
20
|
+
messageOrMeta: Optional<string | LogMeta>;
|
|
21
|
+
metaOrInlineMeta: Optional<LogMeta | InlineMeta>;
|
|
22
|
+
inlineMeta: Optional<InlineMeta>;
|
|
23
|
+
};
|
|
24
|
+
type NormalizedLogPayload = LogOptions & { message: string };
|
|
8
25
|
|
|
9
26
|
export type LogLevel = keyof Omit<Logger, 'setContext'>;
|
|
10
27
|
|
|
@@ -36,29 +53,103 @@ export abstract class BaseLogger implements Logger {
|
|
|
36
53
|
});
|
|
37
54
|
}
|
|
38
55
|
|
|
39
|
-
public debug(
|
|
40
|
-
this.log('debug',
|
|
56
|
+
public debug(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void {
|
|
57
|
+
this.log('debug', message, {
|
|
58
|
+
meta,
|
|
59
|
+
inlineMeta,
|
|
60
|
+
});
|
|
41
61
|
}
|
|
42
|
-
public info(
|
|
43
|
-
this.log('info',
|
|
62
|
+
public info(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void {
|
|
63
|
+
this.log('info', message, {
|
|
64
|
+
meta,
|
|
65
|
+
inlineMeta,
|
|
66
|
+
});
|
|
44
67
|
}
|
|
45
|
-
public notice(
|
|
46
|
-
this.log('notice',
|
|
68
|
+
public notice(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void {
|
|
69
|
+
this.log('notice', message, {
|
|
70
|
+
meta,
|
|
71
|
+
inlineMeta,
|
|
72
|
+
});
|
|
47
73
|
}
|
|
48
|
-
public warning(
|
|
49
|
-
|
|
74
|
+
public warning(error: BaseException, message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
75
|
+
public warning(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
76
|
+
// eslint-disable-next-line max-params
|
|
77
|
+
public warning(
|
|
78
|
+
errorOrMessage: BaseException | string,
|
|
79
|
+
messageOrMeta?: string | LogMeta,
|
|
80
|
+
metaOrInlineMeta?: LogMeta | InlineMeta,
|
|
81
|
+
inlineMeta?: InlineMeta,
|
|
82
|
+
): void {
|
|
83
|
+
this.logErrorLevel('warning', {
|
|
84
|
+
errorOrMessage,
|
|
85
|
+
messageOrMeta,
|
|
86
|
+
metaOrInlineMeta,
|
|
87
|
+
inlineMeta,
|
|
88
|
+
});
|
|
50
89
|
}
|
|
51
|
-
public error(
|
|
52
|
-
|
|
90
|
+
public error(error: BaseException, message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
91
|
+
public error(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
92
|
+
// eslint-disable-next-line max-params
|
|
93
|
+
public error(
|
|
94
|
+
errorOrMessage: BaseException | string,
|
|
95
|
+
messageOrMeta?: string | LogMeta,
|
|
96
|
+
metaOrInlineMeta?: LogMeta | InlineMeta,
|
|
97
|
+
inlineMeta?: InlineMeta,
|
|
98
|
+
): void {
|
|
99
|
+
this.logErrorLevel('error', {
|
|
100
|
+
errorOrMessage,
|
|
101
|
+
messageOrMeta,
|
|
102
|
+
metaOrInlineMeta,
|
|
103
|
+
inlineMeta,
|
|
104
|
+
});
|
|
53
105
|
}
|
|
54
|
-
public critical(
|
|
55
|
-
|
|
106
|
+
public critical(error: BaseException, message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
107
|
+
public critical(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
108
|
+
// eslint-disable-next-line max-params
|
|
109
|
+
public critical(
|
|
110
|
+
errorOrMessage: BaseException | string,
|
|
111
|
+
messageOrMeta?: string | LogMeta,
|
|
112
|
+
metaOrInlineMeta?: LogMeta | InlineMeta,
|
|
113
|
+
inlineMeta?: InlineMeta,
|
|
114
|
+
): void {
|
|
115
|
+
this.logErrorLevel('critical', {
|
|
116
|
+
errorOrMessage,
|
|
117
|
+
messageOrMeta,
|
|
118
|
+
metaOrInlineMeta,
|
|
119
|
+
inlineMeta,
|
|
120
|
+
});
|
|
56
121
|
}
|
|
57
|
-
public alert(
|
|
58
|
-
|
|
122
|
+
public alert(error: BaseException, message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
123
|
+
public alert(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
124
|
+
// eslint-disable-next-line max-params
|
|
125
|
+
public alert(
|
|
126
|
+
errorOrMessage: BaseException | string,
|
|
127
|
+
messageOrMeta?: string | LogMeta,
|
|
128
|
+
metaOrInlineMeta?: LogMeta | InlineMeta,
|
|
129
|
+
inlineMeta?: InlineMeta,
|
|
130
|
+
): void {
|
|
131
|
+
this.logErrorLevel('alert', {
|
|
132
|
+
errorOrMessage,
|
|
133
|
+
messageOrMeta,
|
|
134
|
+
metaOrInlineMeta,
|
|
135
|
+
inlineMeta,
|
|
136
|
+
});
|
|
59
137
|
}
|
|
60
|
-
public emergency(
|
|
61
|
-
|
|
138
|
+
public emergency(error: BaseException, message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
139
|
+
public emergency(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
140
|
+
// eslint-disable-next-line max-params
|
|
141
|
+
public emergency(
|
|
142
|
+
errorOrMessage: BaseException | string,
|
|
143
|
+
messageOrMeta?: string | LogMeta,
|
|
144
|
+
metaOrInlineMeta?: LogMeta | InlineMeta,
|
|
145
|
+
inlineMeta?: InlineMeta,
|
|
146
|
+
): void {
|
|
147
|
+
this.logErrorLevel('emergency', {
|
|
148
|
+
errorOrMessage,
|
|
149
|
+
messageOrMeta,
|
|
150
|
+
metaOrInlineMeta,
|
|
151
|
+
inlineMeta,
|
|
152
|
+
});
|
|
62
153
|
}
|
|
63
154
|
|
|
64
155
|
public setContext(context: Nullable<string>): void {
|
|
@@ -69,15 +160,99 @@ export abstract class BaseLogger implements Logger {
|
|
|
69
160
|
this.logger.add(transport);
|
|
70
161
|
}
|
|
71
162
|
|
|
72
|
-
private
|
|
163
|
+
private logErrorLevel(level: LogLevel, args: ErrorLogOptions): void {
|
|
164
|
+
const payload = this.normalizeErrorLogPayload(args);
|
|
165
|
+
const options: LogOptions = {
|
|
166
|
+
meta: payload.meta,
|
|
167
|
+
inlineMeta: payload.inlineMeta,
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
if (payload.error) {
|
|
171
|
+
options.error = payload.error;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
this.log(level, payload.message, options);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private log(level: LogLevel, message: string, options: LogOptions): void {
|
|
178
|
+
const {
|
|
179
|
+
error,
|
|
180
|
+
meta,
|
|
181
|
+
inlineMeta,
|
|
182
|
+
} = options;
|
|
73
183
|
const mappedLevel = loggerToSyslogMap.get(level) ?? level;
|
|
74
184
|
|
|
75
|
-
|
|
185
|
+
const payload: winston.LogEntry = {
|
|
76
186
|
level: mappedLevel,
|
|
77
|
-
message:
|
|
78
|
-
items: messages,
|
|
187
|
+
message: `${message}${this.formatInlineMeta(inlineMeta)}`,
|
|
79
188
|
context: this.context,
|
|
80
189
|
traceId: this.traceContext.get()?.traceId,
|
|
81
|
-
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
if (meta) {
|
|
193
|
+
payload['meta'] = meta;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (error) {
|
|
197
|
+
payload['error'] = error;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
this.logger.log(payload);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private normalizeErrorLogPayload(args: ErrorLogOptions): NormalizedLogPayload {
|
|
204
|
+
const {
|
|
205
|
+
errorOrMessage,
|
|
206
|
+
messageOrMeta,
|
|
207
|
+
metaOrInlineMeta,
|
|
208
|
+
inlineMeta,
|
|
209
|
+
} = args;
|
|
210
|
+
|
|
211
|
+
if (errorOrMessage instanceof BaseException) {
|
|
212
|
+
return {
|
|
213
|
+
error: errorOrMessage,
|
|
214
|
+
message: messageOrMeta as string,
|
|
215
|
+
meta: metaOrInlineMeta as LogMeta,
|
|
216
|
+
inlineMeta,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return {
|
|
221
|
+
message: errorOrMessage,
|
|
222
|
+
meta: messageOrMeta as LogMeta,
|
|
223
|
+
inlineMeta: metaOrInlineMeta as InlineMeta,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private formatInlineMeta(inlineMeta: Optional<InlineMeta>): string {
|
|
228
|
+
if (!inlineMeta || Object.keys(inlineMeta).length === 0) {
|
|
229
|
+
return '';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const items = Object
|
|
233
|
+
.entries(inlineMeta)
|
|
234
|
+
.map(([key, value]) => `${key}=${this.formatInlineMetaValue(value)}`);
|
|
235
|
+
|
|
236
|
+
return `: ${items.join(', ')}`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private formatInlineMetaValue(value: InlineMeta[keyof InlineMeta]): string {
|
|
240
|
+
if (Array.isArray(value)) {
|
|
241
|
+
return `[${value.map(item => this.formatInlineMetaPrimitive(item)).join(',')}]`;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return this.formatInlineMetaPrimitive(value);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
private formatInlineMetaPrimitive(value: InlineMetaPrimitive): string {
|
|
248
|
+
if (value instanceof Date) {
|
|
249
|
+
return value.toISOString();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (Buffer.isBuffer(value)) {
|
|
253
|
+
return value.toString('base64');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return String(value);
|
|
82
257
|
}
|
|
83
258
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Describe,
|
|
3
|
+
expect,
|
|
4
|
+
Suite,
|
|
5
|
+
Test,
|
|
6
|
+
} from '@hg-ts/tests';
|
|
7
|
+
import { vi } from 'vitest';
|
|
8
|
+
|
|
9
|
+
type ConsoleStdout = {
|
|
10
|
+
_stdout: {
|
|
11
|
+
write: typeof process.stdout.write;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
@Describe()
|
|
16
|
+
export class ConsoleLoggerTest extends Suite {
|
|
17
|
+
private output: string[] = [];
|
|
18
|
+
|
|
19
|
+
@Test()
|
|
20
|
+
public async writesMessageInlineMetaAndMetaToStdout(): Promise<void> {
|
|
21
|
+
const { TraceContext } = await import('../trace.context.js');
|
|
22
|
+
const { ConsoleLogger } = await import('./console.logger.js');
|
|
23
|
+
const logger = new ConsoleLogger(new TraceContext());
|
|
24
|
+
|
|
25
|
+
logger.info(
|
|
26
|
+
'message',
|
|
27
|
+
{ metaKey: 'metaValue' },
|
|
28
|
+
{
|
|
29
|
+
inlineMetaKey: 123,
|
|
30
|
+
anotherKey: true,
|
|
31
|
+
},
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
expect(this.getOutput()).toContain('message: inlineMetaKey=123, anotherKey=true {"metaKey":"metaValue"}');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public override async beforeEach(): Promise<void> {
|
|
38
|
+
this.output = [];
|
|
39
|
+
vi.resetModules();
|
|
40
|
+
const stdout = (console as unknown as ConsoleStdout)['_stdout'];
|
|
41
|
+
|
|
42
|
+
vi.spyOn(stdout, 'write').mockImplementation(((chunk: string | Uint8Array): boolean => {
|
|
43
|
+
this.output.push(chunk.toString());
|
|
44
|
+
|
|
45
|
+
return true;
|
|
46
|
+
}) as typeof process.stdout.write);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public override async afterEach(): Promise<void> {
|
|
50
|
+
vi.restoreAllMocks();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private getOutput(): string {
|
|
54
|
+
return this.output.join('');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -60,12 +60,21 @@ function formatTime(time: Date): string {
|
|
|
60
60
|
return time.toLocaleString('ru-RU');
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
function formatMeta(meta?: Record<string, unknown>): string {
|
|
64
|
+
if (!meta || Object.keys(meta).length === 0) {
|
|
65
|
+
return '';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return ` ${JSON.stringify(meta)}`;
|
|
69
|
+
}
|
|
70
|
+
|
|
63
71
|
const customFormat = createFormatter(info => {
|
|
64
72
|
const process = formatProcess(info.process);
|
|
65
73
|
const timestamp = formatTime(info.timestamp);
|
|
66
74
|
const context = colorizeContext(info.context);
|
|
67
75
|
const level = colorizeLevel(info.level);
|
|
68
|
-
const
|
|
76
|
+
const rawMessage = `${info.message}${formatMeta(info.meta)}`;
|
|
77
|
+
const message = colorizeMessage(info.level, rawMessage);
|
|
69
78
|
const traceId = info['traceId'] ? formatTraceId(info['traceId'] as string) : null;
|
|
70
79
|
|
|
71
80
|
const metaInfoItems: string[] = [timestamp, context, level, process];
|
package/src/logger/index.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {
|
|
2
|
+
Logger,
|
|
3
|
+
type InlineMeta,
|
|
4
|
+
type InlineMetaValue,
|
|
5
|
+
type LogMeta,
|
|
6
|
+
} from './logger.js';
|
|
2
7
|
export { MockLogger } from './mock.logger.js';
|
|
3
8
|
export { ConsoleLogger } from './console.logger.js';
|
|
4
9
|
export { JSONLogger } from './json.logger.js';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Describe,
|
|
3
|
+
expect,
|
|
4
|
+
Suite,
|
|
5
|
+
Test,
|
|
6
|
+
} from '@hg-ts/tests';
|
|
7
|
+
import { vi } from 'vitest';
|
|
8
|
+
|
|
9
|
+
type ConsoleStdout = {
|
|
10
|
+
_stdout: {
|
|
11
|
+
write: typeof process.stdout.write;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
@Describe()
|
|
16
|
+
export class JSONLoggerTest extends Suite {
|
|
17
|
+
private output: string[] = [];
|
|
18
|
+
|
|
19
|
+
@Test()
|
|
20
|
+
public async writesMessageInlineMetaAndMetaToStdout(): Promise<void> {
|
|
21
|
+
const { TraceContext } = await import('../trace.context.js');
|
|
22
|
+
const { JSONLogger } = await import('./json.logger.js');
|
|
23
|
+
const traceContext = new TraceContext();
|
|
24
|
+
const logger = new JSONLogger(traceContext);
|
|
25
|
+
const traceId = 'test-trace-id';
|
|
26
|
+
|
|
27
|
+
traceContext.run({ traceId }, () => logger.info(
|
|
28
|
+
'message',
|
|
29
|
+
{ metaKey: 'metaValue' },
|
|
30
|
+
{
|
|
31
|
+
inlineMetaKey: 123,
|
|
32
|
+
anotherKey: true,
|
|
33
|
+
},
|
|
34
|
+
));
|
|
35
|
+
|
|
36
|
+
const log = JSON.parse(this.output.join('')) as Record<string, unknown>;
|
|
37
|
+
|
|
38
|
+
expect(log['message']).toBe('message: inlineMetaKey=123, anotherKey=true');
|
|
39
|
+
expect(log['meta']).toEqual({ metaKey: 'metaValue' });
|
|
40
|
+
expect(log['inlineMeta']).toBeUndefined();
|
|
41
|
+
expect(log['traceId']).toBe(traceId);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public override async beforeEach(): Promise<void> {
|
|
45
|
+
this.output = [];
|
|
46
|
+
vi.resetModules();
|
|
47
|
+
const stdout = (console as unknown as ConsoleStdout)['_stdout'];
|
|
48
|
+
|
|
49
|
+
vi.spyOn(stdout, 'write').mockImplementation(((chunk: string | Uint8Array): boolean => {
|
|
50
|
+
this.output.push(chunk.toString());
|
|
51
|
+
|
|
52
|
+
return true;
|
|
53
|
+
}) as typeof process.stdout.write);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public override async afterEach(): Promise<void> {
|
|
57
|
+
vi.restoreAllMocks();
|
|
58
|
+
}
|
|
59
|
+
}
|
package/src/logger/logger.ts
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
|
+
import { type BaseException } from '@hg-ts/exception';
|
|
2
|
+
|
|
3
|
+
export type InlineMetaPrimitive = string | number | boolean | Date | Buffer;
|
|
4
|
+
|
|
5
|
+
export type InlineMetaValue = InlineMetaPrimitive | InlineMetaPrimitive[];
|
|
6
|
+
export type InlineMeta = Record<string, InlineMetaValue>;
|
|
7
|
+
export type LogMeta = Record<string, unknown>;
|
|
8
|
+
|
|
1
9
|
export abstract class Logger {
|
|
2
|
-
public abstract debug(
|
|
3
|
-
public abstract info(
|
|
4
|
-
public abstract notice(
|
|
5
|
-
|
|
6
|
-
public abstract error
|
|
7
|
-
public abstract
|
|
8
|
-
|
|
9
|
-
public abstract
|
|
10
|
+
public abstract debug(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
11
|
+
public abstract info(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
12
|
+
public abstract notice(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
13
|
+
|
|
14
|
+
public abstract warning(error: BaseException, message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
15
|
+
public abstract warning(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
16
|
+
|
|
17
|
+
public abstract error(error: BaseException, message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
18
|
+
public abstract error(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
19
|
+
|
|
20
|
+
public abstract critical(error: BaseException, message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
21
|
+
public abstract critical(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
22
|
+
|
|
23
|
+
public abstract alert(error: BaseException, message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
24
|
+
public abstract alert(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
25
|
+
|
|
26
|
+
public abstract emergency(error: BaseException, message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
27
|
+
public abstract emergency(message: string, meta?: LogMeta, inlineMeta?: InlineMeta): void;
|
|
10
28
|
|
|
11
29
|
public abstract setContext(context: Nullable<string>): void;
|
|
12
30
|
}
|