@emartech/json-logger 7.2.3 → 8.0.0
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/README.md +28 -9
- package/dist/logger/logger.d.ts +3 -0
- package/dist/logger/logger.js +67 -20
- package/dist/timer/timer.d.ts +1 -0
- package/dist/timer/timer.js +16 -8
- package/package.json +5 -1
- package/repo-info.json +7 -0
package/README.md
CHANGED
|
@@ -9,9 +9,21 @@ It has the same namespace based enabling/disabling mechanism as [debug].
|
|
|
9
9
|
npm install @emartech/json-logger
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
+
### Usage
|
|
12
13
|
|
|
14
|
+
Since 8.0.0, by default ECS fields will be used when logging.
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
If for reason you still need the old format, you need to override the `outputFormat` config.
|
|
17
|
+
`configure` will apply this setting globally, for all instances of the logger.
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
const { createLogger } = require('@emartech/json-logger');
|
|
21
|
+
|
|
22
|
+
createLogger.configure({
|
|
23
|
+
outputFormat: 'legacy'
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
```
|
|
15
27
|
|
|
16
28
|
#### Script
|
|
17
29
|
|
|
@@ -22,13 +34,15 @@ const mongoLogger = createLogger('mongo');
|
|
|
22
34
|
const redisLogger = createLogger('redis');
|
|
23
35
|
|
|
24
36
|
redisLogger.info('connected', { domain: 'yahoo' });
|
|
25
|
-
// {"
|
|
37
|
+
// ECS format: {"event":{"action":"connected"},"log":{"logger":"redis","level":30},"@timestamp":"2016-08-15T08:50:23.566Z","domain":"yahoo"}
|
|
38
|
+
// Legacy format: {"name":"redis","action":"connected","level":30,"time":"2016-08-15T08:50:23.566Z","domain":"yahoo"}
|
|
26
39
|
|
|
27
40
|
mongoLogger.info('connected', { domain: 'google' });
|
|
28
41
|
// no output, because 'mongo' is not within namespaces (process.env.DEBUG)
|
|
29
42
|
|
|
30
43
|
redisLogger.fromError('query', new Error('Unauthorized'), { problem: 'missmatch' });
|
|
31
|
-
// {"
|
|
44
|
+
// ECS format: {"event":{"action":"query"},"log":{"logger":"redis","level":50},"@timestamp":"2016-08-15T08:50:23.569Z","error":{"type":"Error","message":"Unauthorized","stack_trace":"..."},"problem":"mismatch"}
|
|
45
|
+
// Legacy format: {"name":"redis","action":"query","level":50,"time":"2016-08-15T08:50:23.569Z","error_name":"Error","error_stack":"Error: Unauthorized\n at Object.<anonymous> (/home/blacksonic/workspace/bunyan-debug/example.js:15:32)\n at Module._compile (module.js:541:32)\n at Object.Module._extensions..js (module.js:550:10)\n at Module.load (module.js:458:32)\n at tryModuleLoad (module.js:417:12)\n at Function.Module._load (module.js:409:3)\n at Module.runMain (module.js:575:10)\n at run (bootstrap_node.js:352:7)\n at startup (bootstrap_node.js:144:9)\n at bootstrap_node.js:467:3","error_message":"Unauthorized","problem":"missmatch"}
|
|
32
46
|
```
|
|
33
47
|
|
|
34
48
|
#### Class
|
|
@@ -103,10 +117,12 @@ const { createLogger } = require('@emartech/json-logger');
|
|
|
103
117
|
const redisLogger = createLogger('redis');
|
|
104
118
|
|
|
105
119
|
redisLogger.info('connected', { domain: 'yahoo' });
|
|
106
|
-
// {"
|
|
120
|
+
// ECS format: {"event":{"action":"connected"},"log":{"logger":"redis","level":30},"@timestamp":"2016-08-15T08:50:23.566Z","domain":"yahoo"}
|
|
121
|
+
// Legacy format: {"name":"redis","action":"connected","level":30,"time":"2016-08-15T08:50:23.566Z","domain":"yahoo"}
|
|
107
122
|
|
|
108
123
|
redisLogger.info('connected');
|
|
109
|
-
// {"
|
|
124
|
+
// ECS format: {"event":{"action":"connected"},"log":{"logger":"redis","level":30},"@timestamp":"2016-08-15T08:50:23.566Z"}
|
|
125
|
+
// Legacy format: {"name":"redis","action":"connected","level":30,"time":"2016-08-15T08:50:23.566Z"}
|
|
110
126
|
```
|
|
111
127
|
|
|
112
128
|
By default displays the namespace of the instance (`name`), the current time in ISO8601 format (`time`),
|
|
@@ -144,7 +160,8 @@ const { createLogger } = require('@emartech/json-logger');
|
|
|
144
160
|
const redisLogger = createLogger('redis');
|
|
145
161
|
|
|
146
162
|
redisLogger.fromError('query', new Error('Unauthorized'), { problem: 'missmatch' });
|
|
147
|
-
// {"
|
|
163
|
+
// ECS format: {"event":{"action":"query"},"log":{"logger":"redis","level":50},"@timestamp":"2016-08-15T08:50:23.569Z","error":{"type":"Error","message":"Unauthorized","stack_trace":"..."},"problem":"mismatch"}
|
|
164
|
+
// Legacy format: {"name":"redis","action":"query","level":50,"time":"2016-08-15T08:50:23.569Z","error_name":"Error","error_stack":"Error: Unauthorized\n at Object.<anonymous> (/home/blacksonic/workspace/bunyan-debug/example.js:15:32)\n at Module._compile (module.js:541:32)\n at Object.Module._extensions..js (module.js:550:10)\n at Module.load (module.js:458:32)\n at tryModuleLoad (module.js:417:12)\n at Function.Module._load (module.js:409:3)\n at Module.runMain (module.js:575:10)\n at run (bootstrap_node.js:352:7)\n at startup (bootstrap_node.js:144:9)\n at bootstrap_node.js:467:3","error_message":"Unauthorized","problem":"missmatch"}
|
|
148
165
|
```
|
|
149
166
|
|
|
150
167
|
##### JsonLogger.prototype.warnFromError(action, data)
|
|
@@ -166,7 +183,8 @@ const timer = redisLogger.timer();
|
|
|
166
183
|
// heavy task
|
|
167
184
|
|
|
168
185
|
timer.info('completed');
|
|
169
|
-
// {"name":"redis","action":"completed","level":30,"time":"2016-08-15T08:50:23.566Z","duration": 1500}
|
|
186
|
+
// Legacy format: {"name":"redis","action":"completed","level":30,"time":"2016-08-15T08:50:23.566Z","duration": 1500}
|
|
187
|
+
// ECS format: {"event":{"action":"completed","duration":"1500"},"log":{"logger":"redis","level":30},"@timestamp":"2016-08-15T08:50:23.566Z"}
|
|
170
188
|
```
|
|
171
189
|
|
|
172
190
|
##### JsonLogger.configure(options)
|
|
@@ -182,7 +200,8 @@ const { createLogger } = require('@emartech/json-logger');
|
|
|
182
200
|
createLogger.configure({
|
|
183
201
|
formatter: JSON.stringify,
|
|
184
202
|
output: console.log,
|
|
185
|
-
transformers: []
|
|
203
|
+
transformers: [],
|
|
204
|
+
outputFormat: 'ecs'
|
|
186
205
|
});
|
|
187
206
|
|
|
188
207
|
```
|
|
@@ -225,7 +244,7 @@ app.use(clsAdapter.getKoaMiddleware());
|
|
|
225
244
|
|
|
226
245
|
app.use(async () => {
|
|
227
246
|
logger.info('connected');
|
|
228
|
-
// {"name":"redis","action":"connected","level":30,"time":"2016-08-15T08:50:23.566Z","request_id":"d5caaa0e-b04e-4d94-bc88-3ed3b62dc94a"}
|
|
247
|
+
// Legacy format: {"name":"redis","action":"connected","level":30,"time":"2016-08-15T08:50:23.566Z","request_id":"d5caaa0e-b04e-4d94-bc88-3ed3b62dc94a"}
|
|
229
248
|
})
|
|
230
249
|
```
|
|
231
250
|
|
package/dist/logger/logger.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export interface LoggerConfig {
|
|
|
3
3
|
formatter: Function;
|
|
4
4
|
output: Function;
|
|
5
5
|
transformers: Function[];
|
|
6
|
+
outputFormat: String;
|
|
6
7
|
}
|
|
7
8
|
export declare class Logger {
|
|
8
9
|
private readonly namespace;
|
|
@@ -23,8 +24,10 @@ export declare class Logger {
|
|
|
23
24
|
warnFromError(action: string, error: unknown, data?: unknown): void;
|
|
24
25
|
timer(): Timer;
|
|
25
26
|
private log;
|
|
27
|
+
private getBaseLogFields;
|
|
26
28
|
private shortenStackTrace;
|
|
27
29
|
private shortenData;
|
|
28
30
|
private getErrorDetails;
|
|
31
|
+
private getBaseErrorDetails;
|
|
29
32
|
private getAxiosErrorDetails;
|
|
30
33
|
}
|
package/dist/logger/logger.js
CHANGED
|
@@ -7,7 +7,8 @@ const DATA_LIMIT = 3000;
|
|
|
7
7
|
const timer_1 = require("../timer/timer");
|
|
8
8
|
const json_1 = require("../formatter/json");
|
|
9
9
|
const console_1 = require("../output/console");
|
|
10
|
-
const
|
|
10
|
+
const lodash_1 = require("lodash");
|
|
11
|
+
const allowedKeys = ['output', 'formatter', 'transformers', 'outputFormat'];
|
|
11
12
|
class Logger {
|
|
12
13
|
constructor(namespace, enabled) {
|
|
13
14
|
this.namespace = namespace;
|
|
@@ -20,7 +21,7 @@ class Logger {
|
|
|
20
21
|
static validate(options) {
|
|
21
22
|
Object.keys(options).forEach((key) => {
|
|
22
23
|
if (!allowedKeys.includes(key)) {
|
|
23
|
-
throw new Error('Only the following keys are allowed:
|
|
24
|
+
throw new Error('Only the following keys are allowed: ' + allowedKeys);
|
|
24
25
|
}
|
|
25
26
|
});
|
|
26
27
|
}
|
|
@@ -46,7 +47,7 @@ class Logger {
|
|
|
46
47
|
this.log('fatal', action, data);
|
|
47
48
|
}
|
|
48
49
|
customError(severity, action, error, data = {}) {
|
|
49
|
-
this.log(severity, action,
|
|
50
|
+
this.log(severity, action, (0, lodash_1.merge)(this.getErrorDetails(error), data));
|
|
50
51
|
}
|
|
51
52
|
fromError(action, error, data = {}) {
|
|
52
53
|
this.customError('error', action, error, data);
|
|
@@ -61,17 +62,32 @@ class Logger {
|
|
|
61
62
|
if (!this.enabled) {
|
|
62
63
|
return;
|
|
63
64
|
}
|
|
64
|
-
let dataToLog =
|
|
65
|
-
name: this.namespace,
|
|
66
|
-
action: action,
|
|
67
|
-
level: config_1.config.levels[level].number,
|
|
68
|
-
time: new Date().toISOString(),
|
|
69
|
-
}, data);
|
|
65
|
+
let dataToLog = (0, lodash_1.merge)(this.getBaseLogFields(level, action), data);
|
|
70
66
|
Logger.config.transformers.forEach((transform) => {
|
|
71
67
|
dataToLog = transform(dataToLog);
|
|
72
68
|
});
|
|
73
69
|
Logger.config.output(Logger.config.formatter(dataToLog));
|
|
74
70
|
}
|
|
71
|
+
getBaseLogFields(level, action) {
|
|
72
|
+
if (Logger.config.outputFormat === 'legacy') {
|
|
73
|
+
return {
|
|
74
|
+
name: this.namespace,
|
|
75
|
+
action: action,
|
|
76
|
+
level: config_1.config.levels[level].number,
|
|
77
|
+
time: new Date().toISOString(),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
'@timestamp': new Date().toISOString(),
|
|
82
|
+
event: {
|
|
83
|
+
action: action,
|
|
84
|
+
},
|
|
85
|
+
log: {
|
|
86
|
+
logger: this.namespace,
|
|
87
|
+
level: config_1.config.levels[level].number,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
75
91
|
shortenStackTrace(stack) {
|
|
76
92
|
if (!stack) {
|
|
77
93
|
return;
|
|
@@ -89,24 +105,54 @@ class Logger {
|
|
|
89
105
|
if (!(error instanceof Object)) {
|
|
90
106
|
return {};
|
|
91
107
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
108
|
+
return (0, lodash_1.merge)(this.getBaseErrorDetails(error), this.getAxiosErrorDetails(error));
|
|
109
|
+
}
|
|
110
|
+
getBaseErrorDetails(error) {
|
|
111
|
+
if (Logger.config.outputFormat === 'legacy') {
|
|
112
|
+
return {
|
|
113
|
+
error_name: error.name,
|
|
114
|
+
error_stack: this.shortenStackTrace(error.stack || ''),
|
|
115
|
+
error_message: error.message,
|
|
116
|
+
error_data: this.shortenData(error.data),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
error: {
|
|
121
|
+
type: error.name,
|
|
122
|
+
message: error.message,
|
|
123
|
+
context: this.shortenData(error.data),
|
|
124
|
+
stack_trace: this.shortenStackTrace(error.stack || ''),
|
|
125
|
+
},
|
|
97
126
|
};
|
|
98
|
-
return Object.assign(baseDetails, this.getAxiosErrorDetails(error));
|
|
99
127
|
}
|
|
100
128
|
getAxiosErrorDetails(error) {
|
|
101
129
|
if (!error.isAxiosError) {
|
|
102
130
|
return {};
|
|
103
131
|
}
|
|
132
|
+
if (Logger.config.outputFormat === 'legacy') {
|
|
133
|
+
return {
|
|
134
|
+
request_method: error.config.method,
|
|
135
|
+
request_url: error.config.url,
|
|
136
|
+
response_status: error.response ? error.response.status : undefined,
|
|
137
|
+
response_status_text: error.response ? error.response.statusText : undefined,
|
|
138
|
+
response_data: error.response ? this.shortenData(error.response.data) : undefined,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
104
141
|
return {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
142
|
+
url: {
|
|
143
|
+
full: error.config.url,
|
|
144
|
+
},
|
|
145
|
+
http: {
|
|
146
|
+
request: {
|
|
147
|
+
method: error.config.method,
|
|
148
|
+
},
|
|
149
|
+
response: {
|
|
150
|
+
status_code: error.response ? error.response.status : undefined,
|
|
151
|
+
body: {
|
|
152
|
+
content: error.response ? this.shortenData(error.response.data) : undefined,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
110
156
|
};
|
|
111
157
|
}
|
|
112
158
|
}
|
|
@@ -115,4 +161,5 @@ Logger.config = {
|
|
|
115
161
|
formatter: json_1.jsonFormatter,
|
|
116
162
|
output: console_1.consoleOutput,
|
|
117
163
|
transformers: [],
|
|
164
|
+
outputFormat: 'ecs',
|
|
118
165
|
};
|
package/dist/timer/timer.d.ts
CHANGED
package/dist/timer/timer.js
CHANGED
|
@@ -1,34 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Timer = void 0;
|
|
4
|
+
const logger_1 = require("../logger/logger");
|
|
5
|
+
const lodash_1 = require("lodash");
|
|
4
6
|
class Timer {
|
|
5
7
|
constructor(logger) {
|
|
6
8
|
this.logger = logger;
|
|
7
9
|
this.start = new Date().getTime();
|
|
8
10
|
}
|
|
9
11
|
trace(action, data = {}) {
|
|
10
|
-
this.logger.trace(action,
|
|
12
|
+
this.logger.trace(action, this.getData(data));
|
|
11
13
|
}
|
|
12
14
|
debug(action, data = {}) {
|
|
13
|
-
this.logger.debug(action,
|
|
15
|
+
this.logger.debug(action, this.getData(data));
|
|
14
16
|
}
|
|
15
17
|
info(action, data = {}) {
|
|
16
|
-
this.logger.info(action,
|
|
18
|
+
this.logger.info(action, this.getData(data));
|
|
17
19
|
}
|
|
18
20
|
warn(action, data = {}) {
|
|
19
|
-
this.logger.warn(action,
|
|
21
|
+
this.logger.warn(action, this.getData(data));
|
|
20
22
|
}
|
|
21
23
|
error(action, data = {}) {
|
|
22
|
-
this.logger.error(action,
|
|
24
|
+
this.logger.error(action, this.getData(data));
|
|
23
25
|
}
|
|
24
26
|
fatal(action, data = {}) {
|
|
25
|
-
this.logger.fatal(action,
|
|
27
|
+
this.logger.fatal(action, this.getData(data));
|
|
26
28
|
}
|
|
27
29
|
fromError(action, error, data = {}) {
|
|
28
|
-
this.logger.fromError(action, error,
|
|
30
|
+
this.logger.fromError(action, error, this.getData(data));
|
|
29
31
|
}
|
|
30
32
|
warnFromError(action, error, data = {}) {
|
|
31
|
-
this.logger.warnFromError(action, error,
|
|
33
|
+
this.logger.warnFromError(action, error, this.getData(data));
|
|
34
|
+
}
|
|
35
|
+
getData(data) {
|
|
36
|
+
if (logger_1.Logger.config.outputFormat === 'legacy') {
|
|
37
|
+
return Object.assign({ duration: this.duration() }, data);
|
|
38
|
+
}
|
|
39
|
+
return (0, lodash_1.merge)({ event: { duration: this.duration() } }, data);
|
|
32
40
|
}
|
|
33
41
|
duration() {
|
|
34
42
|
const end = new Date().getTime();
|
package/package.json
CHANGED
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
],
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/chai": "4.3.3",
|
|
31
|
+
"@types/lodash": "4.14.198",
|
|
31
32
|
"@types/mocha": "10.0.0",
|
|
32
33
|
"@types/node": "18.7.23",
|
|
33
34
|
"@types/sinon": "10.0.13",
|
|
@@ -60,5 +61,8 @@
|
|
|
60
61
|
"url": "https://github.com/emartech/json-logger-js/issues"
|
|
61
62
|
},
|
|
62
63
|
"homepage": "https://github.com/emartech/json-logger-js#readme",
|
|
63
|
-
"
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"lodash": "4.17.21"
|
|
66
|
+
},
|
|
67
|
+
"version": "8.0.0"
|
|
64
68
|
}
|