b2b-platform-utils 1.1.2 → 1.1.4
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/localCache.js +1 -1
- package/logger.js +136 -28
- package/package.json +1 -1
package/localCache.js
CHANGED
package/logger.js
CHANGED
|
@@ -1,33 +1,141 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @module logger
|
|
5
|
+
* @description
|
|
6
|
+
* Non-blocking logger that reads environment and service name from localCache.
|
|
7
|
+
* - Production (environment === "production"): newline-delimited JSON to stdout/stderr.
|
|
8
|
+
* - Non-production: colorized console output with icons.
|
|
9
|
+
* - Uses async writes to avoid blocking hot paths.
|
|
10
|
+
*
|
|
11
|
+
* Dependencies:
|
|
12
|
+
* - localCache module must export: getValue(key), getService().
|
|
13
|
+
*/
|
|
4
14
|
|
|
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
|
-
|
|
15
|
+
let cache;
|
|
16
|
+
try {
|
|
17
|
+
// NOTE: Adjust the path if your cache module lives elsewhere.
|
|
18
|
+
cache = require('./localCache');
|
|
19
|
+
} catch (_) {
|
|
20
|
+
// NOTE: Safe fallback stub to keep logger functional if cache is not available.
|
|
21
|
+
cache = {
|
|
22
|
+
getValue: () => null,
|
|
23
|
+
getService: () => 'not_set_service'
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Resolve current environment and service on each call.
|
|
29
|
+
* This allows dynamic changes at runtime (if your cache updates).
|
|
30
|
+
*/
|
|
31
|
+
function resolveContext() {
|
|
32
|
+
const env = cache.getValue('environment') || 'development';
|
|
33
|
+
const service = cache.getService ? cache.getService() : 'not_set_service';
|
|
34
|
+
const isProd = env === 'production';
|
|
35
|
+
return { env, service, isProd };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Internal async writer using setImmediate to offload writes from the hot path.
|
|
40
|
+
* @param {'stdout'|'stderr'} stream
|
|
41
|
+
* @param {string} message
|
|
42
|
+
*/
|
|
43
|
+
function asyncWrite(stream, message) {
|
|
44
|
+
setImmediate(() => {
|
|
45
|
+
process[stream].write(message + '\n');
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Serialize a structured JSON log line for production.
|
|
51
|
+
* @param {string} level
|
|
52
|
+
* @param {string} message
|
|
53
|
+
* @param {Record<string, any>=} extra
|
|
54
|
+
*/
|
|
55
|
+
function serializeJSON(level, message, extra = {}) {
|
|
56
|
+
const { env, service } = resolveContext();
|
|
57
|
+
return JSON.stringify({
|
|
58
|
+
ts: new Date().toISOString(),
|
|
59
|
+
level,
|
|
60
|
+
service,
|
|
61
|
+
env,
|
|
62
|
+
msg: message,
|
|
63
|
+
...extra
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Build a colorized single-line message for non-production.
|
|
69
|
+
* @param {string} colorCode
|
|
70
|
+
* @param {string} icon
|
|
71
|
+
* @param {string} message
|
|
72
|
+
* @param {string} label
|
|
73
|
+
*/
|
|
74
|
+
function colorize(colorCode, icon, message, label) {
|
|
75
|
+
return `${colorCode}${icon} ${message} [${label}] \x1b[0m`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Print a debug payload (object) as magenta JSON or structured JSON in prod.
|
|
80
|
+
* @param {any} data
|
|
81
|
+
*/
|
|
82
|
+
function debug(data) {
|
|
83
|
+
const { isProd } = resolveContext();
|
|
84
|
+
if (isProd) {
|
|
85
|
+
asyncWrite('stdout', serializeJSON('debug', 'debug payload', { data }));
|
|
86
|
+
} else {
|
|
87
|
+
const payload = (() => {
|
|
88
|
+
try { return JSON.stringify(data); } catch { return String(data); }
|
|
89
|
+
})();
|
|
90
|
+
asyncWrite('stdout', colorize('\x1b[35m', '🐛', payload, 'DEBUG'));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Print a green success note.
|
|
96
|
+
* @param {string|number|boolean} message
|
|
97
|
+
*/
|
|
98
|
+
function successNote(message) {
|
|
99
|
+
const { isProd } = resolveContext();
|
|
100
|
+
const msg = message != null ? message.toString() : '';
|
|
101
|
+
if (isProd) {
|
|
102
|
+
asyncWrite('stdout', serializeJSON('info', msg));
|
|
103
|
+
} else {
|
|
104
|
+
asyncWrite('stdout', colorize('\x1b[32m', '✅', msg, 'SUCCESS'));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Print a red critical note.
|
|
110
|
+
* @param {string|number|boolean} message
|
|
111
|
+
*/
|
|
112
|
+
function criticalNote(message) {
|
|
113
|
+
const { isProd } = resolveContext();
|
|
114
|
+
const msg = message != null ? message.toString() : '';
|
|
115
|
+
if (isProd) {
|
|
116
|
+
asyncWrite('stderr', serializeJSON('error', msg));
|
|
117
|
+
} else {
|
|
118
|
+
asyncWrite('stderr', colorize('\x1b[31m', '⛔', msg, 'CRITICAL'));
|
|
32
119
|
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Print a yellow warning note.
|
|
124
|
+
* @param {string|number|boolean} message
|
|
125
|
+
*/
|
|
126
|
+
function warningNote(message) {
|
|
127
|
+
const { isProd } = resolveContext();
|
|
128
|
+
const msg = message != null ? message.toString() : '';
|
|
129
|
+
if (isProd) {
|
|
130
|
+
asyncWrite('stderr', serializeJSON('warn', msg));
|
|
131
|
+
} else {
|
|
132
|
+
asyncWrite('stderr', colorize('\x1b[33m', '⚠️', msg, 'WARNING'));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
module.exports = {
|
|
137
|
+
debug,
|
|
138
|
+
successNote,
|
|
139
|
+
criticalNote,
|
|
140
|
+
warningNote
|
|
33
141
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "b2b-platform-utils",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "Shared utilities for Node.js microservices: errors map, local cache, logger, numbers, dates, filesystem, media optimization, paginator, slugger, crypto wrapper, sanitize HTML, sorting.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"license": "KingSizer",
|