@ncoderz/log-m8 1.0.1

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.
@@ -0,0 +1,1276 @@
1
+ /**
2
+ * Contextual metadata automatically included with all log events from a logger.
3
+ *
4
+ * LogContext provides a way to associate persistent metadata with logger instances
5
+ * that gets automatically included with every log event. This is useful for
6
+ * tracking request IDs, user sessions, service names, or any other contextual
7
+ * information that should be consistent across related log entries.
8
+ *
9
+ * Context is set via logger.setContext() and can contain both predefined
10
+ * properties and arbitrary key-value pairs. Formatters can access context
11
+ * properties using dot-path notation (e.g., {context.requestId}).
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const logger = Logging.getLogger('api.auth');
16
+ *
17
+ * // Set context that applies to all subsequent log events
18
+ * logger.setContext({
19
+ * requestId: 'req-123',
20
+ * userId: 'user-456',
21
+ * sessionId: 'sess-789',
22
+ * service: 'authentication'
23
+ * });
24
+ *
25
+ * // All logs from this logger now include the context
26
+ * logger.info('User authentication started');
27
+ * logger.debug('Validating credentials');
28
+ * logger.info('Authentication successful');
29
+ * ```
30
+ */
31
+ interface LogContext {
32
+ /**
33
+ * Arbitrary context properties using string keys.
34
+ * Supports any serializable values for maximum flexibility.
35
+ */
36
+ [key: string]: unknown;
37
+ /**
38
+ * User identifier for associating log events with specific users.
39
+ * Commonly used for security auditing and user behavior analysis.
40
+ */
41
+ userId?: string;
42
+ /**
43
+ * Request identifier for tracing the complete lifecycle of a request.
44
+ * Essential for distributed tracing and debugging request flows.
45
+ */
46
+ requestId?: string;
47
+ /**
48
+ * Correlation identifier for linking related events across service boundaries.
49
+ * Used in microservice architectures to track operations across multiple services.
50
+ */
51
+ correlationId?: string;
52
+ }
53
+
54
+ /**
55
+ * Enumeration of supported log severity levels in ascending order of verbosity.
56
+ *
57
+ * The logging system uses this hierarchy to determine which events to emit:
58
+ * - 'off': Disables all logging
59
+ * - 'fatal': Critical system failures requiring immediate intervention
60
+ * - 'error': Failures preventing normal operation
61
+ * - 'warn': Potentially problematic situations
62
+ * - 'info': General informational messages about normal operation
63
+ * - 'debug': Detailed diagnostic information for development
64
+ * - 'track': Analytics and user behavior tracking events
65
+ * - 'trace': Most detailed execution information for fine-grained debugging
66
+ *
67
+ * Events are emitted when their level index is <= logger's level index.
68
+ * The 'track' level is positioned between 'debug' and 'trace' to allow
69
+ * analytics collection without the verbosity of full trace logging.
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * // Logger set to 'info' will emit: fatal, error, warn, info
74
+ * logger.setLevel('info');
75
+ * logger.debug('Not emitted'); // debug > info in hierarchy
76
+ * logger.info('Emitted'); // info <= info in hierarchy
77
+ * ```
78
+ */
79
+ declare const LogLevel: {
80
+ readonly off: "off";
81
+ readonly fatal: "fatal";
82
+ readonly error: "error";
83
+ readonly warn: "warn";
84
+ readonly info: "info";
85
+ readonly debug: "debug";
86
+ readonly track: "track";
87
+ readonly trace: "trace";
88
+ };
89
+ /**
90
+ * Type representing a LogLevel enum value.
91
+ */
92
+ type LogLevelType = (typeof LogLevel)[keyof typeof LogLevel];
93
+
94
+ /**
95
+ * Interface for a hierarchical logger instance providing level-based logging methods.
96
+ *
97
+ * Logger instances are created via LogM8.getLogger() and provide methods for emitting
98
+ * log events at different severity levels. Each logger maintains its own context and
99
+ * can create child loggers using dot-separated naming conventions.
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * const logger = Logging.getLogger('app.database');
104
+ * logger.setLevel('debug');
105
+ * logger.info('Connection established', { host: 'localhost' });
106
+ *
107
+ * // Create child logger
108
+ * const queryLogger = logger.getLogger('queries');
109
+ * queryLogger.debug('SELECT * FROM users'); // Name becomes 'app.database.queries'
110
+ *
111
+ * // Check if logging is enabled before expensive operations
112
+ * if (logger.isEnabled && logger.isDebug) {
113
+ * logger.debug('Expensive debug data', computeExpensiveDebugInfo());
114
+ * }
115
+ * ```
116
+ */
117
+ interface Log {
118
+ /**
119
+ * Logs a message at fatal severity level.
120
+ *
121
+ * Fatal events indicate critical system failures that typically require
122
+ * immediate intervention and may result in application termination.
123
+ *
124
+ * @param message - Primary message or serializable object to log
125
+ * @param data - Additional context data to include with the log event
126
+ */
127
+ fatal(message: string | unknown, ...data: unknown[]): void;
128
+ /**
129
+ * Logs a message at error severity level.
130
+ *
131
+ * Error events indicate failures that prevent normal operation but
132
+ * don't necessarily require application termination.
133
+ *
134
+ * @param message - Primary message or serializable object to log
135
+ * @param data - Additional context data to include with the log event
136
+ */
137
+ error(message: string | unknown, ...data: unknown[]): void;
138
+ /**
139
+ * Logs a message at warning severity level.
140
+ *
141
+ * Warning events indicate potentially problematic situations that
142
+ * don't prevent operation but may require attention.
143
+ *
144
+ * @param message - Primary message or serializable object to log
145
+ * @param data - Additional context data to include with the log event
146
+ */
147
+ warn(message: string | unknown, ...data: unknown[]): void;
148
+ /**
149
+ * Logs a message at info severity level.
150
+ *
151
+ * Info events provide general informational messages about normal
152
+ * application operation and significant business events.
153
+ *
154
+ * @param message - Primary message or serializable object to log
155
+ * @param data - Additional context data to include with the log event
156
+ */
157
+ info(message: string | unknown, ...data: unknown[]): void;
158
+ /**
159
+ * Logs a message at debug severity level.
160
+ *
161
+ * Debug events provide detailed diagnostic information useful during
162
+ * development and troubleshooting.
163
+ *
164
+ * @param message - Primary message or serializable object to log
165
+ * @param data - Additional context data to include with the log event
166
+ */
167
+ debug(message: string | unknown, ...data: unknown[]): void;
168
+ /**
169
+ * Logs a message at track severity level.
170
+ *
171
+ * Track events are specifically designed for analytics and user behavior
172
+ * tracking, separate from operational logging concerns.
173
+ *
174
+ * @param message - Primary message or serializable object to log
175
+ * @param data - Additional context data to include with the log event
176
+ */
177
+ track(message: string | unknown, ...data: unknown[]): void;
178
+ /**
179
+ * Logs a message at trace severity level.
180
+ *
181
+ * Trace events provide the most detailed execution information,
182
+ * typically used for fine-grained debugging and performance analysis.
183
+ *
184
+ * @param message - Primary message or serializable object to log
185
+ * @param data - Additional context data to include with the log event
186
+ */
187
+ trace(message: string | unknown, ...data: unknown[]): void;
188
+ /**
189
+ * True when logger's current level enables fatal severity logging.
190
+ * When true, fatal() calls will emit log events.
191
+ */
192
+ readonly isFatal: boolean;
193
+ /**
194
+ * True when logger's current level enables error severity logging.
195
+ * When true, error() calls will emit log events.
196
+ */
197
+ readonly isError: boolean;
198
+ /**
199
+ * True when logger's current level enables warn severity logging.
200
+ * When true, warn() calls will emit log events.
201
+ */
202
+ readonly isWarn: boolean;
203
+ /**
204
+ * True when logger's current level enables info severity logging.
205
+ * When true, info() calls will emit log events.
206
+ */
207
+ readonly isInfo: boolean;
208
+ /**
209
+ * True when logger's current level enables debug severity logging.
210
+ * When true, debug() calls will emit log events.
211
+ */
212
+ readonly isDebug: boolean;
213
+ /**
214
+ * True when logger's current level enables track severity logging.
215
+ * When true, track() calls will emit log events.
216
+ */
217
+ readonly isTrack: boolean;
218
+ /**
219
+ * True when logger's current level enables trace severity logging.
220
+ * When true, trace() calls will emit log events.
221
+ */
222
+ readonly isTrace: boolean;
223
+ /**
224
+ * True when logging is enabled for this logger.
225
+ * False only when the logger level is set to 'off', disabling all log output.
226
+ */
227
+ readonly isEnabled: boolean;
228
+ /** The dot-separated hierarchical name of this logger instance. */
229
+ readonly name: string;
230
+ /** The current logging level determining which events are emitted. */
231
+ readonly level: LogLevelType;
232
+ /** Contextual data automatically included with all log events from this logger. */
233
+ readonly context: LogContext;
234
+ /**
235
+ * Updates the logger's severity level threshold.
236
+ *
237
+ * Events at or below this level will be emitted based on the level hierarchy:
238
+ * off < fatal < error < warn < info < debug < track < trace
239
+ *
240
+ * @param level - New logging level name (e.g., 'info', 'debug', 'off')
241
+ */
242
+ setLevel(level: LogLevelType): void;
243
+ /**
244
+ * Replaces the logger's contextual data.
245
+ *
246
+ * Context is automatically included with all log events emitted by this logger,
247
+ * providing consistent metadata across related log entries.
248
+ *
249
+ * @param context - New context object to associate with this logger
250
+ */
251
+ setContext(context: LogContext): void;
252
+ /**
253
+ * Creates or retrieves a child logger with hierarchical naming.
254
+ *
255
+ * Child loggers inherit configuration but can have independent levels and context.
256
+ * The child's name becomes 'parent.child' using dot notation.
257
+ *
258
+ * @param name - Name segment for the child logger
259
+ * @returns Child logger instance with name 'parent.child'
260
+ *
261
+ * @example
262
+ * ```typescript
263
+ * const parent = Logging.getLogger('app');
264
+ * const child = parent.getLogger('database'); // Name: 'app.database'
265
+ * const grandchild = child.getLogger('queries'); // Name: 'app.database.queries'
266
+ * ```
267
+ */
268
+ getLogger(name: string): Log;
269
+ }
270
+
271
+ /**
272
+ * Configuration options for initializing a plugin.
273
+ */
274
+ interface PluginConfig {
275
+ /**
276
+ * The plugin's unique name.
277
+ */
278
+ name: string;
279
+ /**
280
+ * Additional plugin-specific settings.
281
+ */
282
+ [key: string]: unknown;
283
+ }
284
+
285
+ /**
286
+ * Defines configuration options for a filter plugin.
287
+ * @extends PluginConfig
288
+ */
289
+ interface FilterConfig extends PluginConfig {
290
+ /**
291
+ * Whether the filter is enabled.
292
+ */
293
+ enabled?: boolean;
294
+ }
295
+
296
+ /**
297
+ * Defines configuration options for a formatter plugin.
298
+ * @extends PluginConfig
299
+ */
300
+ interface FormatterConfig extends PluginConfig {
301
+ }
302
+
303
+ /**
304
+ * Defines the configuration options for a log appender plugin.
305
+ */
306
+ interface AppenderConfig extends PluginConfig {
307
+ /**
308
+ * Whether the appender is enabled.
309
+ */
310
+ enabled?: boolean;
311
+ /**
312
+ * Priority determining execution order; higher values run first (descending order).
313
+ */
314
+ priority?: number;
315
+ /**
316
+ * The formatter to apply to log events, specified by name or config object.
317
+ */
318
+ formatter?: string | FormatterConfig;
319
+ /**
320
+ * Filters to apply to log events, specified by name or config objects.
321
+ */
322
+ filters?: (string | FilterConfig)[];
323
+ }
324
+
325
+ /**
326
+ * Primary configuration object for initializing the LogM8 logging system.
327
+ *
328
+ * Defines the overall logging behavior including default levels, per-logger
329
+ * overrides, and output destinations. Used as the parameter to LogM8.init()
330
+ * to configure the entire logging pipeline.
331
+ *
332
+ * If no configuration is provided, the system defaults to console output
333
+ * at 'info' level with the default formatter.
334
+ *
335
+ * @example
336
+ * ```typescript
337
+ * const config: LoggingConfig = {
338
+ * level: 'info',
339
+ * loggers: {
340
+ * 'app.database': 'debug', // More verbose for database operations
341
+ * 'app.security': 'warn', // Less verbose for security components
342
+ * 'app.performance': 'trace' // Maximum detail for performance monitoring
343
+ * },
344
+ * appenders: [
345
+ * {
346
+ * name: 'console',
347
+ * formatter: { name: 'default-formatter', color: true }
348
+ * },
349
+ * {
350
+ * name: 'file',
351
+ * filename: 'app.log',
352
+ * formatter: { name: 'json-formatter', pretty: true }
353
+ * }
354
+ * ]
355
+ * };
356
+ *
357
+ * Logging.init(config);
358
+ * ```
359
+ */
360
+ interface LoggingConfig {
361
+ /**
362
+ * Default log level applied to all loggers unless overridden.
363
+ *
364
+ * Determines the minimum severity level that will be processed.
365
+ * Loggers will emit events at this level and all higher severity levels.
366
+ * Defaults to 'info' if not specified.
367
+ */
368
+ level?: LogLevelType;
369
+ /**
370
+ * Per-logger level overrides by hierarchical name.
371
+ *
372
+ * Allows fine-grained control over logging verbosity for different
373
+ * parts of the application. Logger names use dot-separated hierarchical
374
+ * notation where child loggers inherit from parent configurations.
375
+ *
376
+ * @example
377
+ * ```typescript
378
+ * loggers: {
379
+ * 'app': 'info', // Base level for 'app' namespace
380
+ * 'app.database': 'debug', // More verbose for database operations
381
+ * 'app.database.queries': 'trace' // Maximum detail for query logging
382
+ * }
383
+ * ```
384
+ */
385
+ loggers?: {
386
+ [key: string]: LogLevelType | undefined;
387
+ };
388
+ /**
389
+ * Output destination configurations.
390
+ *
391
+ * Defines where and how log events are written. Each appender can have
392
+ * its own formatter, filters, and specific configuration options.
393
+ * If not specified, defaults to a single console appender.
394
+ *
395
+ * Appenders are executed in priority order (highest first) for
396
+ * deterministic output behavior.
397
+ */
398
+ appenders?: AppenderConfig[];
399
+ /**
400
+ * Global filters applied before any appender-specific processing.
401
+ *
402
+ * Each entry may be a string (filter factory name) or a full FilterConfig
403
+ * object. Global filters run first and can drop events entirely before they
404
+ * reach appenders. Appenders may also define their own filters via
405
+ * AppenderConfig.filters.
406
+ */
407
+ filters?: (string | FilterConfig)[];
408
+ }
409
+
410
+ /**
411
+ * Enumeration of plugin types supported by the LogM8 plugin system.
412
+ *
413
+ * The logging system uses a plugin architecture where functionality is
414
+ * provided by three categories of plugins:
415
+ *
416
+ * - **appender**: Output destinations that write formatted log events
417
+ * - **filter**: Event processors that determine which events to log
418
+ * - **formatter**: Event transformers that convert LogEvent objects to output format
419
+ *
420
+ * Each plugin factory must declare its kind to enable proper registration
421
+ * and instantiation during system initialization.
422
+ *
423
+ * @example
424
+ * ```typescript
425
+ * class CustomAppender implements Appender {
426
+ * kind = PluginKind.appender;
427
+ * // ... implementation
428
+ * }
429
+ *
430
+ * class CustomFilter implements Filter {
431
+ * kind = PluginKind.filter;
432
+ * // ... implementation
433
+ * }
434
+ * ```
435
+ */
436
+ declare const PluginKind: {
437
+ readonly appender: "appender";
438
+ readonly filter: "filter";
439
+ readonly formatter: "formatter";
440
+ };
441
+ /**
442
+ * Type representing a PluginKind enum value.
443
+ */
444
+ type PluginKindType = (typeof PluginKind)[keyof typeof PluginKind];
445
+
446
+ /**
447
+ * Represents a plugin with identifying metadata and lifecycle methods.
448
+ */
449
+ interface Plugin {
450
+ /** The unique plugin name. */
451
+ readonly name: string;
452
+ /** The plugin version in semver format. */
453
+ readonly version: string;
454
+ /** The kind of plugin, categorizing its behavior. */
455
+ readonly kind: PluginKindType;
456
+ /**
457
+ * Initializes the plugin with the given configuration.
458
+ * @param config - Plugin configuration options.
459
+ */
460
+ init(config: PluginConfig): void;
461
+ /**
462
+ * Disposes the plugin, releasing any used resources.
463
+ */
464
+ dispose(): void;
465
+ }
466
+
467
+ /**
468
+ * Factory for creating plugin instances of a specific kind.
469
+ * @template C - Plugin configuration type.
470
+ * @template P - Plugin instance type.
471
+ */
472
+ interface PluginFactory<C extends PluginConfig = PluginConfig, P extends Plugin = Plugin> {
473
+ /** The unique factory name. */
474
+ readonly name: string;
475
+ /** The factory version corresponding to plugin implementations. */
476
+ readonly version: string;
477
+ /** The kind of plugin this factory creates. */
478
+ readonly kind: PluginKindType;
479
+ /**
480
+ * Creates a plugin instance using the provided configuration.
481
+ * @param config - Configuration for the plugin.
482
+ * @returns A new plugin instance.
483
+ */
484
+ create(config: C): P;
485
+ }
486
+
487
+ /**
488
+ * Central logging manager providing hierarchical loggers and configurable output.
489
+ *
490
+ * LogM8 manages the complete logging lifecycle including:
491
+ * - Logger creation and configuration with hierarchical naming
492
+ * - Plugin-based appender, formatter, and filter system
493
+ * - Pre-initialization event buffering (up to 100 events)
494
+ * - Runtime appender and filter control (enable/disable/flush)
495
+ * - Built-in console and file appenders with customizable formatting
496
+ *
497
+ * The manager operates as a singleton export but can also be instantiated directly.
498
+ * Events logged before init() are buffered and flushed on first post-init log.
499
+ *
500
+ * @example
501
+ * ```typescript
502
+ * import { Logging } from 'log-m8';
503
+ *
504
+ * // Configure logging system
505
+ * Logging.init({
506
+ * level: 'info',
507
+ * loggers: { 'app.database': 'debug' },
508
+ * appenders: [
509
+ * { name: 'console', formatter: 'default-formatter' },
510
+ * { name: 'file', filename: 'app.log' }
511
+ * ]
512
+ * });
513
+ *
514
+ * // Use hierarchical loggers
515
+ * const logger = Logging.getLogger('app.service');
516
+ * logger.info('Service started');
517
+ *
518
+ * // Runtime control
519
+ * Logging.disableAppender('console');
520
+ * Logging.disableFilter('sensitive-data');
521
+ * Logging.flushAppenders();
522
+ * ```
523
+ */
524
+ declare class LogM8 {
525
+ private _initialized;
526
+ private _pluginManager;
527
+ private _loggers;
528
+ private _appenders;
529
+ private _filters;
530
+ private _defaultLevel;
531
+ private _logLevelValues;
532
+ private _logLevelSet;
533
+ private _logBuffer;
534
+ constructor();
535
+ /**
536
+ * Initializes the logging system with configuration and flushes any buffered events.
537
+ *
538
+ * Sets up default and per-logger levels, creates configured appenders with their
539
+ * formatters and filters, and processes any events buffered before initialization.
540
+ * Appenders are sorted by priority (descending) for deterministic execution order.
541
+ *
542
+ * @param config - Logging configuration object
543
+ * @param config.level - Default log level for all loggers ('info' if not specified)
544
+ * @param config.loggers - Per-logger level overrides by name
545
+ * @param config.appenders - Appender configurations (defaults to console if not specified)
546
+ *
547
+ * @throws {Error} When referenced plugin factories are not registered
548
+ *
549
+ * @example
550
+ * ```typescript
551
+ * Logging.init({
552
+ * level: 'warn',
553
+ * loggers: { 'app.database': 'debug' },
554
+ * appenders: [{
555
+ * name: 'console',
556
+ * formatter: 'default-formatter',
557
+ * filters: ['sensitive-data']
558
+ * }]
559
+ * });
560
+ * ```
561
+ */
562
+ init(config?: LoggingConfig): void;
563
+ /**
564
+ * Shuts down the logging system and releases all resources.
565
+ *
566
+ * Flushes all appenders, disposes plugin instances, clears logger registry,
567
+ * discards buffered events, and deregisters plugin factories. The system
568
+ * can be reinitialized after disposal.
569
+ *
570
+ * @example
571
+ * ```typescript
572
+ * // Graceful shutdown
573
+ * await new Promise(resolve => {
574
+ * Logging.flushAppenders();
575
+ * setTimeout(() => {
576
+ * Logging.dispose();
577
+ * resolve();
578
+ * }, 100);
579
+ * });
580
+ * ```
581
+ */
582
+ dispose(): void;
583
+ /**
584
+ * Retrieves or creates a logger instance with hierarchical naming.
585
+ *
586
+ * Logger instances are cached and reused for the same name. Names can be
587
+ * provided as strings with dot-separation or as array segments that get
588
+ * joined. Each logger maintains independent level and context settings.
589
+ *
590
+ * @param name - Logger name as string ('app.service') or segments (['app', 'service'])
591
+ * @returns Logger instance for the specified name
592
+ *
593
+ * @example
594
+ * ```typescript
595
+ * const logger1 = Logging.getLogger('app.database');
596
+ * const logger2 = Logging.getLogger(['app', 'database']);
597
+ * // logger1 === logger2 (same instance)
598
+ *
599
+ * logger1.setLevel('debug');
600
+ * logger1.setContext({ service: 'postgres' });
601
+ * ```
602
+ */
603
+ getLogger(name: string | string[]): Log;
604
+ /**
605
+ * Enables an appender to resume processing log events.
606
+ *
607
+ * @param name - Name of the appender to enable
608
+ */
609
+ enableAppender(name: string): void;
610
+ /**
611
+ * Disables an appender to stop processing log events.
612
+ *
613
+ * @param name - Name of the appender to disable
614
+ */
615
+ disableAppender(name: string): void;
616
+ /**
617
+ * Forces an appender to flush any buffered output.
618
+ *
619
+ * Catches and logs flush errors to console without interrupting operation.
620
+ * Useful for ensuring data persistence before shutdown or at intervals.
621
+ *
622
+ * @param name - Name of the appender to flush
623
+ */
624
+ flushAppender(name: string): void;
625
+ /**
626
+ * Flushes all configured appenders.
627
+ *
628
+ * Iterates through all appenders calling flush on each, with individual
629
+ * error handling per appender.
630
+ */
631
+ flushAppenders(): void;
632
+ /**
633
+ * Enables a filter to resume processing log events.
634
+ *
635
+ * When an appender name is provided, enables the filter only for that specific
636
+ * appender. When no appender is specified, enables the filter globally.
637
+ * Silently ignores requests for non-existent filters or appenders.
638
+ *
639
+ * @param name - Name of the filter to enable
640
+ * @param appenderName - Optional appender name to enable filter for specific appender only
641
+ *
642
+ * @example
643
+ * ```typescript
644
+ * // Enable filter globally
645
+ * Logging.enableFilter('sensitive-data');
646
+ *
647
+ * // Enable filter only for console appender
648
+ * Logging.enableFilter('debug-filter', 'console');
649
+ * ```
650
+ */
651
+ enableFilter(name: string, appenderName?: string): void;
652
+ /**
653
+ * Disables a filter to stop processing log events.
654
+ *
655
+ * When an appender name is provided, disables the filter only for that specific
656
+ * appender. When no appender is specified, disables the filter globally.
657
+ * Silently ignores requests for non-existent filters or appenders.
658
+ *
659
+ * @param name - Name of the filter to disable
660
+ * @param appenderName - Optional appender name to disable filter for specific appender only
661
+ *
662
+ * @example
663
+ * ```typescript
664
+ * // Disable filter globally
665
+ * Logging.disableFilter('sensitive-data');
666
+ *
667
+ * // Disable filter only for file appender
668
+ * Logging.disableFilter('debug-filter', 'file');
669
+ * ```
670
+ */
671
+ disableFilter(name: string, appenderName?: string): void;
672
+ /**
673
+ * Registers a custom plugin factory for appenders, formatters, or filters.
674
+ *
675
+ * Allows extending the logging system with custom implementations.
676
+ * Must be called before init() to be available during configuration.
677
+ *
678
+ * @param pluginFactory - Factory instance implementing the PluginFactory interface
679
+ *
680
+ * @example
681
+ * ```typescript
682
+ * class SlackAppenderFactory implements PluginFactory {
683
+ * name = 'slack';
684
+ * kind = PluginKind.appender;
685
+ * create(config) { return new SlackAppender(config); }
686
+ * }
687
+ *
688
+ * Logging.registerPluginFactory(new SlackAppenderFactory());
689
+ * ```
690
+ */
691
+ registerPluginFactory(pluginFactory: PluginFactory): void;
692
+ private _log;
693
+ private _setLevel;
694
+ private _setContext;
695
+ private _processLogEvent;
696
+ private _getAppender;
697
+ private _sortAppenders;
698
+ private _getFilter;
699
+ private _reset;
700
+ }
701
+
702
+ /**
703
+ * Structured representation of a single log entry containing all event data.
704
+ *
705
+ * LogEvent objects are created automatically when logger methods are called
706
+ * and contain the complete context needed for formatting and output by appenders.
707
+ * They are immutable once created and flow through the logging pipeline.
708
+ *
709
+ * @example
710
+ * ```typescript
711
+ * // Created automatically when calling:
712
+ * logger.info('User login', { userId: 123, ip: '192.168.1.1' });
713
+ *
714
+ * // Results in LogEvent:
715
+ * {
716
+ * logger: 'app.auth',
717
+ * level: 'info',
718
+ * message: 'User login',
719
+ * data: [{ userId: 123, ip: '192.168.1.1' }],
720
+ * context: { sessionId: 'sess-456' },
721
+ * timestamp: new Date('2025-08-04T14:23:45.123Z')
722
+ * }
723
+ * ```
724
+ */
725
+ interface LogEvent {
726
+ /**
727
+ * Hierarchical name of the logger that generated this event.
728
+ * Used for filtering and routing by appenders and formatters.
729
+ */
730
+ readonly logger: string;
731
+ /**
732
+ * Severity level determining event importance and routing.
733
+ * Must match one of the LogLevel enum values.
734
+ */
735
+ readonly level: LogLevelType;
736
+ /**
737
+ * Primary log content - can be string, object, or any serializable value.
738
+ * Formatters determine how this is rendered in output.
739
+ */
740
+ readonly message: string | unknown;
741
+ /**
742
+ * Additional arguments passed to the logging method.
743
+ * Typically contains context objects, error details, or supplementary data.
744
+ */
745
+ readonly data: unknown[];
746
+ /**
747
+ * Logger's contextual metadata at the time of event creation.
748
+ * Automatically included from logger.setContext() calls.
749
+ */
750
+ readonly context: LogContext;
751
+ /**
752
+ * Event creation timestamp for chronological ordering and time-based formatting.
753
+ * Set automatically when the log method is called.
754
+ */
755
+ readonly timestamp: Date;
756
+ }
757
+
758
+ /**
759
+ * Represents a log event filter that can be initialized with specific configuration and determines whether a log event should be logged.
760
+ */
761
+ interface Filter extends Plugin {
762
+ /**
763
+ * Runtime flag controlling whether this filter processes events.
764
+ *
765
+ * Can be toggled via LogM8.enableFilter()/disableFilter() for
766
+ * dynamic output control without full reconfiguration.
767
+ */
768
+ enabled: boolean;
769
+ /**
770
+ * Initializes the filter with the specified configuration.
771
+ * @param config - Filter configuration options.
772
+ */
773
+ init(config: FilterConfig): void;
774
+ /**
775
+ * Determines whether the given log event should be logged.
776
+ * @param logEvent - The log event to evaluate.
777
+ * @returns boolean indicating if the event should be logged.
778
+ */
779
+ filter(logEvent: LogEvent): boolean;
780
+ /**
781
+ * Disposes of the filter, cleaning up any resources.
782
+ *
783
+ * Called during parent's dispose() to clean up the filter's resources.
784
+ */
785
+ dispose(): void;
786
+ }
787
+
788
+ /**
789
+ * Represents a log event formatter that initializes with configuration and converts log events into output tokens.
790
+ */
791
+ interface Formatter extends Plugin {
792
+ /**
793
+ * Initializes the formatter with the specified configuration.
794
+ * @param config - Formatter configuration options.
795
+ */
796
+ init(config: FormatterConfig): void;
797
+ /**
798
+ * Formats the given log event into an array of output tokens.
799
+ * @param logEvent - The log event to format.
800
+ * @returns An array of formatted output elements.
801
+ */
802
+ format(logEvent: LogEvent): unknown[];
803
+ /**
804
+ * Disposes of the formatter, cleaning up any resources.
805
+ *
806
+ * Called during parent's dispose() to clean up the formatter's resources.
807
+ */
808
+ dispose(): void;
809
+ }
810
+
811
+ /**
812
+ * Plugin interface for log event output destinations.
813
+ *
814
+ * Appenders receive formatted log events and write them to specific outputs
815
+ * like console, files, network endpoints, or databases. They can be dynamically
816
+ * enabled/disabled and support priority-based execution ordering.
817
+ *
818
+ * Each appender declares which log levels it supports and can optionally
819
+ * use formatters to transform events and filters to determine eligibility.
820
+ *
821
+ * @example
822
+ * ```typescript
823
+ * class DatabaseAppender implements Appender {
824
+ * name = 'database';
825
+ * supportedLevels = new Set(['error', 'fatal']);
826
+ * enabled = true;
827
+ * priority = 10;
828
+ *
829
+ * init(config, formatter, filters) {
830
+ * this.db = new Database(config.connectionString);
831
+ * }
832
+ *
833
+ * write(event) {
834
+ * this.db.insert('logs', this.formatter.format(event));
835
+ * }
836
+ * }
837
+ * ```
838
+ */
839
+ interface Appender extends Plugin {
840
+ /**
841
+ * Set of log levels this appender can process.
842
+ *
843
+ * Events with levels not in this set are automatically skipped.
844
+ * Use this to restrict appenders to specific severity ranges.
845
+ */
846
+ readonly supportedLevels: Set<LogLevelType>;
847
+ /**
848
+ * Runtime flag controlling whether this appender processes events.
849
+ *
850
+ * Can be toggled via LogM8.enableAppender()/disableAppender() for
851
+ * dynamic output control without full reconfiguration.
852
+ */
853
+ enabled: boolean;
854
+ /**
855
+ * Execution priority for deterministic appender ordering.
856
+ *
857
+ * Higher values execute first. Undefined/null treated as 0.
858
+ * Useful for ensuring critical appenders (like error alerting)
859
+ * process events before optional ones (like debug files).
860
+ */
861
+ priority?: number;
862
+ /**
863
+ * Initializes the appender with configuration and optional processing components.
864
+ *
865
+ * Called once during LogM8.init() to set up the appender with its specific
866
+ * configuration, formatter for event transformation, and filters for event
867
+ * eligibility determination.
868
+ *
869
+ * @param config - Appender-specific configuration options
870
+ * @param formatter - Optional formatter to transform log events before output
871
+ * @param filters - Optional filters to determine which events to process
872
+ */
873
+ init(config: AppenderConfig, formatter?: Formatter, filters?: Filter[]): void;
874
+ /**
875
+ * Processes a single log event for output.
876
+ *
877
+ * Called for each log event that passes level and filter checks.
878
+ * Implementations should handle formatting (if no formatter provided)
879
+ * and write to their specific output destination.
880
+ *
881
+ * @param logEvent - The log event to be processed and output
882
+ */
883
+ write(logEvent: LogEvent): void;
884
+ /**
885
+ * Forces immediate output of any buffered log events.
886
+ *
887
+ * Called during appender shutdown or when explicitly requested via
888
+ * LogM8.flushAppender(). Implementations should ensure data persistence.
889
+ */
890
+ flush(): void;
891
+ /**
892
+ * Disposes of the appender and releases any resources.
893
+ *
894
+ * Called during LogM8.dispose() to clean up the appender's resources.
895
+ * Implementations should ensure all buffered events are flushed before disposal.
896
+ */
897
+ dispose(): void;
898
+ /**
899
+ * Enables the specified filter for this appender.
900
+ *
901
+ * @param filterName - The name of the filter to enable
902
+ */
903
+ enableFilter(filterName: string): void;
904
+ /**
905
+ * Disables the specified filter for this appender.
906
+ *
907
+ * @param filterName - The name of the filter to disable
908
+ */
909
+ disableFilter(filterName: string): void;
910
+ }
911
+
912
+ /**
913
+ * Configuration interface for console appender.
914
+ * Currently extends base AppenderConfig without additional options.
915
+ */
916
+ interface ConsoleAppenderConfig extends AppenderConfig {
917
+ }
918
+
919
+ /**
920
+ * Configuration options for the file appender.
921
+ *
922
+ * - filename: Destination file path. The file is opened on init.
923
+ * - append: When true, appends to the existing file; otherwise it is truncated.
924
+ */
925
+ interface FileAppenderConfig extends AppenderConfig {
926
+ /** Destination file path to write logs into. */
927
+ filename: string;
928
+ /** Append to existing file (true) or overwrite on startup (false). Default: false */
929
+ append?: boolean;
930
+ }
931
+
932
+ /**
933
+ * Configuration for MatchFilter.
934
+ *
935
+ * Provides simple allow/deny rule maps where each key is a dot-path into the LogEvent
936
+ * (supports array bracket notation like `data[0].items[2]`) and each value is the value
937
+ * that must match for the rule to apply.
938
+ *
939
+ * Behavior:
940
+ * - allow: If provided and non-empty, an event must satisfy ALL allow rules to pass.
941
+ * - deny: If provided, an event that satisfies ANY deny rule will be blocked.
942
+ * - Precedence: deny rules take precedence over allow; i.e., an event that passes allow
943
+ * but matches a deny rule will be denied.
944
+ *
945
+ * Examples:
946
+ * ```ts
947
+ * // Only allow events from a specific logger AND with a specific data value
948
+ * { name: 'match-filter', allow: { 'logger': 'app.service', 'data[0].type': 'audit' } }
949
+ *
950
+ * // Deny events for a user id regardless of other matches
951
+ * { name: 'match-filter', deny: { 'context.userId': '1234' } }
952
+ *
953
+ * // Combined example
954
+ * {
955
+ * name: 'match-filter',
956
+ * allow: { 'logger': 'allow.this.logger', 'data[0].custom[3].path': 4 },
957
+ * deny: { 'logger': 'block.this.logger', 'context.userId': '1234' }
958
+ * }
959
+ * ```
960
+ */
961
+ interface MatchFilterConfig extends FilterConfig {
962
+ /** All rules in this map must match for the event to be allowed (AND). */
963
+ allow?: Record<string, unknown>;
964
+ /** If any rule in this map matches, the event will be denied (OR). */
965
+ deny?: Record<string, unknown>;
966
+ }
967
+
968
+ /**
969
+ * Configuration for the default text formatter.
970
+ *
971
+ * Extends the base FormatterConfig with options for template customization,
972
+ * timestamp formatting, and optional colorization.
973
+ */
974
+ interface DefaultFormatterConfig extends FormatterConfig {
975
+ /**
976
+ * Custom format template(s) using token syntax.
977
+ * Provide a single template string or an array of template strings for multi-line output.
978
+ * Defaults to a readable text format: ['{timestamp} {LEVEL} [{logger}]', '{message}', '{data}'].
979
+ */
980
+ format?: string | string[];
981
+ /**
982
+ * Timestamp format pattern or preset.
983
+ * Supports 'iso', 'locale', or custom token patterns (yyyy-MM-dd hh:mm:ss).
984
+ */
985
+ timestampFormat?: string;
986
+ /**
987
+ * Enable colorized output for level tokens.
988
+ *
989
+ * - Node.js: Applies ANSI escape codes.
990
+ * - Browser: Returns a tuple ['%cLEVEL', css] suitable for console.log('%c..', ..)
991
+ * when {LEVEL} is resolved; appenders may pass tokens straight to console APIs.
992
+ *
993
+ * Set to true to enable; environment detection is used only to decide ANSI vs CSS.
994
+ */
995
+ color?: boolean;
996
+ }
997
+
998
+ interface StringifyLogOptions {
999
+ /** Max object/array nesting depth to descend into (default 3). */
1000
+ maxDepth?: number;
1001
+ /** Truncate long string values to this length (default 200). */
1002
+ maxStringLength?: number;
1003
+ /** Truncate long arrays to this length (default: 100) */
1004
+ maxArrayLength?: number;
1005
+ }
1006
+ interface SerializedError {
1007
+ name: string;
1008
+ message: string;
1009
+ stack?: string;
1010
+ cause?: SerializedError | null;
1011
+ [key: string]: unknown;
1012
+ }
1013
+ /**
1014
+ * Utility functions for timestamp formatting and object property access.
1015
+ *
1016
+ * Provides environment detection, nested property traversal, and flexible
1017
+ * timestamp formatting with support for custom tokens, ISO formats, and
1018
+ * locale-specific output.
1019
+ */
1020
+ declare class LogM8Utils {
1021
+ /**
1022
+ * Detects browser environment for feature compatibility.
1023
+ *
1024
+ * @returns True when both window and document global objects are available
1025
+ */
1026
+ static isBrowser(): boolean;
1027
+ /**
1028
+ * Check if an object is a string.
1029
+ *
1030
+ * @param obj - The object to check.
1031
+ * @returns true if the object is a string, otherwise false.
1032
+ */
1033
+ static isString(obj: unknown): boolean;
1034
+ /**
1035
+ * Traverses nested object properties using dot-separated path notation.
1036
+ *
1037
+ * Supports both object property access and array indexing with numeric keys.
1038
+ * Also supports bracket notation for array indices which is normalized internally
1039
+ * (e.g., `data[0].items[2]` becomes `data.0.items.2`).
1040
+ * Safe navigation that returns undefined for invalid paths rather than throwing.
1041
+ *
1042
+ * @param obj - Source object to traverse
1043
+ * @param path - Dot-separated property path (e.g., 'user.profile.name', 'items.0.id')
1044
+ * or a path with bracket indices (e.g., 'items[0].id')
1045
+ * @returns Property value at the specified path, or undefined if not found
1046
+ *
1047
+ * @example
1048
+ * ```typescript
1049
+ * const data = { user: { profile: { name: 'John' } }, items: [{ id: 1 }, { id: 2 }] };
1050
+ * getPropertyByPath(data, 'user.profile.name'); // 'John'
1051
+ * getPropertyByPath(data, 'items.0.id'); // 1
1052
+ * getPropertyByPath(data, 'items[1].id'); // 2 (bracket notation)
1053
+ * getPropertyByPath(data, 'missing.path'); // undefined
1054
+ * ```
1055
+ */
1056
+ static getPropertyByPath(obj: unknown, path: string): unknown;
1057
+ /**
1058
+ * Formats Date objects using preset formats or custom token patterns.
1059
+ *
1060
+ * Supports common presets ('iso', 'locale') and flexible token-based formatting
1061
+ * for complete control over timestamp appearance. Tokens are replaced with
1062
+ * corresponding date/time components, while non-token text is preserved literally.
1063
+ *
1064
+ * Supported format tokens:
1065
+ * - yyyy: 4-digit year (2025)
1066
+ * - yy: 2-digit year (25)
1067
+ * - MM: month with leading zero (01-12)
1068
+ * - dd: day with leading zero (01-31)
1069
+ * - hh: 24-hour format hour with leading zero (00-23)
1070
+ * - h: 12-hour format hour (1-12)
1071
+ * - mm: minutes with leading zero (00-59)
1072
+ * - ss: seconds with leading zero (00-59)
1073
+ * - SSS: milliseconds with leading zeros (000-999)
1074
+ * - SS: centiseconds with leading zero (00-99)
1075
+ * - S: deciseconds (0-9)
1076
+ * - A: uppercase AM/PM
1077
+ * - a: lowercase am/pm
1078
+ * - z: timezone offset with colon (±HH:MM)
1079
+ * - zz: timezone offset without colon (±HHMM)
1080
+ *
1081
+ * @param date - Date instance to format
1082
+ * @param fmt - Format preset ('iso'|'locale') or custom token pattern
1083
+ * @returns Formatted timestamp string
1084
+ *
1085
+ * @example
1086
+ * ```typescript
1087
+ * const date = new Date('2025-08-04T14:23:45.123Z');
1088
+ *
1089
+ * // Presets
1090
+ * formatTimestamp(date, 'iso'); // '2025-08-04T14:23:45.123Z'
1091
+ * formatTimestamp(date, 'locale'); // '8/4/2025, 2:23:45 PM' (locale-dependent)
1092
+ *
1093
+ * // Custom patterns
1094
+ * formatTimestamp(date, 'yyyy-MM-dd hh:mm:ss'); // '2025-08-04 14:23:45'
1095
+ * formatTimestamp(date, 'MM/dd/yyyy h:mm A'); // '08/04/2025 2:23 PM'
1096
+ * formatTimestamp(date, 'hh:mm:ss.SSS'); // '14:23:45.123'
1097
+ * formatTimestamp(date, 'yyyy-MM-dd hh:mm:ss z'); // '2025-08-04 14:23:45 +00:00'
1098
+ * ```
1099
+ */
1100
+ static formatTimestamp(date: Date, fmt?: string): string;
1101
+ /**
1102
+ * Converts arbitrary values into JSON strings optimized for logging systems.
1103
+ *
1104
+ * This utility ensures that any JavaScript value can be safely logged without causing
1105
+ * serialization errors or producing excessively large output. It's designed specifically
1106
+ * for logging contexts where reliability and readability are more important than
1107
+ * perfect fidelity.
1108
+ *
1109
+ * ## Key Features
1110
+ *
1111
+ * **Depth Protection**: Prevents stack overflows and excessive output by limiting
1112
+ * object traversal depth. Objects/arrays beyond the limit are replaced with
1113
+ * "[Object]" or "[Array]" placeholders.
1114
+ *
1115
+ * **Array Length Limiting**: Automatically truncates arrays that exceed the maximum
1116
+ * length threshold. Truncated arrays include a message indicating how many additional
1117
+ * items were omitted.
1118
+ *
1119
+ * **String Truncation**: Automatically truncates long strings to prevent log flooding.
1120
+ * Truncated strings end with an ellipsis (…) character.
1121
+ *
1122
+ * **Type Safety**: Handles problematic JavaScript types that would normally cause
1123
+ * JSON.stringify to throw:
1124
+ * - BigInt values are converted to strings
1125
+ * - Date objects are normalized to ISO 8601 format
1126
+ * - Error instances are serialized to structured objects via {@link LogM8Utils.serializeError}
1127
+ *
1128
+ * ## Implementation Details
1129
+ *
1130
+ * - Uses a WeakMap to track traversal depth per object, preventing revisits to the
1131
+ * same instance at different depths
1132
+ * - Respects existing `toJSON()` methods on objects
1133
+ * - Not designed for full cycle detection - cyclic references are handled by the
1134
+ * depth limit rather than explicit cycle breaking
1135
+ * - The replacer function executes in the context of the parent object, enabling
1136
+ * depth tracking through the traversal
1137
+ *
1138
+ * @param value - Any JavaScript value to stringify for logging (events, contexts, errors, etc.)
1139
+ * @param options - Configuration for controlling output size and complexity
1140
+ * @param options.maxDepth - Maximum nesting depth for objects/arrays (default: 3).
1141
+ * Level 0 = primitive values only,
1142
+ * Level 1 = top-level properties,
1143
+ * Level 2 = nested properties, etc.
1144
+ * @param options.maxArrayLength - Maximum number of array elements to include before truncation (default: 100).
1145
+ * Arrays exceeding this limit will be truncated with a message
1146
+ * indicating the number of omitted items.
1147
+ * @param options.maxStringLength - Maximum character length for strings before truncation (default: 200)
1148
+ * @param space - Indentation for pretty-printing. Can be a number (spaces) or string (e.g., '\t').
1149
+ * Pass undefined for compact output (recommended for production logs).
1150
+ *
1151
+ * @returns A JSON string that is guaranteed to be safe for logging systems
1152
+ *
1153
+ * @example
1154
+ * // Basic usage with default options
1155
+ * const json = LogM8Utils.stringifyLog({ message: 'User logged in', userId: 12345 });
1156
+ * // => '{"message":"User logged in","userId":12345}'
1157
+ *
1158
+ * @example
1159
+ * // Handling problematic types
1160
+ * const data = {
1161
+ * bigNumber: 123456789012345678901234567890n,
1162
+ * timestamp: new Date('2024-01-15T10:30:00Z'),
1163
+ * error: new Error('Connection failed'),
1164
+ * longText: 'x'.repeat(500)
1165
+ * };
1166
+ * const json = LogM8Utils.stringifyLog(data);
1167
+ * // => '{"bigNumber":"123456789012345678901234567890","timestamp":"2024-01-15T10:30:00.000Z","error":{...},"longText":"xxx...xxx…"}'
1168
+ *
1169
+ * @example
1170
+ * // Array length limiting for large arrays
1171
+ * const largeData = {
1172
+ * items: new Array(1000).fill({ id: 1, name: 'item' }),
1173
+ * values: Array.from({ length: 500 }, (_, i) => i)
1174
+ * };
1175
+ * const json = LogM8Utils.stringifyLog(largeData, { maxArrayLength: 50 });
1176
+ * // => '{"items":[{...},{...},...,"... 950 more items"],"values":[0,1,2,...,"... 450 more items"]}'
1177
+ *
1178
+ * @example
1179
+ * // Depth limiting for deeply nested objects
1180
+ * const deepObj = {
1181
+ * level1: {
1182
+ * level2: {
1183
+ * level3: {
1184
+ * level4: {
1185
+ * level5: 'too deep'
1186
+ * }
1187
+ * }
1188
+ * }
1189
+ * }
1190
+ * };
1191
+ * const json = LogM8Utils.stringifyLog(deepObj, { maxDepth: 3 });
1192
+ * // => '{"level1":{"level2":{"level3":{"level4":"[Object]"}}}}'
1193
+ *
1194
+ * @example
1195
+ * // Custom options for verbose debugging
1196
+ * const debugJson = LogM8Utils.stringifyLog(
1197
+ * complexObject,
1198
+ * { maxDepth: 5, maxArrayLength: 500, maxStringLength: 1000 },
1199
+ * 2 // Pretty print with 2 spaces
1200
+ * );
1201
+ *
1202
+ * @example
1203
+ * // Production logging with minimal output
1204
+ * const prodJson = LogM8Utils.stringifyLog(
1205
+ * userEvent,
1206
+ * { maxDepth: 2, maxArrayLength: 20, maxStringLength: 100 } // Aggressive truncation for high-volume logs
1207
+ * );
1208
+ *
1209
+ * @example
1210
+ * // Handling arrays with mixed content
1211
+ * const mixedArray = {
1212
+ * results: [
1213
+ * { id: 1, data: 'first' },
1214
+ * { id: 2, data: 'second' },
1215
+ * ...Array(200).fill({ id: 999, data: 'bulk' })
1216
+ * ]
1217
+ * };
1218
+ * const json = LogM8Utils.stringifyLog(mixedArray, { maxArrayLength: 10 });
1219
+ * // First 10 items preserved, then truncation message
1220
+ *
1221
+ * @see {@link LogM8Utils.serializeError} - For Error serialization details
1222
+ */
1223
+ static stringifyLog(value: unknown, { maxDepth, maxStringLength, maxArrayLength }?: StringifyLogOptions, space?: number | string): string;
1224
+ /**
1225
+ * Serializes an Error (or Error-like) into a plain, JSON-safe object.
1226
+ *
1227
+ * Behavior:
1228
+ * - Returns null for falsy inputs.
1229
+ * - If the object provides a custom toJSON(), that result is used verbatim to
1230
+ * honor caller-defined serialization.
1231
+ * - Otherwise includes standard fields: name, message, stack.
1232
+ * - Recursively serializes the optional error.cause chain using the same rules.
1233
+ * - Handles circular references in the cause chain safely.
1234
+ * - Copies other own enumerable properties (excluding name, message, stack, cause),
1235
+ * skipping properties that throw on access or are not JSON-serializable.
1236
+ * - Optionally includes common non-enumerable properties like 'code' if present.
1237
+ *
1238
+ * Important:
1239
+ * - This function does not attempt to preserve all non-enumerable properties.
1240
+ * - Circular references in the cause chain are detected and handled gracefully.
1241
+ *
1242
+ * @param error - Unknown error input (Error instance or compatible object).
1243
+ * @returns Structured error data suitable for logging, or null when input is falsy.
1244
+ *
1245
+ * @example
1246
+ * try {
1247
+ * throw new Error('Boom');
1248
+ * } catch (e) {
1249
+ * const payload = LogM8Utils.serializeError(e);
1250
+ * // { name: 'Error', message: 'Boom', stack: '...', ... }
1251
+ * }
1252
+ */
1253
+ static serializeError(error: unknown): SerializedError | null;
1254
+ }
1255
+
1256
+ /**
1257
+ * Default singleton instance of the LogM8 logging manager.
1258
+ *
1259
+ * Pre-configured with built-in appenders and formatters for immediate use.
1260
+ * Most applications should use this export rather than creating new LogM8 instances.
1261
+ *
1262
+ * @example
1263
+ * ```typescript
1264
+ * import { Logging } from 'log-m8';
1265
+ *
1266
+ * // Initialize with default console output
1267
+ * Logging.init();
1268
+ *
1269
+ * // Get a logger and start logging
1270
+ * const logger = Logging.getLogger('app');
1271
+ * logger.info('Application started');
1272
+ * ```
1273
+ */
1274
+ declare const Logging: LogM8;
1275
+
1276
+ export { type Appender, type AppenderConfig, type ConsoleAppenderConfig, type DefaultFormatterConfig, type FileAppenderConfig, type Filter, type FilterConfig, type Formatter, type FormatterConfig, type Log, type LogContext, LogLevel, type LogLevelType, LogM8Utils, Logging, type LoggingConfig, type MatchFilterConfig, type Plugin, type PluginConfig, type PluginFactory, PluginKind, type PluginKindType };