0
# Logging System
1
2
Configurable logging system with multiple levels, JavaScript console integration, and custom logger support for debugging and monitoring dependency injection operations.
3
4
## Capabilities
5
6
### Logger Interface
7
8
Abstract logging interface for implementing custom loggers with different output destinations.
9
10
```javascript { .api }
11
/**
12
* Abstract logger class for Koin logging system
13
*/
14
abstract class Logger {
15
/**
16
* Display log message at specified level - must be implemented by subclasses
17
* @param level - Log level for the message
18
* @param message - Log message to display
19
*/
20
abstract display(level: Level, message: string): void;
21
22
/**
23
* Log debug level message
24
* @param message - Debug message
25
*/
26
debug(message: string): void;
27
28
/**
29
* Log info level message
30
* @param message - Info message
31
*/
32
info(message: string): void;
33
34
/**
35
* Log warning level message
36
* @param message - Warning message
37
*/
38
warn(message: string): void;
39
40
/**
41
* Log error level message
42
* @param message - Error message
43
*/
44
error(message: string): void;
45
46
/**
47
* Check if logger is at specified level
48
* @param level - Level to check
49
* @returns true if logger will output at this level
50
*/
51
isAt(level: Level): boolean;
52
}
53
```
54
55
**Usage Examples:**
56
57
```javascript
58
import { Logger, Level } from "koin-core";
59
60
// Custom file logger implementation
61
class FileLogger extends Logger {
62
constructor(logFilePath) {
63
super();
64
this.logFilePath = logFilePath;
65
this.currentLevel = Level.INFO;
66
}
67
68
display(level, message) {
69
if (this.isAt(level)) {
70
const timestamp = new Date().toISOString();
71
const logEntry = `[${timestamp}] ${level}: ${message}\n`;
72
73
// Write to file (pseudo-code for file operations)
74
this.appendToFile(this.logFilePath, logEntry);
75
}
76
}
77
78
isAt(level) {
79
const levelPriority = {
80
[Level.DEBUG]: 0,
81
[Level.INFO]: 1,
82
[Level.WARNING]: 2,
83
[Level.ERROR]: 3,
84
[Level.NONE]: 4
85
};
86
87
return levelPriority[level] >= levelPriority[this.currentLevel];
88
}
89
}
90
91
// Custom network logger
92
class NetworkLogger extends Logger {
93
constructor(endpoint) {
94
super();
95
this.endpoint = endpoint;
96
}
97
98
display(level, message) {
99
if (level !== Level.NONE) {
100
const logData = {
101
level: level,
102
message: message,
103
timestamp: Date.now(),
104
source: "koin-core"
105
};
106
107
// Send to logging service
108
fetch(this.endpoint, {
109
method: 'POST',
110
headers: { 'Content-Type': 'application/json' },
111
body: JSON.stringify(logData)
112
}).catch(err => console.error("Logging failed:", err));
113
}
114
}
115
}
116
```
117
118
### Log Levels
119
120
Hierarchical log levels for controlling logging verbosity and filtering.
121
122
```javascript { .api }
123
/**
124
* Log levels for controlling output verbosity
125
*/
126
enum Level {
127
/** Debug level - most verbose, shows all operations */
128
DEBUG = "DEBUG",
129
130
/** Info level - general information about operations */
131
INFO = "INFO",
132
133
/** Warning level - potential issues that don't prevent operation */
134
WARNING = "WARNING",
135
136
/** Error level - errors that may affect operation */
137
ERROR = "ERROR",
138
139
/** None level - no logging output */
140
NONE = "NONE"
141
}
142
```
143
144
**Usage Examples:**
145
146
```javascript
147
import { startKoin, module, Level } from "koin-core";
148
149
const appModule = module((builder) => {
150
builder.single(() => new DatabaseService());
151
builder.factory(() => new ApiClient());
152
});
153
154
// Configure logging level during application start
155
startKoin((app) => {
156
app.modules([appModule]);
157
app.printLogger(Level.DEBUG); // Show all debug information
158
});
159
160
// Or configure with different levels
161
startKoin((app) => {
162
app.modules([appModule]);
163
app.printLogger(Level.ERROR); // Only show errors
164
});
165
166
// Production configuration - no logging
167
startKoin((app) => {
168
app.modules([appModule]);
169
app.printLogger(Level.NONE); // Disable all logging
170
});
171
```
172
173
### JavaScript Console Logger
174
175
Built-in logger implementation using JavaScript console for web and Node.js environments.
176
177
```javascript { .api }
178
/**
179
* Console-based logger implementation for JavaScript environments
180
* Uses console.log, console.warn, console.error for output
181
*/
182
class PrintLogger extends Logger {
183
/**
184
* Create console logger with specified level
185
* @param level - Log level threshold (default: INFO)
186
*/
187
constructor(level: Level = Level.INFO);
188
189
/**
190
* Display message using appropriate console method
191
* @param level - Log level for the message
192
* @param message - Message to display
193
*/
194
display(level: Level, message: string): void;
195
}
196
```
197
198
**Usage Examples:**
199
200
```javascript
201
import { PrintLogger, Level, koinApplication } from "koin-core";
202
203
// Use console logger directly
204
const logger = new PrintLogger(Level.DEBUG);
205
logger.debug("Debug message"); // console.log
206
logger.info("Info message"); // console.log
207
logger.warn("Warning message"); // console.warn
208
logger.error("Error message"); // console.error
209
210
// Configure application with console logger
211
const app = koinApplication((app) => {
212
app.modules([myModule]);
213
app.logger(new PrintLogger(Level.INFO));
214
});
215
216
// Or use the convenience method
217
const app2 = koinApplication((app) => {
218
app.modules([myModule]);
219
app.printLogger(Level.DEBUG); // Creates PrintLogger internally
220
});
221
```
222
223
### No-Op Logger
224
225
Silent logger implementation that produces no output.
226
227
```javascript { .api }
228
/**
229
* Empty logger implementation that produces no output
230
* Useful for production environments or testing
231
*/
232
class EmptyLogger extends Logger {
233
/**
234
* No-op display method - produces no output
235
* @param level - Log level (ignored)
236
* @param message - Message (ignored)
237
*/
238
display(level: Level, message: string): void;
239
}
240
```
241
242
**Usage Examples:**
243
244
```javascript
245
import { EmptyLogger, koinApplication } from "koin-core";
246
247
// Disable all logging
248
const silentApp = koinApplication((app) => {
249
app.modules([productionModule]);
250
app.logger(new EmptyLogger());
251
});
252
253
// Or use NONE level with PrintLogger
254
const silentApp2 = koinApplication((app) => {
255
app.modules([productionModule]);
256
app.printLogger(Level.NONE);
257
});
258
```
259
260
### Application Logger Configuration
261
262
Configure logging during application setup with different strategies.
263
264
```javascript { .api }
265
class KoinApplication {
266
/**
267
* Set custom logger implementation
268
* @param logger - Custom Logger instance
269
* @returns KoinApplication for chaining
270
*/
271
logger(logger: Logger): KoinApplication;
272
273
/**
274
* Use default console logger with specified level
275
* @param level - Log level (default: INFO)
276
* @returns KoinApplication for chaining
277
*/
278
printLogger(level?: Level): KoinApplication;
279
}
280
```
281
282
**Usage Examples:**
283
284
```javascript
285
import { startKoin, module, Level, PrintLogger } from "koin-core";
286
287
// Development configuration with verbose logging
288
startKoin((app) => {
289
app.modules([devModule]);
290
app.printLogger(Level.DEBUG);
291
});
292
293
// Production configuration with custom logger
294
class ProductionLogger extends Logger {
295
constructor() {
296
super();
297
this.logQueue = [];
298
}
299
300
display(level, message) {
301
// Buffer logs and send in batches
302
this.logQueue.push({ level, message, timestamp: Date.now() });
303
304
if (this.logQueue.length >= 10) {
305
this.flushLogs();
306
}
307
}
308
309
flushLogs() {
310
// Send logs to monitoring service
311
this.sendToMonitoring(this.logQueue);
312
this.logQueue = [];
313
}
314
}
315
316
startKoin((app) => {
317
app.modules([prodModule]);
318
app.logger(new ProductionLogger());
319
});
320
321
// Testing configuration with no logging
322
startKoin((app) => {
323
app.modules([testModule]);
324
app.printLogger(Level.NONE);
325
});
326
```
327
328
### Logging Context and Message Formatting
329
330
Enhanced logging with context information and structured messages.
331
332
```javascript { .api }
333
/**
334
* Enhanced logger with context support
335
*/
336
class ContextualLogger extends Logger {
337
constructor(baseLogger, context) {
338
super();
339
this.baseLogger = baseLogger;
340
this.context = context;
341
}
342
343
display(level, message) {
344
const contextualMessage = `[${this.context}] ${message}`;
345
this.baseLogger.display(level, contextualMessage);
346
}
347
}
348
349
/**
350
* Structured logger for JSON-formatted output
351
*/
352
class StructuredLogger extends Logger {
353
constructor(outputFunction) {
354
super();
355
this.output = outputFunction || console.log;
356
}
357
358
display(level, message) {
359
const logEntry = {
360
timestamp: new Date().toISOString(),
361
level: level,
362
message: message,
363
source: "koin-core"
364
};
365
366
this.output(JSON.stringify(logEntry));
367
}
368
}
369
```
370
371
**Usage Examples:**
372
373
```javascript
374
import { ContextualLogger, StructuredLogger, PrintLogger } from "koin-core";
375
376
// Contextual logging for different components
377
const dbLogger = new ContextualLogger(
378
new PrintLogger(Level.DEBUG),
379
"DATABASE"
380
);
381
382
const apiLogger = new ContextualLogger(
383
new PrintLogger(Level.INFO),
384
"API"
385
);
386
387
// Structured logging for log aggregation
388
const structuredLogger = new StructuredLogger((jsonLog) => {
389
// Send to log aggregation service
390
console.log(jsonLog);
391
// Example output: {"timestamp":"2024-01-15T10:30:00.000Z","level":"INFO","message":"Loading module","source":"koin-core"}
392
});
393
394
// Use contextual loggers in application
395
startKoin((app) => {
396
app.modules([databaseModule]);
397
app.logger(dbLogger);
398
});
399
```
400
401
### Runtime Logger Control
402
403
Change logging configuration at runtime for dynamic control.
404
405
```javascript { .api }
406
class Koin {
407
/**
408
* Update logger at runtime
409
* @param logger - New logger instance
410
*/
411
setLogger(logger: Logger): void;
412
413
/**
414
* Get current logger instance
415
* @returns Current Logger
416
*/
417
getLogger(): Logger;
418
}
419
```
420
421
**Usage Examples:**
422
423
```javascript
424
import { GlobalContext, PrintLogger, EmptyLogger, Level } from "koin-core";
425
426
class LoggingManager {
427
constructor() {
428
this.debugMode = false;
429
}
430
431
enableDebugLogging() {
432
if (!this.debugMode) {
433
const koin = GlobalContext.get();
434
koin.setLogger(new PrintLogger(Level.DEBUG));
435
this.debugMode = true;
436
console.log("Debug logging enabled");
437
}
438
}
439
440
disableLogging() {
441
const koin = GlobalContext.get();
442
koin.setLogger(new EmptyLogger());
443
this.debugMode = false;
444
console.log("Logging disabled");
445
}
446
447
setLogLevel(level) {
448
const koin = GlobalContext.get();
449
koin.setLogger(new PrintLogger(level));
450
console.log(`Log level set to: ${level}`);
451
}
452
453
getCurrentLogger() {
454
const koin = GlobalContext.get();
455
return koin.getLogger();
456
}
457
}
458
459
// Usage
460
const loggingManager = new LoggingManager();
461
462
// Enable debug logging temporarily
463
loggingManager.enableDebugLogging();
464
465
// Process some operations...
466
467
// Disable logging for performance
468
loggingManager.disableLogging();
469
470
// Set specific log level
471
loggingManager.setLogLevel(Level.WARNING);
472
```
473
474
### Logging Best Practices
475
476
Utilities and patterns for effective logging in Koin applications.
477
478
```javascript { .api }
479
/**
480
* Logging utilities for common patterns
481
*/
482
class LoggingUtils {
483
/**
484
* Create filtered logger that only logs specific patterns
485
* @param baseLogger - Base logger to filter
486
* @param filterFunction - Function to determine if message should be logged
487
* @returns Filtered logger
488
*/
489
static createFilteredLogger(baseLogger, filterFunction) {
490
return new (class extends Logger {
491
display(level, message) {
492
if (filterFunction(level, message)) {
493
baseLogger.display(level, message);
494
}
495
}
496
})();
497
}
498
499
/**
500
* Create rate-limited logger to prevent spam
501
* @param baseLogger - Base logger to rate limit
502
* @param maxMessagesPerSecond - Maximum messages per second
503
* @returns Rate-limited logger
504
*/
505
static createRateLimitedLogger(baseLogger, maxMessagesPerSecond = 10) {
506
const messageQueue = [];
507
const windowMs = 1000;
508
509
return new (class extends Logger {
510
display(level, message) {
511
const now = Date.now();
512
513
// Remove old messages outside window
514
while (messageQueue.length > 0 && messageQueue[0] < now - windowMs) {
515
messageQueue.shift();
516
}
517
518
// Check rate limit
519
if (messageQueue.length < maxMessagesPerSecond) {
520
messageQueue.push(now);
521
baseLogger.display(level, message);
522
}
523
}
524
})();
525
}
526
}
527
```
528
529
**Usage Examples:**
530
531
```javascript
532
import { LoggingUtils, PrintLogger, Level } from "koin-core";
533
534
// Filter out debug messages in production
535
const productionLogger = LoggingUtils.createFilteredLogger(
536
new PrintLogger(Level.DEBUG),
537
(level, message) => level !== Level.DEBUG || !message.includes("debug")
538
);
539
540
// Rate-limited logger to prevent log spam
541
const rateLimitedLogger = LoggingUtils.createRateLimitedLogger(
542
new PrintLogger(Level.INFO),
543
5 // Max 5 messages per second
544
);
545
546
// Use filtered logger
547
startKoin((app) => {
548
app.modules([appModule]);
549
app.logger(productionLogger);
550
});
551
```
552
553
## Types
554
555
```javascript { .api }
556
/** Abstract logger class */
557
abstract class Logger {
558
abstract display(level: Level, message: string): void;
559
debug(message: string): void;
560
info(message: string): void;
561
warn(message: string): void;
562
error(message: string): void;
563
isAt(level: Level): boolean;
564
}
565
566
/** Log levels enumeration */
567
enum Level {
568
DEBUG = "DEBUG",
569
INFO = "INFO",
570
WARNING = "WARNING",
571
ERROR = "ERROR",
572
NONE = "NONE"
573
}
574
575
/** Console-based logger implementation */
576
class PrintLogger extends Logger {
577
constructor(level?: Level);
578
display(level: Level, message: string): void;
579
}
580
581
/** No-op logger implementation */
582
class EmptyLogger extends Logger {
583
display(level: Level, message: string): void;
584
}
585
586
/** Message type for logging */
587
type MESSAGE = string;
588
```