@feizk/logger 1.7.0 → 2.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 +148 -27
- package/dist/index.d.mts +178 -53
- package/dist/index.d.ts +178 -53
- package/dist/index.js +284 -167
- package/dist/index.mjs +281 -155
- package/package.json +14 -6
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,223 +15,342 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
31
21
|
var index_exports = {};
|
|
32
22
|
__export(index_exports, {
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
LEVEL_LABELS: () => LEVEL_LABELS,
|
|
24
|
+
LOG_LEVEL_PRIORITIES: () => LOG_LEVEL_PRIORITIES,
|
|
25
|
+
Logger: () => Logger
|
|
35
26
|
});
|
|
36
27
|
module.exports = __toCommonJS(index_exports);
|
|
37
28
|
|
|
38
|
-
// src/
|
|
39
|
-
var
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
29
|
+
// src/constants.ts
|
|
30
|
+
var LOG_LEVEL_PRIORITIES = {
|
|
31
|
+
trace: 0,
|
|
32
|
+
debug: 1,
|
|
33
|
+
info: 2,
|
|
34
|
+
warn: 3,
|
|
35
|
+
error: 4,
|
|
36
|
+
fatal: 5
|
|
37
|
+
};
|
|
38
|
+
var ANSI = {
|
|
39
|
+
reset: "\x1B[0m",
|
|
40
|
+
bold: "\x1B[1m",
|
|
41
|
+
dim: "\x1B[2m",
|
|
42
|
+
red: "\x1B[31m",
|
|
43
|
+
green: "\x1B[32m",
|
|
44
|
+
yellow: "\x1B[33m",
|
|
45
|
+
blue: "\x1B[34m",
|
|
46
|
+
magenta: "\x1B[35m",
|
|
47
|
+
cyan: "\x1B[36m",
|
|
48
|
+
gray: "\x1B[90m",
|
|
49
|
+
white: "\x1B[37m",
|
|
50
|
+
bgRed: "\x1B[41m"
|
|
51
|
+
};
|
|
52
|
+
var LEVEL_COLORS = {
|
|
53
|
+
trace: ANSI.gray,
|
|
54
|
+
debug: ANSI.cyan,
|
|
55
|
+
info: ANSI.blue,
|
|
56
|
+
warn: ANSI.yellow,
|
|
57
|
+
error: ANSI.red,
|
|
58
|
+
fatal: `${ANSI.bgRed}${ANSI.white}${ANSI.bold}`
|
|
59
|
+
};
|
|
60
|
+
var LEVEL_LABELS = {
|
|
61
|
+
trace: "[TRACE]",
|
|
62
|
+
debug: "[DEBUG]",
|
|
63
|
+
info: "[INFO]",
|
|
64
|
+
warn: "[WARN]",
|
|
65
|
+
error: "[ERROR]",
|
|
66
|
+
fatal: "[FATAL]"
|
|
44
67
|
};
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
68
|
+
var CONSOLE_METHODS = {
|
|
69
|
+
trace: "trace",
|
|
70
|
+
debug: "debug",
|
|
71
|
+
info: "log",
|
|
72
|
+
warn: "warn",
|
|
73
|
+
error: "error",
|
|
74
|
+
fatal: "error"
|
|
75
|
+
};
|
|
76
|
+
var TIMESTAMP_PRESETS = {
|
|
77
|
+
iso: (date) => date.toISOString(),
|
|
78
|
+
locale: (date) => date.toLocaleString()
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// src/utils.ts
|
|
82
|
+
var coloredLabelCache = /* @__PURE__ */ new Map();
|
|
83
|
+
function getColoredLabel(level, enableColors) {
|
|
84
|
+
const cacheKey = `${level}:${enableColors}`;
|
|
85
|
+
const cached = coloredLabelCache.get(cacheKey);
|
|
86
|
+
if (cached !== void 0) return cached;
|
|
87
|
+
const label = LEVEL_LABELS[level];
|
|
88
|
+
if (!enableColors) {
|
|
89
|
+
coloredLabelCache.set(cacheKey, label);
|
|
90
|
+
return label;
|
|
91
|
+
}
|
|
92
|
+
const color = LEVEL_COLORS[level];
|
|
93
|
+
const result = `${color}${label}${ANSI.reset}`;
|
|
94
|
+
coloredLabelCache.set(cacheKey, result);
|
|
95
|
+
return result;
|
|
48
96
|
}
|
|
49
|
-
function
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"[DEBUG]": import_chalk.default.gray(level)
|
|
56
|
-
};
|
|
57
|
-
return colors[level] || level;
|
|
97
|
+
function formatTimestamp(option, date = /* @__PURE__ */ new Date()) {
|
|
98
|
+
if (typeof option === "function") {
|
|
99
|
+
return option(date);
|
|
100
|
+
}
|
|
101
|
+
const preset = TIMESTAMP_PRESETS[option];
|
|
102
|
+
return preset(date);
|
|
58
103
|
}
|
|
59
|
-
function
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
104
|
+
function formatJson(entry) {
|
|
105
|
+
const message = entry.args.map((arg) => {
|
|
106
|
+
if (typeof arg === "string") return arg;
|
|
107
|
+
try {
|
|
108
|
+
return JSON.stringify(arg);
|
|
109
|
+
} catch {
|
|
110
|
+
return String(arg);
|
|
111
|
+
}
|
|
112
|
+
}).join(" ");
|
|
113
|
+
const output = {
|
|
114
|
+
level: entry.level,
|
|
115
|
+
timestamp: entry.timestamp,
|
|
116
|
+
message
|
|
65
117
|
};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
function formatLog(level, timestamp, args, options) {
|
|
72
|
-
const { formatLog: formatLog2, enableColors = true } = options;
|
|
73
|
-
const coloredLevel = getColor(level, enableColors);
|
|
74
|
-
if (formatLog2) {
|
|
75
|
-
return [formatLog2(coloredLevel, timestamp, args)];
|
|
118
|
+
if (entry.prefix) {
|
|
119
|
+
output.prefix = entry.prefix;
|
|
120
|
+
}
|
|
121
|
+
if (Object.keys(entry.context).length > 0) {
|
|
122
|
+
output.context = entry.context;
|
|
76
123
|
}
|
|
77
|
-
return
|
|
124
|
+
return JSON.stringify(output);
|
|
125
|
+
}
|
|
126
|
+
function buildMessage(args) {
|
|
127
|
+
return args.map((arg) => {
|
|
128
|
+
if (typeof arg === "string") return arg;
|
|
129
|
+
try {
|
|
130
|
+
return JSON.stringify(arg);
|
|
131
|
+
} catch {
|
|
132
|
+
return String(arg);
|
|
133
|
+
}
|
|
134
|
+
}).join(" ");
|
|
78
135
|
}
|
|
79
136
|
|
|
80
137
|
// src/logger.ts
|
|
81
|
-
var
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
error: 3
|
|
87
|
-
};
|
|
88
|
-
var Logger = class {
|
|
138
|
+
var Logger = class _Logger {
|
|
139
|
+
/**
|
|
140
|
+
* Create a new Logger instance.
|
|
141
|
+
* @param options - Configuration options
|
|
142
|
+
*/
|
|
89
143
|
constructor(options = {}) {
|
|
90
|
-
this.discordQueue = [];
|
|
91
|
-
this.isProcessing = false;
|
|
92
144
|
this.options = {
|
|
145
|
+
level: options.level ?? "debug",
|
|
146
|
+
silent: options.silent ?? false,
|
|
93
147
|
enableColors: options.enableColors ?? true,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
148
|
+
timestamp: options.timestamp ?? "iso",
|
|
149
|
+
formatter: options.formatter,
|
|
150
|
+
json: options.json ?? false,
|
|
151
|
+
transports: [...options.transports ?? []],
|
|
152
|
+
prefix: options.prefix,
|
|
153
|
+
context: { ...options.context ?? {} }
|
|
97
154
|
};
|
|
98
|
-
this.
|
|
155
|
+
this.transports = this.options.transports;
|
|
156
|
+
this.prefix = this.options.prefix;
|
|
157
|
+
this.context = this.options.context;
|
|
99
158
|
}
|
|
159
|
+
// ============================================================================
|
|
160
|
+
// Public Log Methods
|
|
161
|
+
// ============================================================================
|
|
100
162
|
/**
|
|
101
|
-
*
|
|
102
|
-
* @param
|
|
163
|
+
* Log a trace message (most verbose).
|
|
164
|
+
* @param args - Arguments to log
|
|
165
|
+
*/
|
|
166
|
+
trace(...args) {
|
|
167
|
+
this.log("trace", args);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Log a debug message.
|
|
171
|
+
* @param args - Arguments to log
|
|
172
|
+
*/
|
|
173
|
+
debug(...args) {
|
|
174
|
+
this.log("debug", args);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Log an info message.
|
|
178
|
+
* @param args - Arguments to log
|
|
179
|
+
*/
|
|
180
|
+
info(...args) {
|
|
181
|
+
this.log("info", args);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Log a warning message.
|
|
185
|
+
* @param args - Arguments to log
|
|
186
|
+
*/
|
|
187
|
+
warn(...args) {
|
|
188
|
+
this.log("warn", args);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Log an error message.
|
|
192
|
+
* @param args - Arguments to log
|
|
193
|
+
*/
|
|
194
|
+
error(...args) {
|
|
195
|
+
this.log("error", args);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Log a fatal message (most severe).
|
|
199
|
+
* @param args - Arguments to log
|
|
200
|
+
*/
|
|
201
|
+
fatal(...args) {
|
|
202
|
+
this.log("fatal", args);
|
|
203
|
+
}
|
|
204
|
+
// ============================================================================
|
|
205
|
+
// Level Management
|
|
206
|
+
// ============================================================================
|
|
207
|
+
/**
|
|
208
|
+
* Set the minimum log level.
|
|
209
|
+
* @param level - The log level to set
|
|
103
210
|
*/
|
|
104
211
|
setLevel(level) {
|
|
105
|
-
this.level = level;
|
|
212
|
+
this.options.level = level;
|
|
106
213
|
}
|
|
107
214
|
/**
|
|
108
|
-
*
|
|
109
|
-
* @
|
|
110
|
-
* @param timestamp - The formatted timestamp.
|
|
111
|
-
* @param args - The log arguments.
|
|
215
|
+
* Get the current log level.
|
|
216
|
+
* @returns The current log level
|
|
112
217
|
*/
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (!discord?.enable) return;
|
|
116
|
-
try {
|
|
117
|
-
new URL(discord.webhookURL);
|
|
118
|
-
} catch {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
const message = args.map((arg) => typeof arg === "string" ? arg : JSON.stringify(arg)).join(" ");
|
|
122
|
-
const title = `${level.toUpperCase()}-${generateId()}`;
|
|
123
|
-
const embed = discord.formatEmbed ? discord.formatEmbed(level, timestamp, message) : {
|
|
124
|
-
title,
|
|
125
|
-
description: message,
|
|
126
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
127
|
-
color: getDiscordColor(level)
|
|
128
|
-
};
|
|
129
|
-
this.discordQueue.push({ embed, retryCount: 0 });
|
|
130
|
-
if (!this.isProcessing) {
|
|
131
|
-
this.isProcessing = true;
|
|
132
|
-
setTimeout(() => this.processQueue(), 0);
|
|
133
|
-
}
|
|
218
|
+
getLevel() {
|
|
219
|
+
return this.options.level;
|
|
134
220
|
}
|
|
221
|
+
// ============================================================================
|
|
222
|
+
// Transport Management
|
|
223
|
+
// ============================================================================
|
|
135
224
|
/**
|
|
136
|
-
*
|
|
225
|
+
* Add a transport to the logger.
|
|
226
|
+
* @param transport - The transport to add
|
|
137
227
|
*/
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
228
|
+
addTransport(transport) {
|
|
229
|
+
this.transports.push(transport);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Remove a transport from the logger.
|
|
233
|
+
* @param transport - The transport to remove
|
|
234
|
+
*/
|
|
235
|
+
removeTransport(transport) {
|
|
236
|
+
const index = this.transports.indexOf(transport);
|
|
237
|
+
if (index !== -1) {
|
|
238
|
+
this.transports.splice(index, 1);
|
|
142
239
|
}
|
|
143
|
-
this.isProcessing = true;
|
|
144
|
-
const discord = this.options.discord;
|
|
145
|
-
const batchSize = discord.batchSize ?? 10;
|
|
146
|
-
const batch = this.discordQueue.splice(0, batchSize);
|
|
147
|
-
this.sendBatch(batch.map((item) => item.embed)).then(() => {
|
|
148
|
-
const delay = discord.batchDelay ?? 2e3;
|
|
149
|
-
this.processTimeout = setTimeout(() => this.processQueue(), delay);
|
|
150
|
-
}).catch(() => {
|
|
151
|
-
const maxRetries = discord.maxRetries ?? 3;
|
|
152
|
-
const retryItems = batch.filter((item) => item.retryCount < maxRetries).map((item) => ({
|
|
153
|
-
...item,
|
|
154
|
-
retryCount: item.retryCount + 1
|
|
155
|
-
}));
|
|
156
|
-
this.discordQueue.unshift(...retryItems);
|
|
157
|
-
const retryDelayBase = discord.retryDelayBase ?? 1e3;
|
|
158
|
-
const delay = retryDelayBase * Math.pow(2, batch[0]?.retryCount ?? 0);
|
|
159
|
-
this.processTimeout = setTimeout(() => this.processQueue(), delay);
|
|
160
|
-
});
|
|
161
240
|
}
|
|
241
|
+
// ============================================================================
|
|
242
|
+
// Child Logger
|
|
243
|
+
// ============================================================================
|
|
162
244
|
/**
|
|
163
|
-
*
|
|
164
|
-
* @param
|
|
245
|
+
* Create a child logger with additional prefix and context.
|
|
246
|
+
* @param options - Child logger options
|
|
247
|
+
* @returns A new Logger instance
|
|
165
248
|
*/
|
|
166
|
-
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
249
|
+
child(options = {}) {
|
|
250
|
+
const combinedPrefix = options.prefix ? this.prefix ? `${this.prefix}:${options.prefix}` : options.prefix : this.prefix;
|
|
251
|
+
const combinedContext = {
|
|
252
|
+
...this.context,
|
|
253
|
+
...options.context ?? {}
|
|
254
|
+
};
|
|
255
|
+
return new _Logger({
|
|
256
|
+
level: options.level ?? this.options.level,
|
|
257
|
+
silent: options.silent ?? this.options.silent,
|
|
258
|
+
enableColors: this.options.enableColors,
|
|
259
|
+
timestamp: this.options.timestamp,
|
|
260
|
+
formatter: this.options.formatter,
|
|
261
|
+
json: this.options.json,
|
|
262
|
+
transports: this.transports.slice(),
|
|
263
|
+
prefix: combinedPrefix,
|
|
264
|
+
context: combinedContext
|
|
172
265
|
});
|
|
173
266
|
}
|
|
267
|
+
// ============================================================================
|
|
268
|
+
// Cleanup
|
|
269
|
+
// ============================================================================
|
|
174
270
|
/**
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* @returns True if the message should be logged.
|
|
271
|
+
* Destroy the logger and all its transports.
|
|
272
|
+
* Calls destroy() on all registered transports.
|
|
178
273
|
*/
|
|
179
|
-
|
|
180
|
-
|
|
274
|
+
async destroy() {
|
|
275
|
+
const destroyPromises = this.transports.map(async (transport) => {
|
|
276
|
+
if (typeof transport.destroy === "function") {
|
|
277
|
+
await transport.destroy();
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
await Promise.all(destroyPromises);
|
|
281
|
+
this.transports.length = 0;
|
|
181
282
|
}
|
|
283
|
+
// ============================================================================
|
|
284
|
+
// Private Methods
|
|
285
|
+
// ============================================================================
|
|
182
286
|
/**
|
|
183
|
-
*
|
|
184
|
-
* @param
|
|
287
|
+
* Core logging method - all public methods delegate here.
|
|
288
|
+
* @param level - The log level
|
|
289
|
+
* @param args - The arguments to log
|
|
185
290
|
*/
|
|
186
|
-
|
|
187
|
-
if (!this.shouldLog(
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
291
|
+
log(level, args) {
|
|
292
|
+
if (!this.shouldLog(level)) return;
|
|
293
|
+
const entry = {
|
|
294
|
+
level,
|
|
295
|
+
timestamp: formatTimestamp(this.options.timestamp),
|
|
296
|
+
args,
|
|
297
|
+
prefix: this.prefix,
|
|
298
|
+
context: this.context
|
|
299
|
+
};
|
|
300
|
+
if (!this.options.silent) {
|
|
301
|
+
this.writeToConsole(level, entry);
|
|
302
|
+
}
|
|
303
|
+
for (const transport of this.transports) {
|
|
304
|
+
this.dispatchToTransport(transport, entry);
|
|
305
|
+
}
|
|
194
306
|
}
|
|
195
307
|
/**
|
|
196
|
-
*
|
|
197
|
-
* @param
|
|
308
|
+
* Write a log entry to the console.
|
|
309
|
+
* @param level - The log level
|
|
310
|
+
* @param entry - The log entry
|
|
198
311
|
*/
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
this.options.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
312
|
+
writeToConsole(level, entry) {
|
|
313
|
+
const method = CONSOLE_METHODS[level];
|
|
314
|
+
if (this.options.formatter) {
|
|
315
|
+
console[method](this.options.formatter(entry));
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
if (this.options.json) {
|
|
319
|
+
console[method](formatJson(entry));
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const label = getColoredLabel(entry.level, this.options.enableColors);
|
|
323
|
+
const prefixStr = entry.prefix ? ` [${entry.prefix}]` : "";
|
|
324
|
+
const message = buildMessage(entry.args);
|
|
325
|
+
console[method](`${label} ${entry.timestamp}${prefixStr}`, message);
|
|
207
326
|
}
|
|
208
327
|
/**
|
|
209
|
-
*
|
|
210
|
-
* @param
|
|
328
|
+
* Dispatch a log entry to a transport.
|
|
329
|
+
* @param transport - The transport
|
|
330
|
+
* @param entry - The log entry
|
|
211
331
|
*/
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
332
|
+
dispatchToTransport(transport, entry) {
|
|
333
|
+
try {
|
|
334
|
+
const result = transport.log(entry);
|
|
335
|
+
if (result instanceof Promise) {
|
|
336
|
+
result.catch(() => {
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
} catch {
|
|
340
|
+
}
|
|
220
341
|
}
|
|
221
342
|
/**
|
|
222
|
-
*
|
|
223
|
-
* @param
|
|
343
|
+
* Check if a log level should be output.
|
|
344
|
+
* @param level - The log level to check
|
|
345
|
+
* @returns True if the message should be logged
|
|
224
346
|
*/
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const timestamp = formatTimestamp(
|
|
228
|
-
this.options.formatTimestamp,
|
|
229
|
-
TIMESTAMP_TYPES
|
|
230
|
-
);
|
|
231
|
-
console.log(...formatLog("[DEBUG]", timestamp, args, this.options));
|
|
232
|
-
this.sendToDiscord("debug", timestamp, args);
|
|
347
|
+
shouldLog(level) {
|
|
348
|
+
return LOG_LEVEL_PRIORITIES[level] >= LOG_LEVEL_PRIORITIES[this.options.level];
|
|
233
349
|
}
|
|
234
350
|
};
|
|
235
351
|
// Annotate the CommonJS export names for ESM import in node:
|
|
236
352
|
0 && (module.exports = {
|
|
237
|
-
|
|
238
|
-
|
|
353
|
+
LEVEL_LABELS,
|
|
354
|
+
LOG_LEVEL_PRIORITIES,
|
|
355
|
+
Logger
|
|
239
356
|
});
|