@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
package/src/Logger.ts
CHANGED
|
@@ -17,9 +17,21 @@ import type {
|
|
|
17
17
|
TimerEntry,
|
|
18
18
|
ILogHandler,
|
|
19
19
|
LogMetadata,
|
|
20
|
-
StyleOptions
|
|
20
|
+
StyleOptions,
|
|
21
|
+
Bindings,
|
|
22
|
+
SerializerFn,
|
|
23
|
+
HookEvent,
|
|
24
|
+
HookCallback,
|
|
25
|
+
MiddlewareFn,
|
|
26
|
+
TransportTarget,
|
|
27
|
+
TransportRecord
|
|
21
28
|
} from './types/index.js';
|
|
22
29
|
|
|
30
|
+
// Enterprise features
|
|
31
|
+
import { SerializerRegistry } from './serializers/index.js';
|
|
32
|
+
import { HookManager } from './hooks/index.js';
|
|
33
|
+
import { TransportManager } from './transports/index.js';
|
|
34
|
+
|
|
23
35
|
// Utility imports
|
|
24
36
|
import { parseStackTrace } from './utils/stackTrace.js';
|
|
25
37
|
import { formatTimestamp } from './utils/timestamps.js';
|
|
@@ -39,6 +51,9 @@ import {
|
|
|
39
51
|
import { getSmartPreset, getAvailablePresets, hasPreset } from './styling/SmartPresets.js';
|
|
40
52
|
import { createLogStyleBuilder } from './styling/LogStyleBuilder.js';
|
|
41
53
|
|
|
54
|
+
// Scoped loggers (static import for performance)
|
|
55
|
+
import { ScopedLogger, APILogger, ComponentLogger } from './ScopedLogger.js';
|
|
56
|
+
|
|
42
57
|
// Handler imports
|
|
43
58
|
import { ExportLogHandler } from './handlers/index.js';
|
|
44
59
|
|
|
@@ -89,12 +104,17 @@ export class Logger {
|
|
|
89
104
|
private exportHandler?: ExportLogHandler;
|
|
90
105
|
private cliProcessor?: CommandProcessor;
|
|
91
106
|
private themeChangeListener?: (() => void) | null;
|
|
107
|
+
private badgeList: string[] = [];
|
|
92
108
|
private displaySettings = {
|
|
93
109
|
showTimestamp: true,
|
|
94
110
|
showLocation: true,
|
|
95
111
|
showBadges: true
|
|
96
112
|
};
|
|
97
113
|
|
|
114
|
+
private serializerRegistry: SerializerRegistry;
|
|
115
|
+
private hookManager: HookManager;
|
|
116
|
+
private transportManager?: TransportManager;
|
|
117
|
+
|
|
98
118
|
/**
|
|
99
119
|
* Crea una nueva instancia del Logger
|
|
100
120
|
*
|
|
@@ -115,6 +135,10 @@ export class Logger {
|
|
|
115
135
|
...config,
|
|
116
136
|
};
|
|
117
137
|
|
|
138
|
+
// Initialize enterprise features
|
|
139
|
+
this.serializerRegistry = new SerializerRegistry();
|
|
140
|
+
this.hookManager = new HookManager();
|
|
141
|
+
|
|
118
142
|
// Initialize export handler if buffer size is specified
|
|
119
143
|
if (this.config.bufferSize) {
|
|
120
144
|
this.exportHandler = new ExportLogHandler(this.config.bufferSize);
|
|
@@ -123,7 +147,7 @@ export class Logger {
|
|
|
123
147
|
|
|
124
148
|
// Initialize CLI processor
|
|
125
149
|
this.cliProcessor = createDefaultCLI();
|
|
126
|
-
|
|
150
|
+
|
|
127
151
|
// Set up theme change listener if auto-detection is enabled
|
|
128
152
|
if (this.config.autoDetectTheme) {
|
|
129
153
|
this.setupAutoThemeDetection();
|
|
@@ -324,36 +348,10 @@ export class Logger {
|
|
|
324
348
|
this.themeChangeListener();
|
|
325
349
|
this.themeChangeListener = null;
|
|
326
350
|
}
|
|
351
|
+
// Close transports
|
|
352
|
+
this.transportManager?.close().catch(() => {});
|
|
327
353
|
}
|
|
328
354
|
|
|
329
|
-
/**
|
|
330
|
-
* Factory method para crear loggers con scope evitando dependencias circulares
|
|
331
|
-
* @private
|
|
332
|
-
* @param {string} type - Tipo de logger ('scope' | 'api' | 'component')
|
|
333
|
-
* @param {string} name - Nombre del scope
|
|
334
|
-
* @returns {Promise<any>} Logger con scope
|
|
335
|
-
*/
|
|
336
|
-
private async createScopedLogger(type: string, name: string): Promise<any> {
|
|
337
|
-
try {
|
|
338
|
-
const { ScopedLogger, APILogger, ComponentLogger } = await import('./ScopedLogger.js');
|
|
339
|
-
|
|
340
|
-
switch (type) {
|
|
341
|
-
case 'component':
|
|
342
|
-
return new ComponentLogger(this, name);
|
|
343
|
-
case 'api':
|
|
344
|
-
return new APILogger(this, name);
|
|
345
|
-
case 'scope':
|
|
346
|
-
default:
|
|
347
|
-
return new ScopedLogger(this, name);
|
|
348
|
-
}
|
|
349
|
-
} catch (error) {
|
|
350
|
-
// Fallback: crear logger básico con prefijo
|
|
351
|
-
this.error('Failed to load ScopedLogger, using basic logger with prefix:', error);
|
|
352
|
-
const basicLogger = new Logger(this.getConfig());
|
|
353
|
-
basicLogger.setGlobalPrefix(`${this.config.globalPrefix || ''}:${name}`);
|
|
354
|
-
return basicLogger;
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
355
|
|
|
358
356
|
// ===== SIMPLIFIED API =====
|
|
359
357
|
|
|
@@ -486,12 +484,12 @@ export class Logger {
|
|
|
486
484
|
|
|
487
485
|
/**
|
|
488
486
|
* Muestra los badges en los logs
|
|
489
|
-
*
|
|
487
|
+
*
|
|
490
488
|
* @example
|
|
491
489
|
* logger.showBadges();
|
|
492
490
|
* const api = logger.api('GraphQL');
|
|
493
491
|
* api.info('Con badges'); // [API] [GraphQL] Con badges
|
|
494
|
-
*
|
|
492
|
+
*
|
|
495
493
|
* @since 0.3.0
|
|
496
494
|
*/
|
|
497
495
|
showBadges(): void {
|
|
@@ -499,71 +497,68 @@ export class Logger {
|
|
|
499
497
|
this.success('Badges shown');
|
|
500
498
|
}
|
|
501
499
|
|
|
502
|
-
// ===== SCOPED LOGGERS =====
|
|
503
|
-
|
|
504
500
|
/**
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
* @param {string}
|
|
508
|
-
* @returns {
|
|
509
|
-
*
|
|
501
|
+
* Establece múltiples badges para los logs
|
|
502
|
+
*
|
|
503
|
+
* @param {string[]} badges - Array de badges a mostrar
|
|
504
|
+
* @returns {this} Logger instance para encadenamiento
|
|
505
|
+
*
|
|
510
506
|
* @example
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
*
|
|
515
|
-
* authLogger.success('Usuario autenticado');
|
|
516
|
-
* // [COMPONENT] [Autenticación] ✓ Usuario autenticado
|
|
517
|
-
*
|
|
518
|
-
* @since 0.3.0
|
|
507
|
+
* logger.badges(['v3', 'stable']).info('Release publicado');
|
|
508
|
+
* logger.badges(['API', 'v2']).warn('Endpoint deprecado');
|
|
509
|
+
*
|
|
510
|
+
* @since 3.0.0
|
|
519
511
|
*/
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
return this
|
|
512
|
+
badges(badges: string[]): this {
|
|
513
|
+
this.badgeList = [...badges];
|
|
514
|
+
return this;
|
|
523
515
|
}
|
|
524
516
|
|
|
525
517
|
/**
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
* @param {string}
|
|
529
|
-
* @returns {
|
|
530
|
-
*
|
|
518
|
+
* Añade un badge individual a la lista
|
|
519
|
+
*
|
|
520
|
+
* @param {string} badge - Badge a añadir
|
|
521
|
+
* @returns {this} Logger instance para encadenamiento
|
|
522
|
+
*
|
|
531
523
|
* @example
|
|
532
|
-
*
|
|
533
|
-
*
|
|
534
|
-
*
|
|
535
|
-
*
|
|
536
|
-
* // Con badges adicionales
|
|
537
|
-
* api.badges(['v2', 'cached']).info('Respuesta desde caché');
|
|
538
|
-
* // [API] [v2] [cached] [REST] Respuesta desde caché
|
|
539
|
-
*
|
|
540
|
-
* @since 0.3.0
|
|
524
|
+
* logger.badge('DEBUG').badge('AUTH').info('Token validado');
|
|
525
|
+
*
|
|
526
|
+
* @since 3.0.0
|
|
541
527
|
*/
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
528
|
+
badge(badge: string): this {
|
|
529
|
+
if (!this.badgeList.includes(badge)) {
|
|
530
|
+
this.badgeList.push(badge);
|
|
531
|
+
}
|
|
532
|
+
return this;
|
|
545
533
|
}
|
|
546
534
|
|
|
547
535
|
/**
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
* @
|
|
551
|
-
*
|
|
552
|
-
*
|
|
536
|
+
* Limpia todos los badges activos
|
|
537
|
+
*
|
|
538
|
+
* @returns {this} Logger instance para encadenamiento
|
|
539
|
+
*
|
|
553
540
|
* @example
|
|
554
|
-
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
*
|
|
558
|
-
* // Con badges personalizados
|
|
559
|
-
* dbLogger.badge('SLOW').warn('Query tardó 5s');
|
|
560
|
-
* // [SLOW] [Database] Query tardó 5s
|
|
561
|
-
*
|
|
562
|
-
* @since 0.3.0
|
|
541
|
+
* logger.clearBadges().info('Sin badges');
|
|
542
|
+
*
|
|
543
|
+
* @since 3.0.0
|
|
563
544
|
*/
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
return this
|
|
545
|
+
clearBadges(): this {
|
|
546
|
+
this.badgeList = [];
|
|
547
|
+
return this;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// ===== SCOPED LOGGERS =====
|
|
551
|
+
|
|
552
|
+
component(name: string): ComponentLogger {
|
|
553
|
+
return new ComponentLogger(this, name);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
api(name: string): APILogger {
|
|
557
|
+
return new APILogger(this, name);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
scope(name: string): ScopedLogger {
|
|
561
|
+
return new ScopedLogger(this, name);
|
|
567
562
|
}
|
|
568
563
|
|
|
569
564
|
// ===== SIMPLE CUSTOMIZATION =====
|
|
@@ -654,7 +649,7 @@ export class Logger {
|
|
|
654
649
|
|
|
655
650
|
/**
|
|
656
651
|
* Obtiene el handler de exportación si está disponible
|
|
657
|
-
*
|
|
652
|
+
*
|
|
658
653
|
* @returns {ExportLogHandler | undefined} Handler de exportación o undefined
|
|
659
654
|
* @since 0.3.0
|
|
660
655
|
*/
|
|
@@ -662,6 +657,212 @@ export class Logger {
|
|
|
662
657
|
return this.exportHandler;
|
|
663
658
|
}
|
|
664
659
|
|
|
660
|
+
// ===== SERIALIZERS =====
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Añade un serializador personalizado para un tipo específico
|
|
664
|
+
*
|
|
665
|
+
* @param type - Constructor del tipo a serializar
|
|
666
|
+
* @param serializer - Función de serialización
|
|
667
|
+
* @param priority - Prioridad (mayor = primero)
|
|
668
|
+
*
|
|
669
|
+
* @example
|
|
670
|
+
* logger.addSerializer(Error, (err) => ({
|
|
671
|
+
* name: err.name,
|
|
672
|
+
* message: err.message,
|
|
673
|
+
* stack: err.stack?.split('\n').slice(0, 5)
|
|
674
|
+
* }));
|
|
675
|
+
*
|
|
676
|
+
* @since 3.0.0
|
|
677
|
+
*/
|
|
678
|
+
addSerializer<T>(
|
|
679
|
+
type: new (...args: any[]) => T,
|
|
680
|
+
serializer: SerializerFn<T>,
|
|
681
|
+
priority?: number
|
|
682
|
+
): void {
|
|
683
|
+
this.serializerRegistry.add(type, serializer, priority);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Elimina un serializador registrado
|
|
688
|
+
*
|
|
689
|
+
* @param type - Constructor del tipo a remover
|
|
690
|
+
* @returns true si se eliminó
|
|
691
|
+
*
|
|
692
|
+
* @since 3.0.0
|
|
693
|
+
*/
|
|
694
|
+
removeSerializer<T>(type: new (...args: any[]) => T): boolean {
|
|
695
|
+
return this.serializerRegistry.remove(type);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Obtiene el registry de serializadores
|
|
700
|
+
*
|
|
701
|
+
* @returns SerializerRegistry
|
|
702
|
+
* @since 3.0.0
|
|
703
|
+
*/
|
|
704
|
+
getSerializerRegistry(): SerializerRegistry {
|
|
705
|
+
return this.serializerRegistry;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// ===== HOOKS & MIDDLEWARE =====
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* Registra un hook para un evento
|
|
712
|
+
*
|
|
713
|
+
* @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'
|
|
714
|
+
* @param callback - Función a ejecutar
|
|
715
|
+
* @param priority - Prioridad (mayor = primero)
|
|
716
|
+
* @returns Función para desregistrar
|
|
717
|
+
*
|
|
718
|
+
* @example
|
|
719
|
+
* const unsubscribe = logger.on('beforeLog', (entry) => {
|
|
720
|
+
* entry.correlationId = getCorrelationId();
|
|
721
|
+
* return entry;
|
|
722
|
+
* });
|
|
723
|
+
*
|
|
724
|
+
* @since 3.0.0
|
|
725
|
+
*/
|
|
726
|
+
on(event: HookEvent, callback: HookCallback, priority?: number): () => void {
|
|
727
|
+
return this.hookManager.on(event, callback, priority);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* Registra un hook que se ejecuta solo una vez
|
|
732
|
+
*
|
|
733
|
+
* @param event - Evento: 'beforeLog' | 'afterLog' | 'onError'
|
|
734
|
+
* @param callback - Función a ejecutar
|
|
735
|
+
* @param priority - Prioridad (mayor = primero)
|
|
736
|
+
* @returns Función para desregistrar
|
|
737
|
+
*
|
|
738
|
+
* @since 3.0.0
|
|
739
|
+
*/
|
|
740
|
+
once(event: HookEvent, callback: HookCallback, priority?: number): () => void {
|
|
741
|
+
return this.hookManager.once(event, callback, priority);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Elimina un hook registrado
|
|
746
|
+
*
|
|
747
|
+
* @param event - Evento del hook
|
|
748
|
+
* @param callback - Callback a remover
|
|
749
|
+
* @returns true si se eliminó
|
|
750
|
+
*
|
|
751
|
+
* @since 3.0.0
|
|
752
|
+
*/
|
|
753
|
+
off(event: HookEvent, callback: HookCallback): boolean {
|
|
754
|
+
return this.hookManager.off(event, callback);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Añade un middleware al pipeline
|
|
759
|
+
*
|
|
760
|
+
* @param middleware - Función middleware
|
|
761
|
+
* @param priority - Prioridad (mayor = primero)
|
|
762
|
+
* @returns Función para desregistrar
|
|
763
|
+
*
|
|
764
|
+
* @example
|
|
765
|
+
* logger.use((entry, next) => {
|
|
766
|
+
* entry.requestId = asyncLocalStorage.getStore()?.requestId;
|
|
767
|
+
* next();
|
|
768
|
+
* });
|
|
769
|
+
*
|
|
770
|
+
* @since 3.0.0
|
|
771
|
+
*/
|
|
772
|
+
use(middleware: MiddlewareFn, priority?: number): () => void {
|
|
773
|
+
return this.hookManager.use(middleware, priority);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Obtiene el HookManager
|
|
778
|
+
*
|
|
779
|
+
* @returns HookManager
|
|
780
|
+
* @since 3.0.0
|
|
781
|
+
*/
|
|
782
|
+
getHookManager(): HookManager {
|
|
783
|
+
return this.hookManager;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// ===== TRANSPORTS =====
|
|
787
|
+
|
|
788
|
+
/**
|
|
789
|
+
* Añade un transport para envío de logs
|
|
790
|
+
*
|
|
791
|
+
* @param target - Configuración del transport
|
|
792
|
+
* @returns ID único del transport
|
|
793
|
+
*
|
|
794
|
+
* @example
|
|
795
|
+
* // File transport
|
|
796
|
+
* logger.addTransport({
|
|
797
|
+
* target: 'file',
|
|
798
|
+
* options: { destination: '/var/log/app.log' }
|
|
799
|
+
* });
|
|
800
|
+
*
|
|
801
|
+
* @example
|
|
802
|
+
* // HTTP transport con batching
|
|
803
|
+
* logger.addTransport({
|
|
804
|
+
* target: 'http',
|
|
805
|
+
* options: {
|
|
806
|
+
* url: 'https://logs.example.com',
|
|
807
|
+
* batchSize: 100,
|
|
808
|
+
* flushInterval: 5000
|
|
809
|
+
* },
|
|
810
|
+
* level: 'warn'
|
|
811
|
+
* });
|
|
812
|
+
*
|
|
813
|
+
* @since 3.0.0
|
|
814
|
+
*/
|
|
815
|
+
addTransport(target: TransportTarget): string {
|
|
816
|
+
if (!this.transportManager) {
|
|
817
|
+
this.transportManager = new TransportManager();
|
|
818
|
+
}
|
|
819
|
+
return this.transportManager.add(target);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Elimina un transport
|
|
824
|
+
*
|
|
825
|
+
* @param id - ID del transport a remover
|
|
826
|
+
* @returns true si se eliminó
|
|
827
|
+
*
|
|
828
|
+
* @since 3.0.0
|
|
829
|
+
*/
|
|
830
|
+
removeTransport(id: string): boolean {
|
|
831
|
+
return this.transportManager?.remove(id) ?? false;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
/**
|
|
835
|
+
* Fuerza el flush de todos los transports
|
|
836
|
+
*
|
|
837
|
+
* @returns Promise que resuelve cuando todos los buffers están vaciados
|
|
838
|
+
*
|
|
839
|
+
* @since 3.0.0
|
|
840
|
+
*/
|
|
841
|
+
async flushTransports(): Promise<void> {
|
|
842
|
+
await this.transportManager?.flush();
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
/**
|
|
846
|
+
* Cierra todos los transports
|
|
847
|
+
*
|
|
848
|
+
* @returns Promise que resuelve cuando todos están cerrados
|
|
849
|
+
*
|
|
850
|
+
* @since 3.0.0
|
|
851
|
+
*/
|
|
852
|
+
async closeTransports(): Promise<void> {
|
|
853
|
+
await this.transportManager?.close();
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Obtiene el TransportManager
|
|
858
|
+
*
|
|
859
|
+
* @returns TransportManager o undefined si no hay transports
|
|
860
|
+
* @since 3.0.0
|
|
861
|
+
*/
|
|
862
|
+
getTransportManager(): TransportManager | undefined {
|
|
863
|
+
return this.transportManager;
|
|
864
|
+
}
|
|
865
|
+
|
|
665
866
|
// ===== CORE LOGGING METHODS =====
|
|
666
867
|
|
|
667
868
|
/**
|
|
@@ -697,8 +898,33 @@ export class Logger {
|
|
|
697
898
|
|
|
698
899
|
const stackInfo = this.config.enableStackTrace ? parseStackTrace() : null;
|
|
699
900
|
const prefix = this.getEffectivePrefix();
|
|
700
|
-
const
|
|
701
|
-
|
|
901
|
+
const timestamp = formatTimestamp();
|
|
902
|
+
|
|
903
|
+
// Serialize args using registry
|
|
904
|
+
const serializedArgs = args.map(arg => this.serializerRegistry.serialize(arg));
|
|
905
|
+
|
|
906
|
+
// Prepend badges to message if any
|
|
907
|
+
let message = serializedArgs.length > 0 ? String(serializedArgs[0]) : '';
|
|
908
|
+
if (this.badgeList.length > 0 && this.displaySettings.showBadges) {
|
|
909
|
+
const badgePrefix = this.badgeList.map(b => `[${b}]`).join('');
|
|
910
|
+
message = badgePrefix + ' ' + message;
|
|
911
|
+
}
|
|
912
|
+
const additionalArgs = serializedArgs.slice(1);
|
|
913
|
+
|
|
914
|
+
// Process beforeLog hooks (sync for performance)
|
|
915
|
+
let hookEntry = {
|
|
916
|
+
level,
|
|
917
|
+
message,
|
|
918
|
+
args: serializedArgs,
|
|
919
|
+
timestamp,
|
|
920
|
+
prefix,
|
|
921
|
+
stackInfo: stackInfo || undefined
|
|
922
|
+
};
|
|
923
|
+
|
|
924
|
+
// Emit beforeLog event (fire-and-forget for sync logging)
|
|
925
|
+
this.hookManager.emit('beforeLog', hookEntry).then(processed => {
|
|
926
|
+
message = processed.message;
|
|
927
|
+
}).catch(() => {});
|
|
702
928
|
|
|
703
929
|
// Create styled output with theme detection and display settings
|
|
704
930
|
const [format, ...styles] = createStyledOutput(
|
|
@@ -730,7 +956,7 @@ export class Logger {
|
|
|
730
956
|
|
|
731
957
|
// Call custom handlers
|
|
732
958
|
const metadata: LogMetadata = {
|
|
733
|
-
timestamp
|
|
959
|
+
timestamp,
|
|
734
960
|
level,
|
|
735
961
|
prefix,
|
|
736
962
|
stackInfo: stackInfo ? stackInfo : undefined,
|
|
@@ -738,24 +964,55 @@ export class Logger {
|
|
|
738
964
|
|
|
739
965
|
this.handlers.forEach(handler => {
|
|
740
966
|
try {
|
|
741
|
-
handler.handle(level, message,
|
|
967
|
+
handler.handle(level, message, serializedArgs, metadata);
|
|
742
968
|
} catch (error) {
|
|
743
969
|
console.error('Log handler failed:', error);
|
|
744
970
|
}
|
|
745
971
|
});
|
|
972
|
+
|
|
973
|
+
// Write to transports (async, fire-and-forget)
|
|
974
|
+
if (this.transportManager) {
|
|
975
|
+
const levelValues: Record<LogLevel, number> = {
|
|
976
|
+
debug: 0, info: 1, warn: 2, error: 3, critical: 4
|
|
977
|
+
};
|
|
978
|
+
const record: TransportRecord = {
|
|
979
|
+
level,
|
|
980
|
+
levelValue: levelValues[level],
|
|
981
|
+
time: Date.now(),
|
|
982
|
+
msg: message,
|
|
983
|
+
prefix,
|
|
984
|
+
location: stackInfo ? {
|
|
985
|
+
file: stackInfo.file,
|
|
986
|
+
line: stackInfo.line,
|
|
987
|
+
column: stackInfo.column,
|
|
988
|
+
function: stackInfo.function
|
|
989
|
+
} : undefined
|
|
990
|
+
};
|
|
991
|
+
this.transportManager.write(record).catch(() => {});
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
// Emit afterLog event (fire-and-forget)
|
|
995
|
+
this.hookManager.emit('afterLog', hookEntry).catch(() => {});
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
logWithBindings(bindings: Bindings, level: LogLevel, ...args: any[]): void {
|
|
999
|
+
if (!this.shouldLog(level)) return;
|
|
1000
|
+
|
|
1001
|
+
let prefix = '';
|
|
1002
|
+
if (bindings.badges?.length) {
|
|
1003
|
+
prefix += bindings.badges.map(b => `[${b}]`).join('');
|
|
1004
|
+
}
|
|
1005
|
+
if (bindings.scope) {
|
|
1006
|
+
prefix += `[${bindings.scope}] `;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
if (prefix && args.length > 0) {
|
|
1010
|
+
args[0] = prefix + String(args[0]);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
this.log(level, ...args);
|
|
746
1014
|
}
|
|
747
1015
|
|
|
748
|
-
/**
|
|
749
|
-
* Registra información de debug (prioridad más baja)
|
|
750
|
-
*
|
|
751
|
-
* @param {...any} args - Mensajes y datos a loggear
|
|
752
|
-
*
|
|
753
|
-
* @example
|
|
754
|
-
* logger.debug('Variable estado:', { usuario: 'Juan', activo: true });
|
|
755
|
-
* logger.debug('Iniciando proceso de validación');
|
|
756
|
-
*
|
|
757
|
-
* @since 0.3.0
|
|
758
|
-
*/
|
|
759
1016
|
debug(...args: any[]): void {
|
|
760
1017
|
this.log('debug', ...args);
|
|
761
1018
|
}
|
|
@@ -1309,14 +1566,46 @@ export const hideLocation = () => getDefaultLogger().hideLocation();
|
|
|
1309
1566
|
export const showLocation = () => getDefaultLogger().showLocation();
|
|
1310
1567
|
export const hideBadges = () => getDefaultLogger().hideBadges();
|
|
1311
1568
|
export const showBadges = () => getDefaultLogger().showBadges();
|
|
1569
|
+
export const badges = (badgeList: string[]) => getDefaultLogger().badges(badgeList);
|
|
1570
|
+
export const badge = (badgeName: string) => getDefaultLogger().badge(badgeName);
|
|
1571
|
+
export const clearBadges = () => getDefaultLogger().clearBadges();
|
|
1312
1572
|
export const component = (name: string) => getDefaultLogger().component(name);
|
|
1313
1573
|
export const api = (name: string) => getDefaultLogger().api(name);
|
|
1314
1574
|
export const scope = (name: string) => getDefaultLogger().scope(name);
|
|
1315
1575
|
export const customize = (overrides: any) => getDefaultLogger().customize(overrides);
|
|
1316
1576
|
export const styles = () => getDefaultLogger().styles();
|
|
1317
1577
|
|
|
1578
|
+
// Enterprise features exports
|
|
1579
|
+
export const addSerializer = <T>(
|
|
1580
|
+
type: new (...args: any[]) => T,
|
|
1581
|
+
serializer: SerializerFn<T>,
|
|
1582
|
+
priority?: number
|
|
1583
|
+
) => getDefaultLogger().addSerializer(type, serializer, priority);
|
|
1584
|
+
export const removeSerializer = <T>(type: new (...args: any[]) => T) =>
|
|
1585
|
+
getDefaultLogger().removeSerializer(type);
|
|
1586
|
+
export const on = (event: HookEvent, callback: HookCallback, priority?: number) =>
|
|
1587
|
+
getDefaultLogger().on(event, callback, priority);
|
|
1588
|
+
export const once = (event: HookEvent, callback: HookCallback, priority?: number) =>
|
|
1589
|
+
getDefaultLogger().once(event, callback, priority);
|
|
1590
|
+
export const off = (event: HookEvent, callback: HookCallback) =>
|
|
1591
|
+
getDefaultLogger().off(event, callback);
|
|
1592
|
+
export const use = (middleware: MiddlewareFn, priority?: number) =>
|
|
1593
|
+
getDefaultLogger().use(middleware, priority);
|
|
1594
|
+
export const addTransport = (target: TransportTarget) =>
|
|
1595
|
+
getDefaultLogger().addTransport(target);
|
|
1596
|
+
export const removeTransport = (id: string) =>
|
|
1597
|
+
getDefaultLogger().removeTransport(id);
|
|
1598
|
+
export const flushTransports = () =>
|
|
1599
|
+
getDefaultLogger().flushTransports();
|
|
1600
|
+
export const closeTransports = () =>
|
|
1601
|
+
getDefaultLogger().closeTransports();
|
|
1602
|
+
|
|
1318
1603
|
// Re-export handlers and utilities for backward compatibility
|
|
1319
1604
|
export { FileLogHandler, RemoteLogHandler, AnalyticsLogHandler, ExportLogHandler } from './handlers/index.js';
|
|
1320
1605
|
export { StyleBuilder, StylePresets as Styles } from './styling/index.js';
|
|
1321
|
-
|
|
1322
|
-
// export
|
|
1606
|
+
|
|
1607
|
+
// Re-export enterprise features
|
|
1608
|
+
export { SerializerRegistry } from './serializers/index.js';
|
|
1609
|
+
export { HookManager } from './hooks/index.js';
|
|
1610
|
+
export { TransportManager, ConsoleTransport, FileTransport, HttpTransport } from './transports/index.js';
|
|
1611
|
+
export { StyleCache, getStyleCache } from './styling/StyleCache.js';
|