@mks2508/better-logger 2.1.0 → 3.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/.claude/settings.local.json +6 -1
- package/CHANGELOG.json +93 -1
- package/CHANGELOG.md +127 -0
- package/CLAUDE.md +14 -1
- package/README.md +111 -20
- package/dist/Logger.d.ts +205 -58
- package/dist/Logger.d.ts.map +1 -1
- package/dist/ScopedLogger.d.ts +23 -276
- package/dist/ScopedLogger.d.ts.map +1 -1
- package/dist/chunks/Logger-BCfx_yCK.js +2 -0
- package/dist/chunks/Logger-BCfx_yCK.js.map +1 -0
- package/dist/chunks/{Logger-B7L-ujY4.js → Logger-C126NTrD.js} +862 -96
- package/dist/chunks/Logger-C126NTrD.js.map +1 -0
- package/dist/exports-module.d.ts +1 -1
- package/dist/exports-module.d.ts.map +1 -1
- package/dist/exports.cjs +1 -1
- package/dist/exports.js +1 -1
- package/dist/hooks/HookManager.d.ts +21 -0
- package/dist/hooks/HookManager.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +23 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +240 -9
- package/dist/index.js.map +1 -1
- package/dist/serializers/SerializerRegistry.d.ts +16 -0
- package/dist/serializers/SerializerRegistry.d.ts.map +1 -0
- package/dist/serializers/index.d.ts +2 -0
- package/dist/serializers/index.d.ts.map +1 -0
- package/dist/styling/StyleCache.d.ts +42 -0
- package/dist/styling/StyleCache.d.ts.map +1 -0
- package/dist/styling-module.d.ts +1 -1
- package/dist/styling-module.d.ts.map +1 -1
- package/dist/styling.cjs +1 -1
- package/dist/styling.js +2 -2
- package/dist/transports/ConsoleTransport.d.ts +9 -0
- package/dist/transports/ConsoleTransport.d.ts.map +1 -0
- package/dist/transports/FileTransport.d.ts +15 -0
- package/dist/transports/FileTransport.d.ts.map +1 -0
- package/dist/transports/HttpTransport.d.ts +16 -0
- package/dist/transports/HttpTransport.d.ts.map +1 -0
- package/dist/transports/TransportManager.d.ts +14 -0
- package/dist/transports/TransportManager.d.ts.map +1 -0
- package/dist/transports/index.d.ts +5 -0
- package/dist/transports/index.d.ts.map +1 -0
- package/dist/types/core.d.ts +38 -0
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/hooks.d.ts +36 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/index.d.ts +5 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/serializers.d.ts +25 -0
- package/dist/types/serializers.d.ts.map +1 -0
- package/dist/types/transports.d.ts +47 -0
- package/dist/types/transports.d.ts.map +1 -0
- package/docs/API.md +227 -0
- package/package.json +1 -1
- package/packages/core/package.json +1 -1
- package/src/Logger.ts +391 -102
- package/src/ScopedLogger.ts +78 -318
- package/src/hooks/HookManager.ts +177 -0
- package/src/hooks/index.ts +1 -0
- package/src/index.ts +77 -2
- package/src/serializers/SerializerRegistry.ts +173 -0
- package/src/serializers/index.ts +1 -0
- package/src/styling/StyleCache.ts +131 -0
- package/src/transports/ConsoleTransport.ts +28 -0
- package/src/transports/FileTransport.ts +53 -0
- package/src/transports/HttpTransport.ts +56 -0
- package/src/transports/TransportManager.ts +130 -0
- package/src/transports/index.ts +4 -0
- package/src/types/core.ts +46 -0
- package/src/types/hooks.ts +45 -0
- package/src/types/index.ts +39 -1
- package/src/types/serializers.ts +30 -0
- package/src/types/transports.ts +52 -0
- package/dist/chunks/Logger-B7L-ujY4.js.map +0 -1
- package/dist/chunks/Logger-DzU_c5sX.js +0 -2
- package/dist/chunks/Logger-DzU_c5sX.js.map +0 -1
- package/dist/chunks/ScopedLogger-BY3-E8Ov.js +0 -2
- package/dist/chunks/ScopedLogger-BY3-E8Ov.js.map +0 -1
- package/dist/chunks/ScopedLogger-D-RbiFZn.js +0 -361
- package/dist/chunks/ScopedLogger-D-RbiFZn.js.map +0 -1
|
@@ -1,4 +1,364 @@
|
|
|
1
|
-
import { h as getAdaptiveColor, A as ADAPTIVE_COLORS, b as StyleBuilder, j as BUFFER_LIMITS, k as generateLogId, l as parseTimeInput, m as formatDisplayTime, n as safeStringify, o as escapeHtml, q as EXPORT_FORMATS, D as DEFAULT_CONFIG, r as setupThemeChangeListener, t as getEnvironment, p as parseStackTrace,
|
|
1
|
+
import { h as getAdaptiveColor, A as ADAPTIVE_COLORS, b as StyleBuilder, j as BUFFER_LIMITS, k as generateLogId, l as parseTimeInput, m as formatDisplayTime, n as safeStringify, o as escapeHtml, q as EXPORT_FORMATS, D as DEFAULT_CONFIG$1, r as setupThemeChangeListener, t as getEnvironment, p as parseStackTrace, f as formatTimestamp, c as createStyledOutput, S as StylePresets } from "./environment-TI2ByCPT.js";
|
|
2
|
+
const DEFAULT_CONFIG = {
|
|
3
|
+
maxDepth: 5,
|
|
4
|
+
circular: "placeholder",
|
|
5
|
+
preserveUndefined: false
|
|
6
|
+
};
|
|
7
|
+
class SerializerRegistry {
|
|
8
|
+
serializers = /* @__PURE__ */ new Map();
|
|
9
|
+
config;
|
|
10
|
+
constructor(config = {}) {
|
|
11
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
12
|
+
this.registerDefaults();
|
|
13
|
+
}
|
|
14
|
+
registerDefaults() {
|
|
15
|
+
this.add(Error, (err) => ({
|
|
16
|
+
name: err.name,
|
|
17
|
+
message: err.message,
|
|
18
|
+
stack: err.stack?.split("\n").slice(0, 10),
|
|
19
|
+
...err.cause ? { cause: this.serialize(err.cause) } : {}
|
|
20
|
+
}), 100);
|
|
21
|
+
this.add(Date, (date) => ({
|
|
22
|
+
iso: date.toISOString(),
|
|
23
|
+
timestamp: date.getTime()
|
|
24
|
+
}), 90);
|
|
25
|
+
this.add(RegExp, (regex) => ({
|
|
26
|
+
pattern: regex.source,
|
|
27
|
+
flags: regex.flags
|
|
28
|
+
}), 90);
|
|
29
|
+
this.add(Map, (map, ctx) => {
|
|
30
|
+
const obj = {};
|
|
31
|
+
map.forEach((value, key) => {
|
|
32
|
+
const keyStr = typeof key === "object" ? JSON.stringify(key) : String(key);
|
|
33
|
+
obj[keyStr] = this.serializeInternal(value, {
|
|
34
|
+
...ctx,
|
|
35
|
+
depth: ctx.depth + 1,
|
|
36
|
+
path: [...ctx.path, keyStr]
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
return { __type: "Map", entries: obj };
|
|
40
|
+
}, 80);
|
|
41
|
+
this.add(Set, (set, ctx) => ({
|
|
42
|
+
__type: "Set",
|
|
43
|
+
values: Array.from(set).map(
|
|
44
|
+
(v, i) => this.serializeInternal(v, {
|
|
45
|
+
...ctx,
|
|
46
|
+
depth: ctx.depth + 1,
|
|
47
|
+
path: [...ctx.path, `[${i}]`]
|
|
48
|
+
})
|
|
49
|
+
)
|
|
50
|
+
}), 80);
|
|
51
|
+
if (typeof Buffer !== "undefined") {
|
|
52
|
+
this.add(Buffer, (buf) => ({
|
|
53
|
+
__type: "Buffer",
|
|
54
|
+
length: buf.length,
|
|
55
|
+
preview: buf.slice(0, 50).toString("hex")
|
|
56
|
+
}), 70);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
add(type, serializer, priority = 50) {
|
|
60
|
+
this.serializers.set(type, { type, serializer, priority });
|
|
61
|
+
}
|
|
62
|
+
remove(type) {
|
|
63
|
+
return this.serializers.delete(type);
|
|
64
|
+
}
|
|
65
|
+
has(type) {
|
|
66
|
+
return this.serializers.has(type);
|
|
67
|
+
}
|
|
68
|
+
getAll() {
|
|
69
|
+
return Array.from(this.serializers.values()).sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50));
|
|
70
|
+
}
|
|
71
|
+
findSerializer(value) {
|
|
72
|
+
const sorted = this.getAll();
|
|
73
|
+
for (const entry of sorted) {
|
|
74
|
+
if (value instanceof entry.type) {
|
|
75
|
+
return entry;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
serializeInternal(value, context) {
|
|
81
|
+
if (value === null) return null;
|
|
82
|
+
if (value === void 0) return this.config.preserveUndefined ? void 0 : "[undefined]";
|
|
83
|
+
if (typeof value === "function") return `[Function: ${value.name || "anonymous"}]`;
|
|
84
|
+
if (typeof value !== "object") return value;
|
|
85
|
+
if (context.depth >= this.config.maxDepth) {
|
|
86
|
+
return "[Max Depth]";
|
|
87
|
+
}
|
|
88
|
+
if (context.seen.has(value)) {
|
|
89
|
+
switch (this.config.circular) {
|
|
90
|
+
case "error":
|
|
91
|
+
throw new Error(`Circular reference at ${context.path.join(".")}`);
|
|
92
|
+
case "skip":
|
|
93
|
+
return void 0;
|
|
94
|
+
case "placeholder":
|
|
95
|
+
default:
|
|
96
|
+
return "[Circular]";
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
context.seen.add(value);
|
|
100
|
+
const serializer = this.findSerializer(value);
|
|
101
|
+
if (serializer) {
|
|
102
|
+
return serializer.serializer(value, context);
|
|
103
|
+
}
|
|
104
|
+
if (Array.isArray(value)) {
|
|
105
|
+
return value.map(
|
|
106
|
+
(item, i) => this.serializeInternal(item, {
|
|
107
|
+
...context,
|
|
108
|
+
depth: context.depth + 1,
|
|
109
|
+
path: [...context.path, `[${i}]`]
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
const result = {};
|
|
114
|
+
for (const [key, val] of Object.entries(value)) {
|
|
115
|
+
result[key] = this.serializeInternal(val, {
|
|
116
|
+
...context,
|
|
117
|
+
depth: context.depth + 1,
|
|
118
|
+
path: [...context.path, key]
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
serialize(value, config) {
|
|
124
|
+
const mergedConfig = { ...this.config, ...config };
|
|
125
|
+
return this.serializeInternal(value, {
|
|
126
|
+
depth: 0,
|
|
127
|
+
maxDepth: mergedConfig.maxDepth,
|
|
128
|
+
path: [],
|
|
129
|
+
seen: /* @__PURE__ */ new WeakSet()
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function generateId() {
|
|
134
|
+
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
135
|
+
}
|
|
136
|
+
class HookManager {
|
|
137
|
+
hooks = /* @__PURE__ */ new Map();
|
|
138
|
+
middlewares = [];
|
|
139
|
+
constructor() {
|
|
140
|
+
this.hooks.set("beforeLog", []);
|
|
141
|
+
this.hooks.set("afterLog", []);
|
|
142
|
+
this.hooks.set("onError", []);
|
|
143
|
+
}
|
|
144
|
+
on(event, callback, priority = 50) {
|
|
145
|
+
const registration = {
|
|
146
|
+
id: generateId(),
|
|
147
|
+
event,
|
|
148
|
+
callback,
|
|
149
|
+
priority,
|
|
150
|
+
once: false
|
|
151
|
+
};
|
|
152
|
+
const hooks = this.hooks.get(event);
|
|
153
|
+
hooks.push(registration);
|
|
154
|
+
hooks.sort((a, b) => b.priority - a.priority);
|
|
155
|
+
return () => this.removeHook(event, registration.id);
|
|
156
|
+
}
|
|
157
|
+
once(event, callback, priority = 50) {
|
|
158
|
+
const registration = {
|
|
159
|
+
id: generateId(),
|
|
160
|
+
event,
|
|
161
|
+
callback,
|
|
162
|
+
priority,
|
|
163
|
+
once: true
|
|
164
|
+
};
|
|
165
|
+
const hooks = this.hooks.get(event);
|
|
166
|
+
hooks.push(registration);
|
|
167
|
+
hooks.sort((a, b) => b.priority - a.priority);
|
|
168
|
+
return () => this.removeHook(event, registration.id);
|
|
169
|
+
}
|
|
170
|
+
off(event, callback) {
|
|
171
|
+
const hooks = this.hooks.get(event);
|
|
172
|
+
if (!hooks) return false;
|
|
173
|
+
const index = hooks.findIndex((h) => h.callback === callback);
|
|
174
|
+
if (index >= 0) {
|
|
175
|
+
hooks.splice(index, 1);
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
removeHook(event, id) {
|
|
181
|
+
const hooks = this.hooks.get(event);
|
|
182
|
+
if (hooks) {
|
|
183
|
+
const index = hooks.findIndex((h) => h.id === id);
|
|
184
|
+
if (index >= 0) {
|
|
185
|
+
hooks.splice(index, 1);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
use(middleware, priority = 50) {
|
|
190
|
+
const registration = {
|
|
191
|
+
id: generateId(),
|
|
192
|
+
fn: middleware,
|
|
193
|
+
priority
|
|
194
|
+
};
|
|
195
|
+
this.middlewares.push(registration);
|
|
196
|
+
this.middlewares.sort((a, b) => b.priority - a.priority);
|
|
197
|
+
return () => {
|
|
198
|
+
const index = this.middlewares.findIndex((m) => m.id === registration.id);
|
|
199
|
+
if (index >= 0) {
|
|
200
|
+
this.middlewares.splice(index, 1);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
async emit(event, entry) {
|
|
205
|
+
const hooks = this.hooks.get(event) || [];
|
|
206
|
+
let currentEntry = { ...entry };
|
|
207
|
+
const toRemove = [];
|
|
208
|
+
for (const hook of hooks) {
|
|
209
|
+
try {
|
|
210
|
+
const result = await hook.callback(currentEntry);
|
|
211
|
+
if (result) {
|
|
212
|
+
currentEntry = { ...currentEntry, ...result };
|
|
213
|
+
}
|
|
214
|
+
if (hook.once) {
|
|
215
|
+
toRemove.push(hook.id);
|
|
216
|
+
}
|
|
217
|
+
} catch (error) {
|
|
218
|
+
if (event !== "onError") {
|
|
219
|
+
await this.emit("onError", {
|
|
220
|
+
...currentEntry,
|
|
221
|
+
error,
|
|
222
|
+
hookEvent: event
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
toRemove.forEach((id) => this.removeHook(event, id));
|
|
228
|
+
return currentEntry;
|
|
229
|
+
}
|
|
230
|
+
async process(entry) {
|
|
231
|
+
let currentEntry = { ...entry };
|
|
232
|
+
currentEntry = await this.emit("beforeLog", currentEntry);
|
|
233
|
+
if (this.middlewares.length > 0) {
|
|
234
|
+
let index = 0;
|
|
235
|
+
const executeNext = async () => {
|
|
236
|
+
if (index < this.middlewares.length) {
|
|
237
|
+
const middleware = this.middlewares[index++];
|
|
238
|
+
if (middleware) {
|
|
239
|
+
await middleware.fn(currentEntry, executeNext);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
await executeNext();
|
|
244
|
+
}
|
|
245
|
+
return currentEntry;
|
|
246
|
+
}
|
|
247
|
+
async afterProcess(entry) {
|
|
248
|
+
await this.emit("afterLog", entry);
|
|
249
|
+
}
|
|
250
|
+
clear() {
|
|
251
|
+
this.hooks.forEach((hooks) => hooks.length = 0);
|
|
252
|
+
this.middlewares.length = 0;
|
|
253
|
+
}
|
|
254
|
+
getStats() {
|
|
255
|
+
return {
|
|
256
|
+
hooks: {
|
|
257
|
+
beforeLog: this.hooks.get("beforeLog")?.length || 0,
|
|
258
|
+
afterLog: this.hooks.get("afterLog")?.length || 0,
|
|
259
|
+
onError: this.hooks.get("onError")?.length || 0
|
|
260
|
+
},
|
|
261
|
+
middlewares: this.middlewares.length
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const LOG_LEVELS = {
|
|
266
|
+
debug: 0,
|
|
267
|
+
info: 1,
|
|
268
|
+
warn: 2,
|
|
269
|
+
error: 3,
|
|
270
|
+
critical: 4
|
|
271
|
+
};
|
|
272
|
+
function generateTransportId() {
|
|
273
|
+
return `transport-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`;
|
|
274
|
+
}
|
|
275
|
+
class TransportManager {
|
|
276
|
+
transports = /* @__PURE__ */ new Map();
|
|
277
|
+
defaultLevel = "info";
|
|
278
|
+
constructor(defaultLevel) {
|
|
279
|
+
if (defaultLevel) {
|
|
280
|
+
this.defaultLevel = defaultLevel;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
add(target) {
|
|
284
|
+
const id = generateTransportId();
|
|
285
|
+
const level = target.level || this.defaultLevel;
|
|
286
|
+
let transport;
|
|
287
|
+
if (typeof target.target === "string") {
|
|
288
|
+
throw new Error(`String transport targets not supported. Use inline transport object.`);
|
|
289
|
+
} else {
|
|
290
|
+
transport = target.target;
|
|
291
|
+
}
|
|
292
|
+
const entry = {
|
|
293
|
+
id,
|
|
294
|
+
transport,
|
|
295
|
+
options: target.options || {},
|
|
296
|
+
level,
|
|
297
|
+
levelValue: LOG_LEVELS[level]
|
|
298
|
+
};
|
|
299
|
+
this.transports.set(id, entry);
|
|
300
|
+
return id;
|
|
301
|
+
}
|
|
302
|
+
remove(id) {
|
|
303
|
+
const entry = this.transports.get(id);
|
|
304
|
+
if (entry) {
|
|
305
|
+
entry.transport.close?.();
|
|
306
|
+
return this.transports.delete(id);
|
|
307
|
+
}
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
async write(record) {
|
|
311
|
+
const promises = [];
|
|
312
|
+
for (const entry of this.transports.values()) {
|
|
313
|
+
if (record.levelValue < entry.levelValue) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
let transformedRecord = record;
|
|
317
|
+
if (entry.options.transform) {
|
|
318
|
+
const result2 = entry.options.transform(record);
|
|
319
|
+
if (result2 === null) continue;
|
|
320
|
+
transformedRecord = result2;
|
|
321
|
+
}
|
|
322
|
+
const result = entry.transport.write(transformedRecord);
|
|
323
|
+
if (result instanceof Promise) {
|
|
324
|
+
promises.push(result);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
await Promise.all(promises);
|
|
328
|
+
}
|
|
329
|
+
async flush() {
|
|
330
|
+
const promises = [];
|
|
331
|
+
for (const entry of this.transports.values()) {
|
|
332
|
+
if (entry.transport.flush) {
|
|
333
|
+
const result = entry.transport.flush();
|
|
334
|
+
if (result instanceof Promise) {
|
|
335
|
+
promises.push(result);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
await Promise.all(promises);
|
|
340
|
+
}
|
|
341
|
+
async close() {
|
|
342
|
+
await this.flush();
|
|
343
|
+
const promises = [];
|
|
344
|
+
for (const entry of this.transports.values()) {
|
|
345
|
+
if (entry.transport.close) {
|
|
346
|
+
const result = entry.transport.close();
|
|
347
|
+
if (result instanceof Promise) {
|
|
348
|
+
promises.push(result);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
await Promise.all(promises);
|
|
353
|
+
this.transports.clear();
|
|
354
|
+
}
|
|
355
|
+
get count() {
|
|
356
|
+
return this.transports.size;
|
|
357
|
+
}
|
|
358
|
+
list() {
|
|
359
|
+
return Array.from(this.transports.keys());
|
|
360
|
+
}
|
|
361
|
+
}
|
|
2
362
|
const THEME_PRESETS = {
|
|
3
363
|
default: {
|
|
4
364
|
debug: {
|
|
@@ -1210,6 +1570,193 @@ function getAvailablePresets() {
|
|
|
1210
1570
|
function hasPreset(name) {
|
|
1211
1571
|
return name in SMART_PRESETS;
|
|
1212
1572
|
}
|
|
1573
|
+
class ScopedLogger {
|
|
1574
|
+
parent;
|
|
1575
|
+
scopeName;
|
|
1576
|
+
badgeList = [];
|
|
1577
|
+
contextStack = [];
|
|
1578
|
+
_timers;
|
|
1579
|
+
constructor(parent, scopeName) {
|
|
1580
|
+
this.parent = parent;
|
|
1581
|
+
this.scopeName = scopeName;
|
|
1582
|
+
}
|
|
1583
|
+
get timers() {
|
|
1584
|
+
if (!this._timers) this._timers = /* @__PURE__ */ new Map();
|
|
1585
|
+
return this._timers;
|
|
1586
|
+
}
|
|
1587
|
+
getBindings() {
|
|
1588
|
+
return {
|
|
1589
|
+
scope: this.getScopePrefix(),
|
|
1590
|
+
badges: this.badgeList.length > 0 ? [...this.badgeList] : void 0
|
|
1591
|
+
};
|
|
1592
|
+
}
|
|
1593
|
+
getScopePrefix() {
|
|
1594
|
+
if (this.contextStack.length === 0) return this.scopeName;
|
|
1595
|
+
return [this.scopeName, ...this.contextStack].join(":");
|
|
1596
|
+
}
|
|
1597
|
+
badges(badges) {
|
|
1598
|
+
this.badgeList = [...badges];
|
|
1599
|
+
return this;
|
|
1600
|
+
}
|
|
1601
|
+
badge(badge) {
|
|
1602
|
+
if (!this.badgeList.includes(badge)) {
|
|
1603
|
+
this.badgeList.push(badge);
|
|
1604
|
+
}
|
|
1605
|
+
return this;
|
|
1606
|
+
}
|
|
1607
|
+
clearBadges() {
|
|
1608
|
+
this.badgeList = [];
|
|
1609
|
+
return this;
|
|
1610
|
+
}
|
|
1611
|
+
style(presetName) {
|
|
1612
|
+
this.parent.setTheme(presetName);
|
|
1613
|
+
return this;
|
|
1614
|
+
}
|
|
1615
|
+
context(contextName) {
|
|
1616
|
+
return new ContextLogger(this, contextName);
|
|
1617
|
+
}
|
|
1618
|
+
time(label) {
|
|
1619
|
+
this.timers.set(label, {
|
|
1620
|
+
label: `${this.scopeName}:${label}`,
|
|
1621
|
+
startTime: performance.now()
|
|
1622
|
+
});
|
|
1623
|
+
}
|
|
1624
|
+
timeEnd(label) {
|
|
1625
|
+
const timer = this.timers.get(label);
|
|
1626
|
+
if (!timer) {
|
|
1627
|
+
this.warn(`Timer '${label}' not found`);
|
|
1628
|
+
return void 0;
|
|
1629
|
+
}
|
|
1630
|
+
const elapsed = performance.now() - timer.startTime;
|
|
1631
|
+
this.timers.delete(label);
|
|
1632
|
+
this.success(`Timer: ${label} - ${elapsed.toFixed(2)}ms`);
|
|
1633
|
+
return elapsed;
|
|
1634
|
+
}
|
|
1635
|
+
debug(...args) {
|
|
1636
|
+
this.parent.logWithBindings(this.getBindings(), "debug", ...args);
|
|
1637
|
+
}
|
|
1638
|
+
info(...args) {
|
|
1639
|
+
this.parent.logWithBindings(this.getBindings(), "info", ...args);
|
|
1640
|
+
}
|
|
1641
|
+
warn(...args) {
|
|
1642
|
+
this.parent.logWithBindings(this.getBindings(), "warn", ...args);
|
|
1643
|
+
}
|
|
1644
|
+
error(...args) {
|
|
1645
|
+
this.parent.logWithBindings(this.getBindings(), "error", ...args);
|
|
1646
|
+
}
|
|
1647
|
+
success(...args) {
|
|
1648
|
+
const bindings = this.getBindings();
|
|
1649
|
+
this.parent.logWithBindings(bindings, "info", ...args);
|
|
1650
|
+
}
|
|
1651
|
+
critical(...args) {
|
|
1652
|
+
this.parent.logWithBindings(this.getBindings(), "critical", ...args);
|
|
1653
|
+
}
|
|
1654
|
+
trace(...args) {
|
|
1655
|
+
this.parent.logWithBindings(this.getBindings(), "debug", ...args);
|
|
1656
|
+
console.trace(`[${this.scopeName}]`);
|
|
1657
|
+
}
|
|
1658
|
+
_pushContext(context) {
|
|
1659
|
+
this.contextStack.push(context);
|
|
1660
|
+
}
|
|
1661
|
+
_popContext() {
|
|
1662
|
+
this.contextStack.pop();
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
class APILogger extends ScopedLogger {
|
|
1666
|
+
constructor(parent, apiName) {
|
|
1667
|
+
super(parent, `API:${apiName}`);
|
|
1668
|
+
this.badge("API");
|
|
1669
|
+
}
|
|
1670
|
+
slow(message, duration) {
|
|
1671
|
+
this.badge("SLOW");
|
|
1672
|
+
const msg = duration ? `${message} (${duration}ms)` : message;
|
|
1673
|
+
this.warn(msg);
|
|
1674
|
+
}
|
|
1675
|
+
rateLimit(message) {
|
|
1676
|
+
this.badge("RATE_LIMIT");
|
|
1677
|
+
this.warn(message);
|
|
1678
|
+
}
|
|
1679
|
+
auth(message) {
|
|
1680
|
+
this.badge("AUTH");
|
|
1681
|
+
this.error(message);
|
|
1682
|
+
}
|
|
1683
|
+
deprecated(message) {
|
|
1684
|
+
this.badge("DEPRECATED");
|
|
1685
|
+
this.warn(message);
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
class ComponentLogger extends ScopedLogger {
|
|
1689
|
+
constructor(parent, componentName) {
|
|
1690
|
+
super(parent, componentName);
|
|
1691
|
+
this.badge("COMPONENT");
|
|
1692
|
+
}
|
|
1693
|
+
lifecycle(event, message) {
|
|
1694
|
+
this.badge("LIFECYCLE");
|
|
1695
|
+
const msg = message ? `${event}: ${message}` : event;
|
|
1696
|
+
this.info(msg);
|
|
1697
|
+
}
|
|
1698
|
+
stateChange(from, to, data) {
|
|
1699
|
+
this.badge("STATE");
|
|
1700
|
+
const msg = `${from} → ${to}`;
|
|
1701
|
+
if (data) {
|
|
1702
|
+
this.info(msg, data);
|
|
1703
|
+
} else {
|
|
1704
|
+
this.info(msg);
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
propsChange(changes) {
|
|
1708
|
+
this.badge("PROPS");
|
|
1709
|
+
this.debug("Props changed:", changes);
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
class ContextLogger {
|
|
1713
|
+
parentLogger;
|
|
1714
|
+
contextName;
|
|
1715
|
+
constructor(parentLogger, contextName) {
|
|
1716
|
+
this.parentLogger = parentLogger;
|
|
1717
|
+
this.contextName = contextName;
|
|
1718
|
+
}
|
|
1719
|
+
run(fn) {
|
|
1720
|
+
this.parentLogger._pushContext(this.contextName);
|
|
1721
|
+
try {
|
|
1722
|
+
return fn();
|
|
1723
|
+
} finally {
|
|
1724
|
+
this.parentLogger._popContext();
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
async runAsync(fn) {
|
|
1728
|
+
this.parentLogger._pushContext(this.contextName);
|
|
1729
|
+
try {
|
|
1730
|
+
return await fn();
|
|
1731
|
+
} finally {
|
|
1732
|
+
this.parentLogger._popContext();
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
start() {
|
|
1736
|
+
this.parentLogger._pushContext(this.contextName);
|
|
1737
|
+
}
|
|
1738
|
+
end() {
|
|
1739
|
+
this.parentLogger._popContext();
|
|
1740
|
+
}
|
|
1741
|
+
debug(...args) {
|
|
1742
|
+
this.parentLogger.debug(...args);
|
|
1743
|
+
}
|
|
1744
|
+
info(...args) {
|
|
1745
|
+
this.parentLogger.info(...args);
|
|
1746
|
+
}
|
|
1747
|
+
warn(...args) {
|
|
1748
|
+
this.parentLogger.warn(...args);
|
|
1749
|
+
}
|
|
1750
|
+
error(...args) {
|
|
1751
|
+
this.parentLogger.error(...args);
|
|
1752
|
+
}
|
|
1753
|
+
success(...args) {
|
|
1754
|
+
this.parentLogger.success(...args);
|
|
1755
|
+
}
|
|
1756
|
+
critical(...args) {
|
|
1757
|
+
this.parentLogger.critical(...args);
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1213
1760
|
class ExportLogHandler {
|
|
1214
1761
|
buffer = [];
|
|
1215
1762
|
maxSize;
|
|
@@ -2497,11 +3044,15 @@ class Logger {
|
|
|
2497
3044
|
exportHandler;
|
|
2498
3045
|
cliProcessor;
|
|
2499
3046
|
themeChangeListener;
|
|
3047
|
+
badgeList = [];
|
|
2500
3048
|
displaySettings = {
|
|
2501
3049
|
showTimestamp: true,
|
|
2502
3050
|
showLocation: true,
|
|
2503
3051
|
showBadges: true
|
|
2504
3052
|
};
|
|
3053
|
+
serializerRegistry;
|
|
3054
|
+
hookManager;
|
|
3055
|
+
transportManager;
|
|
2505
3056
|
/**
|
|
2506
3057
|
* Crea una nueva instancia del Logger
|
|
2507
3058
|
*
|
|
@@ -2518,9 +3069,11 @@ class Logger {
|
|
|
2518
3069
|
*/
|
|
2519
3070
|
constructor(config = {}) {
|
|
2520
3071
|
this.config = {
|
|
2521
|
-
...DEFAULT_CONFIG,
|
|
3072
|
+
...DEFAULT_CONFIG$1,
|
|
2522
3073
|
...config
|
|
2523
3074
|
};
|
|
3075
|
+
this.serializerRegistry = new SerializerRegistry();
|
|
3076
|
+
this.hookManager = new HookManager();
|
|
2524
3077
|
if (this.config.bufferSize) {
|
|
2525
3078
|
this.exportHandler = new ExportLogHandler(this.config.bufferSize);
|
|
2526
3079
|
this.handlers.push(this.exportHandler);
|
|
@@ -2675,7 +3228,7 @@ class Logger {
|
|
|
2675
3228
|
this.themeChangeListener();
|
|
2676
3229
|
this.themeChangeListener = null;
|
|
2677
3230
|
}
|
|
2678
|
-
this.config = { ...DEFAULT_CONFIG };
|
|
3231
|
+
this.config = { ...DEFAULT_CONFIG$1 };
|
|
2679
3232
|
LEVEL_STYLES = THEME_PRESETS.default;
|
|
2680
3233
|
if (this.config.autoDetectTheme) {
|
|
2681
3234
|
this.setupAutoThemeDetection();
|
|
@@ -2696,32 +3249,8 @@ class Logger {
|
|
|
2696
3249
|
this.themeChangeListener();
|
|
2697
3250
|
this.themeChangeListener = null;
|
|
2698
3251
|
}
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
* Factory method para crear loggers con scope evitando dependencias circulares
|
|
2702
|
-
* @private
|
|
2703
|
-
* @param {string} type - Tipo de logger ('scope' | 'api' | 'component')
|
|
2704
|
-
* @param {string} name - Nombre del scope
|
|
2705
|
-
* @returns {Promise<any>} Logger con scope
|
|
2706
|
-
*/
|
|
2707
|
-
async createScopedLogger(type, name) {
|
|
2708
|
-
try {
|
|
2709
|
-
const { ScopedLogger, APILogger, ComponentLogger } = await import("./ScopedLogger-D-RbiFZn.js");
|
|
2710
|
-
switch (type) {
|
|
2711
|
-
case "component":
|
|
2712
|
-
return new ComponentLogger(this, name);
|
|
2713
|
-
case "api":
|
|
2714
|
-
return new APILogger(this, name);
|
|
2715
|
-
case "scope":
|
|
2716
|
-
default:
|
|
2717
|
-
return new ScopedLogger(this, name);
|
|
2718
|
-
}
|
|
2719
|
-
} catch (error2) {
|
|
2720
|
-
this.error("Failed to load ScopedLogger, using basic logger with prefix:", error2);
|
|
2721
|
-
const basicLogger = new Logger(this.getConfig());
|
|
2722
|
-
basicLogger.setGlobalPrefix(`${this.config.globalPrefix || ""}:${name}`);
|
|
2723
|
-
return basicLogger;
|
|
2724
|
-
}
|
|
3252
|
+
this.transportManager?.close().catch(() => {
|
|
3253
|
+
});
|
|
2725
3254
|
}
|
|
2726
3255
|
// ===== SIMPLIFIED API =====
|
|
2727
3256
|
/**
|
|
@@ -2839,77 +3368,74 @@ class Logger {
|
|
|
2839
3368
|
}
|
|
2840
3369
|
/**
|
|
2841
3370
|
* Muestra los badges en los logs
|
|
2842
|
-
*
|
|
3371
|
+
*
|
|
2843
3372
|
* @example
|
|
2844
3373
|
* logger.showBadges();
|
|
2845
3374
|
* const api = logger.api('GraphQL');
|
|
2846
3375
|
* api.info('Con badges'); // [API] [GraphQL] Con badges
|
|
2847
|
-
*
|
|
3376
|
+
*
|
|
2848
3377
|
* @since 0.3.0
|
|
2849
3378
|
*/
|
|
2850
3379
|
showBadges() {
|
|
2851
3380
|
this.displaySettings.showBadges = true;
|
|
2852
3381
|
this.success("Badges shown");
|
|
2853
3382
|
}
|
|
2854
|
-
// ===== SCOPED LOGGERS =====
|
|
2855
3383
|
/**
|
|
2856
|
-
*
|
|
2857
|
-
*
|
|
2858
|
-
* @param {string}
|
|
2859
|
-
* @returns {
|
|
2860
|
-
*
|
|
3384
|
+
* Establece múltiples badges para los logs
|
|
3385
|
+
*
|
|
3386
|
+
* @param {string[]} badges - Array de badges a mostrar
|
|
3387
|
+
* @returns {this} Logger instance para encadenamiento
|
|
3388
|
+
*
|
|
2861
3389
|
* @example
|
|
2862
|
-
*
|
|
2863
|
-
*
|
|
2864
|
-
*
|
|
2865
|
-
*
|
|
2866
|
-
* authLogger.success('Usuario autenticado');
|
|
2867
|
-
* // [COMPONENT] [Autenticación] ✓ Usuario autenticado
|
|
2868
|
-
*
|
|
2869
|
-
* @since 0.3.0
|
|
3390
|
+
* logger.badges(['v3', 'stable']).info('Release publicado');
|
|
3391
|
+
* logger.badges(['API', 'v2']).warn('Endpoint deprecado');
|
|
3392
|
+
*
|
|
3393
|
+
* @since 3.0.0
|
|
2870
3394
|
*/
|
|
2871
|
-
|
|
2872
|
-
|
|
3395
|
+
badges(badges2) {
|
|
3396
|
+
this.badgeList = [...badges2];
|
|
3397
|
+
return this;
|
|
2873
3398
|
}
|
|
2874
3399
|
/**
|
|
2875
|
-
*
|
|
2876
|
-
*
|
|
2877
|
-
* @param {string}
|
|
2878
|
-
* @returns {
|
|
2879
|
-
*
|
|
3400
|
+
* Añade un badge individual a la lista
|
|
3401
|
+
*
|
|
3402
|
+
* @param {string} badge - Badge a añadir
|
|
3403
|
+
* @returns {this} Logger instance para encadenamiento
|
|
3404
|
+
*
|
|
2880
3405
|
* @example
|
|
2881
|
-
*
|
|
2882
|
-
*
|
|
2883
|
-
*
|
|
2884
|
-
*
|
|
2885
|
-
* // Con badges adicionales
|
|
2886
|
-
* api.badges(['v2', 'cached']).info('Respuesta desde caché');
|
|
2887
|
-
* // [API] [v2] [cached] [REST] Respuesta desde caché
|
|
2888
|
-
*
|
|
2889
|
-
* @since 0.3.0
|
|
3406
|
+
* logger.badge('DEBUG').badge('AUTH').info('Token validado');
|
|
3407
|
+
*
|
|
3408
|
+
* @since 3.0.0
|
|
2890
3409
|
*/
|
|
2891
|
-
|
|
2892
|
-
|
|
3410
|
+
badge(badge2) {
|
|
3411
|
+
if (!this.badgeList.includes(badge2)) {
|
|
3412
|
+
this.badgeList.push(badge2);
|
|
3413
|
+
}
|
|
3414
|
+
return this;
|
|
2893
3415
|
}
|
|
2894
3416
|
/**
|
|
2895
|
-
*
|
|
2896
|
-
*
|
|
2897
|
-
* @
|
|
2898
|
-
*
|
|
2899
|
-
*
|
|
3417
|
+
* Limpia todos los badges activos
|
|
3418
|
+
*
|
|
3419
|
+
* @returns {this} Logger instance para encadenamiento
|
|
3420
|
+
*
|
|
2900
3421
|
* @example
|
|
2901
|
-
*
|
|
2902
|
-
*
|
|
2903
|
-
*
|
|
2904
|
-
*
|
|
2905
|
-
* // Con badges personalizados
|
|
2906
|
-
* dbLogger.badge('SLOW').warn('Query tardó 5s');
|
|
2907
|
-
* // [SLOW] [Database] Query tardó 5s
|
|
2908
|
-
*
|
|
2909
|
-
* @since 0.3.0
|
|
3422
|
+
* logger.clearBadges().info('Sin badges');
|
|
3423
|
+
*
|
|
3424
|
+
* @since 3.0.0
|
|
2910
3425
|
*/
|
|
3426
|
+
clearBadges() {
|
|
3427
|
+
this.badgeList = [];
|
|
3428
|
+
return this;
|
|
3429
|
+
}
|
|
3430
|
+
// ===== SCOPED LOGGERS =====
|
|
3431
|
+
component(name) {
|
|
3432
|
+
return new ComponentLogger(this, name);
|
|
3433
|
+
}
|
|
3434
|
+
api(name) {
|
|
3435
|
+
return new APILogger(this, name);
|
|
3436
|
+
}
|
|
2911
3437
|
scope(name) {
|
|
2912
|
-
return this
|
|
3438
|
+
return new ScopedLogger(this, name);
|
|
2913
3439
|
}
|
|
2914
3440
|
// ===== SIMPLE CUSTOMIZATION =====
|
|
2915
3441
|
/**
|
|
@@ -2981,13 +3507,199 @@ class Logger {
|
|
|
2981
3507
|
}
|
|
2982
3508
|
/**
|
|
2983
3509
|
* Obtiene el handler de exportación si está disponible
|
|
2984
|
-
*
|
|
3510
|
+
*
|
|
2985
3511
|
* @returns {ExportLogHandler | undefined} Handler de exportación o undefined
|
|
2986
3512
|
* @since 0.3.0
|
|
2987
3513
|
*/
|
|
2988
3514
|
getExportHandler() {
|
|
2989
3515
|
return this.exportHandler;
|
|
2990
3516
|
}
|
|
3517
|
+
// ===== SERIALIZERS =====
|
|
3518
|
+
/**
|
|
3519
|
+
* Añade un serializador personalizado para un tipo específico
|
|
3520
|
+
*
|
|
3521
|
+
* @param type - Constructor del tipo a serializar
|
|
3522
|
+
* @param serializer - Función de serialización
|
|
3523
|
+
* @param priority - Prioridad (mayor = primero)
|
|
3524
|
+
*
|
|
3525
|
+
* @example
|
|
3526
|
+
* logger.addSerializer(Error, (err) => ({
|
|
3527
|
+
* name: err.name,
|
|
3528
|
+
* message: err.message,
|
|
3529
|
+
* stack: err.stack?.split('\n').slice(0, 5)
|
|
3530
|
+
* }));
|
|
3531
|
+
*
|
|
3532
|
+
* @since 3.0.0
|
|
3533
|
+
*/
|
|
3534
|
+
addSerializer(type, serializer, priority) {
|
|
3535
|
+
this.serializerRegistry.add(type, serializer, priority);
|
|
3536
|
+
}
|
|
3537
|
+
/**
|
|
3538
|
+
* Elimina un serializador registrado
|
|
3539
|
+
*
|
|
3540
|
+
* @param type - Constructor del tipo a remover
|
|
3541
|
+
* @returns true si se eliminó
|
|
3542
|
+
*
|
|
3543
|
+
* @since 3.0.0
|
|
3544
|
+
*/
|
|
3545
|
+
removeSerializer(type) {
|
|
3546
|
+
return this.serializerRegistry.remove(type);
|
|
3547
|
+
}
|
|
3548
|
+
/**
|
|
3549
|
+
* Obtiene el registry de serializadores
|
|
3550
|
+
*
|
|
3551
|
+
* @returns SerializerRegistry
|
|
3552
|
+
* @since 3.0.0
|
|
3553
|
+
*/
|
|
3554
|
+
getSerializerRegistry() {
|
|
3555
|
+
return this.serializerRegistry;
|
|
3556
|
+
}
|
|
3557
|
+
// ===== HOOKS & MIDDLEWARE =====
|
|
3558
|
+
/**
|
|
3559
|
+
* Registra un hook para un evento
|
|
3560
|
+
*
|
|
3561
|
+
* @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'
|
|
3562
|
+
* @param callback - Función a ejecutar
|
|
3563
|
+
* @param priority - Prioridad (mayor = primero)
|
|
3564
|
+
* @returns Función para desregistrar
|
|
3565
|
+
*
|
|
3566
|
+
* @example
|
|
3567
|
+
* const unsubscribe = logger.on('beforeLog', (entry) => {
|
|
3568
|
+
* entry.correlationId = getCorrelationId();
|
|
3569
|
+
* return entry;
|
|
3570
|
+
* });
|
|
3571
|
+
*
|
|
3572
|
+
* @since 3.0.0
|
|
3573
|
+
*/
|
|
3574
|
+
on(event, callback, priority) {
|
|
3575
|
+
return this.hookManager.on(event, callback, priority);
|
|
3576
|
+
}
|
|
3577
|
+
/**
|
|
3578
|
+
* Registra un hook que se ejecuta solo una vez
|
|
3579
|
+
*
|
|
3580
|
+
* @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'
|
|
3581
|
+
* @param callback - Función a ejecutar
|
|
3582
|
+
* @param priority - Prioridad (mayor = primero)
|
|
3583
|
+
* @returns Función para desregistrar
|
|
3584
|
+
*
|
|
3585
|
+
* @since 3.0.0
|
|
3586
|
+
*/
|
|
3587
|
+
once(event, callback, priority) {
|
|
3588
|
+
return this.hookManager.once(event, callback, priority);
|
|
3589
|
+
}
|
|
3590
|
+
/**
|
|
3591
|
+
* Elimina un hook registrado
|
|
3592
|
+
*
|
|
3593
|
+
* @param event - Evento del hook
|
|
3594
|
+
* @param callback - Callback a remover
|
|
3595
|
+
* @returns true si se eliminó
|
|
3596
|
+
*
|
|
3597
|
+
* @since 3.0.0
|
|
3598
|
+
*/
|
|
3599
|
+
off(event, callback) {
|
|
3600
|
+
return this.hookManager.off(event, callback);
|
|
3601
|
+
}
|
|
3602
|
+
/**
|
|
3603
|
+
* Añade un middleware al pipeline
|
|
3604
|
+
*
|
|
3605
|
+
* @param middleware - Función middleware
|
|
3606
|
+
* @param priority - Prioridad (mayor = primero)
|
|
3607
|
+
* @returns Función para desregistrar
|
|
3608
|
+
*
|
|
3609
|
+
* @example
|
|
3610
|
+
* logger.use((entry, next) => {
|
|
3611
|
+
* entry.requestId = asyncLocalStorage.getStore()?.requestId;
|
|
3612
|
+
* next();
|
|
3613
|
+
* });
|
|
3614
|
+
*
|
|
3615
|
+
* @since 3.0.0
|
|
3616
|
+
*/
|
|
3617
|
+
use(middleware, priority) {
|
|
3618
|
+
return this.hookManager.use(middleware, priority);
|
|
3619
|
+
}
|
|
3620
|
+
/**
|
|
3621
|
+
* Obtiene el HookManager
|
|
3622
|
+
*
|
|
3623
|
+
* @returns HookManager
|
|
3624
|
+
* @since 3.0.0
|
|
3625
|
+
*/
|
|
3626
|
+
getHookManager() {
|
|
3627
|
+
return this.hookManager;
|
|
3628
|
+
}
|
|
3629
|
+
// ===== TRANSPORTS =====
|
|
3630
|
+
/**
|
|
3631
|
+
* Añade un transport para envío de logs
|
|
3632
|
+
*
|
|
3633
|
+
* @param target - Configuración del transport
|
|
3634
|
+
* @returns ID único del transport
|
|
3635
|
+
*
|
|
3636
|
+
* @example
|
|
3637
|
+
* // File transport
|
|
3638
|
+
* logger.addTransport({
|
|
3639
|
+
* target: 'file',
|
|
3640
|
+
* options: { destination: '/var/log/app.log' }
|
|
3641
|
+
* });
|
|
3642
|
+
*
|
|
3643
|
+
* @example
|
|
3644
|
+
* // HTTP transport con batching
|
|
3645
|
+
* logger.addTransport({
|
|
3646
|
+
* target: 'http',
|
|
3647
|
+
* options: {
|
|
3648
|
+
* url: 'https://logs.example.com',
|
|
3649
|
+
* batchSize: 100,
|
|
3650
|
+
* flushInterval: 5000
|
|
3651
|
+
* },
|
|
3652
|
+
* level: 'warn'
|
|
3653
|
+
* });
|
|
3654
|
+
*
|
|
3655
|
+
* @since 3.0.0
|
|
3656
|
+
*/
|
|
3657
|
+
addTransport(target) {
|
|
3658
|
+
if (!this.transportManager) {
|
|
3659
|
+
this.transportManager = new TransportManager();
|
|
3660
|
+
}
|
|
3661
|
+
return this.transportManager.add(target);
|
|
3662
|
+
}
|
|
3663
|
+
/**
|
|
3664
|
+
* Elimina un transport
|
|
3665
|
+
*
|
|
3666
|
+
* @param id - ID del transport a remover
|
|
3667
|
+
* @returns true si se eliminó
|
|
3668
|
+
*
|
|
3669
|
+
* @since 3.0.0
|
|
3670
|
+
*/
|
|
3671
|
+
removeTransport(id) {
|
|
3672
|
+
return this.transportManager?.remove(id) ?? false;
|
|
3673
|
+
}
|
|
3674
|
+
/**
|
|
3675
|
+
* Fuerza el flush de todos los transports
|
|
3676
|
+
*
|
|
3677
|
+
* @returns Promise que resuelve cuando todos los buffers están vaciados
|
|
3678
|
+
*
|
|
3679
|
+
* @since 3.0.0
|
|
3680
|
+
*/
|
|
3681
|
+
async flushTransports() {
|
|
3682
|
+
await this.transportManager?.flush();
|
|
3683
|
+
}
|
|
3684
|
+
/**
|
|
3685
|
+
* Cierra todos los transports
|
|
3686
|
+
*
|
|
3687
|
+
* @returns Promise que resuelve cuando todos están cerrados
|
|
3688
|
+
*
|
|
3689
|
+
* @since 3.0.0
|
|
3690
|
+
*/
|
|
3691
|
+
async closeTransports() {
|
|
3692
|
+
await this.transportManager?.close();
|
|
3693
|
+
}
|
|
3694
|
+
/**
|
|
3695
|
+
* Obtiene el TransportManager
|
|
3696
|
+
*
|
|
3697
|
+
* @returns TransportManager o undefined si no hay transports
|
|
3698
|
+
* @since 3.0.0
|
|
3699
|
+
*/
|
|
3700
|
+
getTransportManager() {
|
|
3701
|
+
return this.transportManager;
|
|
3702
|
+
}
|
|
2991
3703
|
// ===== CORE LOGGING METHODS =====
|
|
2992
3704
|
/**
|
|
2993
3705
|
* Verifica si un nivel de log debe mostrarse según la verbosidad actual
|
|
@@ -3019,8 +3731,26 @@ class Logger {
|
|
|
3019
3731
|
if (!this.shouldLog(level)) return;
|
|
3020
3732
|
const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
|
|
3021
3733
|
const prefix = this.getEffectivePrefix();
|
|
3022
|
-
const
|
|
3023
|
-
const
|
|
3734
|
+
const timestamp = formatTimestamp();
|
|
3735
|
+
const serializedArgs = args.map((arg) => this.serializerRegistry.serialize(arg));
|
|
3736
|
+
let message = serializedArgs.length > 0 ? String(serializedArgs[0]) : "";
|
|
3737
|
+
if (this.badgeList.length > 0 && this.displaySettings.showBadges) {
|
|
3738
|
+
const badgePrefix = this.badgeList.map((b) => `[${b}]`).join("");
|
|
3739
|
+
message = badgePrefix + " " + message;
|
|
3740
|
+
}
|
|
3741
|
+
const additionalArgs = serializedArgs.slice(1);
|
|
3742
|
+
let hookEntry = {
|
|
3743
|
+
level,
|
|
3744
|
+
message,
|
|
3745
|
+
args: serializedArgs,
|
|
3746
|
+
timestamp,
|
|
3747
|
+
prefix,
|
|
3748
|
+
stackInfo: stackInfo || void 0
|
|
3749
|
+
};
|
|
3750
|
+
this.hookManager.emit("beforeLog", hookEntry).then((processed) => {
|
|
3751
|
+
message = processed.message;
|
|
3752
|
+
}).catch(() => {
|
|
3753
|
+
});
|
|
3024
3754
|
const [format, ...styles2] = createStyledOutput(
|
|
3025
3755
|
level,
|
|
3026
3756
|
LEVEL_STYLES,
|
|
@@ -3042,30 +3772,59 @@ class Logger {
|
|
|
3042
3772
|
this.exportHandler.setGroupInfo(this.groupDepth);
|
|
3043
3773
|
}
|
|
3044
3774
|
const metadata = {
|
|
3045
|
-
timestamp
|
|
3775
|
+
timestamp,
|
|
3046
3776
|
level,
|
|
3047
3777
|
prefix,
|
|
3048
3778
|
stackInfo: stackInfo ? stackInfo : void 0
|
|
3049
3779
|
};
|
|
3050
3780
|
this.handlers.forEach((handler) => {
|
|
3051
3781
|
try {
|
|
3052
|
-
handler.handle(level, message,
|
|
3782
|
+
handler.handle(level, message, serializedArgs, metadata);
|
|
3053
3783
|
} catch (error2) {
|
|
3054
3784
|
console.error("Log handler failed:", error2);
|
|
3055
3785
|
}
|
|
3056
3786
|
});
|
|
3787
|
+
if (this.transportManager) {
|
|
3788
|
+
const levelValues = {
|
|
3789
|
+
debug: 0,
|
|
3790
|
+
info: 1,
|
|
3791
|
+
warn: 2,
|
|
3792
|
+
error: 3,
|
|
3793
|
+
critical: 4
|
|
3794
|
+
};
|
|
3795
|
+
const record = {
|
|
3796
|
+
level,
|
|
3797
|
+
levelValue: levelValues[level],
|
|
3798
|
+
time: Date.now(),
|
|
3799
|
+
msg: message,
|
|
3800
|
+
prefix,
|
|
3801
|
+
location: stackInfo ? {
|
|
3802
|
+
file: stackInfo.file,
|
|
3803
|
+
line: stackInfo.line,
|
|
3804
|
+
column: stackInfo.column,
|
|
3805
|
+
function: stackInfo.function
|
|
3806
|
+
} : void 0
|
|
3807
|
+
};
|
|
3808
|
+
this.transportManager.write(record).catch(() => {
|
|
3809
|
+
});
|
|
3810
|
+
}
|
|
3811
|
+
this.hookManager.emit("afterLog", hookEntry).catch(() => {
|
|
3812
|
+
});
|
|
3813
|
+
}
|
|
3814
|
+
logWithBindings(bindings, level, ...args) {
|
|
3815
|
+
if (!this.shouldLog(level)) return;
|
|
3816
|
+
let prefix = "";
|
|
3817
|
+
if (bindings.badges?.length) {
|
|
3818
|
+
prefix += bindings.badges.map((b) => `[${b}]`).join("");
|
|
3819
|
+
}
|
|
3820
|
+
if (bindings.scope) {
|
|
3821
|
+
prefix += `[${bindings.scope}] `;
|
|
3822
|
+
}
|
|
3823
|
+
if (prefix && args.length > 0) {
|
|
3824
|
+
args[0] = prefix + String(args[0]);
|
|
3825
|
+
}
|
|
3826
|
+
this.log(level, ...args);
|
|
3057
3827
|
}
|
|
3058
|
-
/**
|
|
3059
|
-
* Registra información de debug (prioridad más baja)
|
|
3060
|
-
*
|
|
3061
|
-
* @param {...any} args - Mensajes y datos a loggear
|
|
3062
|
-
*
|
|
3063
|
-
* @example
|
|
3064
|
-
* logger.debug('Variable estado:', { usuario: 'Juan', activo: true });
|
|
3065
|
-
* logger.debug('Iniciando proceso de validación');
|
|
3066
|
-
*
|
|
3067
|
-
* @since 0.3.0
|
|
3068
|
-
*/
|
|
3069
3828
|
debug(...args) {
|
|
3070
3829
|
this.log("debug", ...args);
|
|
3071
3830
|
}
|
|
@@ -3493,11 +4252,18 @@ function getDefaultLogger() {
|
|
|
3493
4252
|
}
|
|
3494
4253
|
getDefaultLogger();
|
|
3495
4254
|
export {
|
|
4255
|
+
APILogger as A,
|
|
3496
4256
|
BANNER_VARIANTS as B,
|
|
4257
|
+
ComponentLogger as C,
|
|
3497
4258
|
ExportLogHandler as E,
|
|
4259
|
+
HookManager as H,
|
|
3498
4260
|
Logger as L,
|
|
4261
|
+
SerializerRegistry as S,
|
|
3499
4262
|
THEME_PRESETS as T,
|
|
3500
4263
|
THEME_BANNERS as a,
|
|
3501
|
-
|
|
4264
|
+
TransportManager as b,
|
|
4265
|
+
ScopedLogger as c,
|
|
4266
|
+
ContextLogger as d,
|
|
4267
|
+
displayInitBanner as e
|
|
3502
4268
|
};
|
|
3503
|
-
//# sourceMappingURL=Logger-
|
|
4269
|
+
//# sourceMappingURL=Logger-C126NTrD.js.map
|