@rabbit-company/logger 5.0.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -7
- package/module/logger.d.ts +276 -35
- package/module/logger.js +56 -23
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ A versatile, multi-transport logging library for Node.js and browser environment
|
|
|
12
12
|
|
|
13
13
|
## Features ✨
|
|
14
14
|
|
|
15
|
-
- **Multiple log levels**: ERROR, WARN, INFO, HTTP,
|
|
15
|
+
- **Multiple log levels**: ERROR, WARN, AUDIT, INFO, HTTP, DEBUG, VERBOSE, SILLY
|
|
16
16
|
- **Structured logging**: Attach metadata objects to log entries
|
|
17
17
|
- **Transport system**: Console, NDJSON, and Loki transports included
|
|
18
18
|
- **Loki optimized**: Automatic label management and batching
|
|
@@ -48,6 +48,42 @@ logger.error("Database connection failed", {
|
|
|
48
48
|
});
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
## Console Formatting 🖥️
|
|
52
|
+
|
|
53
|
+
The console transport supports extensive datetime formatting:
|
|
54
|
+
|
|
55
|
+
### Available Placeholders
|
|
56
|
+
|
|
57
|
+
#### UTC Formats:
|
|
58
|
+
|
|
59
|
+
- `{iso}`: Full ISO-8601 (2023-11-15T14:30:45.123Z)
|
|
60
|
+
- `{datetime}`: Simplified (2023-11-15 14:30:45)
|
|
61
|
+
- `{date}`: Date only (2023-11-15)
|
|
62
|
+
- `{time}`: Time only (14:30:45)
|
|
63
|
+
- `{utc}`: UTC string (Wed, 15 Nov 2023 14:30:45 GMT)
|
|
64
|
+
- `{ms}`: Milliseconds since epoch
|
|
65
|
+
|
|
66
|
+
#### Local Time Formats:
|
|
67
|
+
|
|
68
|
+
- `{datetime-local}`: Local datetime (2023-11-15 14:30:45)
|
|
69
|
+
- `{date-local}`: Local date only (2023-11-15)
|
|
70
|
+
- `{time-local}`: Local time only (14:30:45)
|
|
71
|
+
- `{full-local}`: Complete local string with timezone
|
|
72
|
+
|
|
73
|
+
#### Log Content:
|
|
74
|
+
|
|
75
|
+
- `{type}`: Log level (INFO, ERROR, etc.)
|
|
76
|
+
- `{message}`: The log message
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
import { ConsoleTransport } from "@rabbit-company/logger";
|
|
80
|
+
|
|
81
|
+
// Custom format examples
|
|
82
|
+
new ConsoleTransport("[{datetime-local}] {type} {message}");
|
|
83
|
+
new ConsoleTransport("{time} | {type} | {message}", false);
|
|
84
|
+
new ConsoleTransport("EPOCH:{ms} {message}");
|
|
85
|
+
```
|
|
86
|
+
|
|
51
87
|
## Transports 🚚
|
|
52
88
|
|
|
53
89
|
### Console Transport (Default)
|
|
@@ -58,7 +94,7 @@ import { ConsoleTransport } from "@rabbit-company/logger";
|
|
|
58
94
|
const logger = new Logger({
|
|
59
95
|
transports: [
|
|
60
96
|
new ConsoleTransport(
|
|
61
|
-
"[{
|
|
97
|
+
"[{time-local}] {type} {message}", // Custom format
|
|
62
98
|
true // Enable colors
|
|
63
99
|
),
|
|
64
100
|
],
|
|
@@ -104,11 +140,12 @@ const logger = new Logger({
|
|
|
104
140
|
enum Levels {
|
|
105
141
|
ERROR, // Critical errors
|
|
106
142
|
WARN, // Warnings
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
DEBUG, //
|
|
111
|
-
|
|
143
|
+
AUDIT, // Security audits
|
|
144
|
+
INFO, // Informational
|
|
145
|
+
HTTP, // HTTP traffic
|
|
146
|
+
DEBUG, // Debugging
|
|
147
|
+
VERBOSE, // Detailed tracing
|
|
148
|
+
SILLY // Very low-level
|
|
112
149
|
}
|
|
113
150
|
```
|
|
114
151
|
|
|
@@ -117,6 +154,7 @@ enum Levels {
|
|
|
117
154
|
```js
|
|
118
155
|
logger.error(message: string, metadata?: object): void
|
|
119
156
|
logger.warn(message: string, metadata?: object): void
|
|
157
|
+
logger.audit(message: string, metadata?: object): void
|
|
120
158
|
logger.info(message: string, metadata?: object): void
|
|
121
159
|
logger.http(message: string, metadata?: object): void
|
|
122
160
|
logger.verbose(message: string, metadata?: object): void
|
package/module/logger.d.ts
CHANGED
|
@@ -45,43 +45,68 @@ export declare const enum Colors {
|
|
|
45
45
|
*
|
|
46
46
|
* The levels are ordered from most important (ERROR) to least important (SILLY).
|
|
47
47
|
* When setting a log level, only messages of that level or higher will be emitted.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // Set logger to display DEBUG level and above
|
|
51
|
+
* logger.setLevel(Levels.DEBUG);
|
|
48
52
|
*/
|
|
49
53
|
export declare enum Levels {
|
|
50
54
|
/**
|
|
51
55
|
* Error level. Indicates critical issues that require immediate attention.
|
|
52
56
|
* Use for unrecoverable errors that prevent normal operation.
|
|
57
|
+
* @example
|
|
58
|
+
* logger.error("Database connection failed");
|
|
53
59
|
*/
|
|
54
60
|
ERROR = 0,
|
|
55
61
|
/**
|
|
56
62
|
* Warning level. Indicates potential issues or noteworthy conditions.
|
|
57
63
|
* Use for recoverable issues that don't prevent normal operation.
|
|
64
|
+
* @example
|
|
65
|
+
* logger.warn("High memory usage detected");
|
|
58
66
|
*/
|
|
59
67
|
WARN = 1,
|
|
68
|
+
/**
|
|
69
|
+
* Audit level. For security-sensitive operations and compliance logging.
|
|
70
|
+
* Use for tracking authentication, authorization, and sensitive data access.
|
|
71
|
+
* @example
|
|
72
|
+
* logger.audit("User permissions changed", { user: "admin", changes: [...] });
|
|
73
|
+
*/
|
|
74
|
+
AUDIT = 2,
|
|
60
75
|
/**
|
|
61
76
|
* Informational level. Provides general information about the application's state.
|
|
62
77
|
* Use for normal operational messages that highlight progress.
|
|
78
|
+
* @example
|
|
79
|
+
* logger.info("Application started on port 3000");
|
|
63
80
|
*/
|
|
64
|
-
INFO =
|
|
81
|
+
INFO = 3,
|
|
65
82
|
/**
|
|
66
83
|
* HTTP-related level. Logs HTTP requests and responses.
|
|
67
84
|
* Use for tracking HTTP API calls and their status.
|
|
85
|
+
* @example
|
|
86
|
+
* logger.http("GET /api/users 200 45ms");
|
|
68
87
|
*/
|
|
69
|
-
HTTP =
|
|
70
|
-
/**
|
|
71
|
-
* Verbose level. Provides detailed information for in-depth analysis.
|
|
72
|
-
* Use for detailed operational logs that are typically only needed during debugging.
|
|
73
|
-
*/
|
|
74
|
-
VERBOSE = 4,
|
|
88
|
+
HTTP = 4,
|
|
75
89
|
/**
|
|
76
90
|
* Debug level. Provides detailed context for debugging purposes.
|
|
77
91
|
* Use for extended debugging information during development.
|
|
92
|
+
* @example
|
|
93
|
+
* logger.debug("Database query", { query: "...", duration: "120ms" });
|
|
78
94
|
*/
|
|
79
95
|
DEBUG = 5,
|
|
96
|
+
/**
|
|
97
|
+
* Verbose level. Provides detailed information for in-depth analysis.
|
|
98
|
+
* Use for detailed operational logs that are typically only needed during debugging.
|
|
99
|
+
* @example
|
|
100
|
+
* logger.verbose("Cache update cycle completed", { entries: 1423 });
|
|
101
|
+
*/
|
|
102
|
+
VERBOSE = 6,
|
|
80
103
|
/**
|
|
81
104
|
* Silly level. Logs very low-level messages.
|
|
82
105
|
* Use for extremely verbose logging messages.
|
|
106
|
+
* @example
|
|
107
|
+
* logger.silly("Iteration 14563 completed");
|
|
83
108
|
*/
|
|
84
|
-
SILLY =
|
|
109
|
+
SILLY = 7
|
|
85
110
|
}
|
|
86
111
|
/**
|
|
87
112
|
* Represents a single log entry with message, severity level, timestamp, and optional metadata
|
|
@@ -216,103 +241,290 @@ export declare class Logger {
|
|
|
216
241
|
*/
|
|
217
242
|
private processEntry;
|
|
218
243
|
/**
|
|
219
|
-
* Logs an error message
|
|
244
|
+
* Logs an error message (highest severity)
|
|
220
245
|
* @param message The error message
|
|
221
246
|
* @param metadata Optional metadata object
|
|
247
|
+
* @example
|
|
248
|
+
* logger.error("Database connection failed", { error: error.stack });
|
|
222
249
|
*/
|
|
223
250
|
error(message: string, metadata?: Record<string, any>): void;
|
|
224
251
|
/**
|
|
225
252
|
* Logs a warning message
|
|
226
253
|
* @param message The warning message
|
|
227
254
|
* @param metadata Optional metadata object
|
|
255
|
+
* @example
|
|
256
|
+
* logger.warn("High memory usage detected", { usage: "85%" });
|
|
228
257
|
*/
|
|
229
258
|
warn(message: string, metadata?: Record<string, any>): void;
|
|
259
|
+
/**
|
|
260
|
+
* Logs security-sensitive audit events
|
|
261
|
+
* @param message The audit message
|
|
262
|
+
* @param metadata Optional metadata object
|
|
263
|
+
* @example
|
|
264
|
+
* logger.audit("User permissions modified", {
|
|
265
|
+
* actor: "admin@example.com",
|
|
266
|
+
* action: "role_change",
|
|
267
|
+
* target: "user:1234"
|
|
268
|
+
* });
|
|
269
|
+
*/
|
|
270
|
+
audit(message: string, metadata?: Record<string, any>): void;
|
|
230
271
|
/**
|
|
231
272
|
* Logs an informational message
|
|
232
273
|
* @param message The info message
|
|
233
274
|
* @param metadata Optional metadata object
|
|
275
|
+
* @example
|
|
276
|
+
* logger.info("Server started", { port: 3000, env: "production" });
|
|
234
277
|
*/
|
|
235
278
|
info(message: string, metadata?: Record<string, any>): void;
|
|
236
279
|
/**
|
|
237
|
-
* Logs
|
|
280
|
+
* Logs HTTP-related messages
|
|
238
281
|
* @param message The HTTP message
|
|
239
282
|
* @param metadata Optional metadata object
|
|
283
|
+
* @example
|
|
284
|
+
* logger.http("Request completed", {
|
|
285
|
+
* method: "GET",
|
|
286
|
+
* path: "/api/users",
|
|
287
|
+
* status: 200,
|
|
288
|
+
* duration: "45ms"
|
|
289
|
+
* });
|
|
240
290
|
*/
|
|
241
291
|
http(message: string, metadata?: Record<string, any>): void;
|
|
242
292
|
/**
|
|
243
|
-
* Logs
|
|
244
|
-
* @param message The
|
|
293
|
+
* Logs debug information (for development environments)
|
|
294
|
+
* @param message The debug message
|
|
245
295
|
* @param metadata Optional metadata object
|
|
296
|
+
* @example
|
|
297
|
+
* logger.debug("Database query", {
|
|
298
|
+
* query: "SELECT * FROM users",
|
|
299
|
+
* parameters: { limit: 50 }
|
|
300
|
+
* });
|
|
246
301
|
*/
|
|
247
|
-
|
|
302
|
+
debug(message: string, metadata?: Record<string, any>): void;
|
|
248
303
|
/**
|
|
249
|
-
* Logs
|
|
250
|
-
* @param message The
|
|
304
|
+
* Logs verbose tracing information (very detailed)
|
|
305
|
+
* @param message The verbose message
|
|
251
306
|
* @param metadata Optional metadata object
|
|
307
|
+
* @example
|
|
308
|
+
* logger.verbose("Cache update cycle", {
|
|
309
|
+
* entriesProcessed: 1423,
|
|
310
|
+
* memoryUsage: "1.2MB"
|
|
311
|
+
* });
|
|
252
312
|
*/
|
|
253
|
-
|
|
313
|
+
verbose(message: string, metadata?: Record<string, any>): void;
|
|
254
314
|
/**
|
|
255
|
-
* Logs
|
|
315
|
+
* Logs extremely low-level details (lowest severity)
|
|
256
316
|
* @param message The silly message
|
|
257
|
-
* @param metadata Optional metadata
|
|
317
|
+
* @param metadata Optional metadata data
|
|
318
|
+
* @example
|
|
319
|
+
* logger.silly("Iteration complete", { iteration: 14563 });
|
|
258
320
|
*/
|
|
259
321
|
silly(message: string, metadata?: Record<string, any>): void;
|
|
260
322
|
/**
|
|
261
323
|
* Adds a new transport to the logger
|
|
262
324
|
* @param transport The transport to add
|
|
325
|
+
* @example
|
|
326
|
+
* logger.addTransport(new LokiTransport({ url: "http://loki:3100" }));
|
|
263
327
|
*/
|
|
264
328
|
addTransport(transport: Transport): void;
|
|
265
329
|
/**
|
|
266
330
|
* Removes a transport from the logger
|
|
267
331
|
* @param transport The transport to remove
|
|
332
|
+
* @example
|
|
333
|
+
* logger.removeTransport(consoleTransport);
|
|
268
334
|
*/
|
|
269
335
|
removeTransport(transport: Transport): void;
|
|
270
336
|
/**
|
|
271
337
|
* Sets the minimum log level
|
|
272
338
|
* @param level The new minimum log level
|
|
339
|
+
* @example
|
|
340
|
+
* // Only show errors and warnings
|
|
341
|
+
* logger.setLevel(Levels.WARN);
|
|
273
342
|
*/
|
|
274
343
|
setLevel(level: Levels): void;
|
|
275
344
|
}
|
|
276
345
|
/**
|
|
277
|
-
* Transport that outputs logs to the console with configurable formatting
|
|
346
|
+
* Transport that outputs logs to the console with configurable formatting and colors.
|
|
347
|
+
*
|
|
348
|
+
* Features:
|
|
349
|
+
* - Customizable output format with extensive placeholder support
|
|
350
|
+
* - ANSI color support (enabled by default)
|
|
351
|
+
* - Cross-platform compatibility (Node.js and browsers)
|
|
352
|
+
* - Lightweight and performant
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* // Basic usage with default formatting
|
|
356
|
+
* const transport = new ConsoleTransport();
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* // Custom format with local timestamps
|
|
360
|
+
* const transport = new ConsoleTransport(
|
|
361
|
+
* "[{datetime-local}] {type} - {message}",
|
|
362
|
+
* true
|
|
363
|
+
* );
|
|
278
364
|
*/
|
|
279
365
|
export declare class ConsoleTransport implements Transport {
|
|
280
366
|
private format;
|
|
281
367
|
private colors;
|
|
282
368
|
/**
|
|
283
|
-
*
|
|
284
|
-
* @param format Format string
|
|
285
|
-
*
|
|
369
|
+
* Creates a new ConsoleTransport instance
|
|
370
|
+
* @param format Format string supporting these placeholders:
|
|
371
|
+
*
|
|
372
|
+
* ### Time/Date Formats
|
|
373
|
+
* - `{iso}`: Full ISO-8601 UTC format (YYYY-MM-DDTHH:MM:SS.mmmZ)
|
|
374
|
+
* - `{datetime}`: Simplified UTC (YYYY-MM-DD HH:MM:SS)
|
|
375
|
+
* - `{date}`: UTC date only (YYYY-MM-DD)
|
|
376
|
+
* - `{time}`: UTC time only (HH:MM:SS)
|
|
377
|
+
* - `{datetime-local}`: Local datetime (YYYY-MM-DD HH:MM:SS)
|
|
378
|
+
* - `{date-local}`: Local date only (YYYY-MM-DD)
|
|
379
|
+
* - `{time-local}`: Local time only (HH:MM:SS)
|
|
380
|
+
* - `{ms}`: Milliseconds since epoch
|
|
381
|
+
*
|
|
382
|
+
* ### Log Content
|
|
383
|
+
* - `{type}`: Log level name (e.g., "INFO")
|
|
384
|
+
* - `{message}`: The log message content
|
|
385
|
+
*
|
|
386
|
+
* @default "[{datetime-local}] {type} {message}"
|
|
387
|
+
*
|
|
388
|
+
* @param colors Enable ANSI color output. When disabled:
|
|
389
|
+
* - Improves performance in non-TTY environments
|
|
390
|
+
* - Removes all color formatting
|
|
391
|
+
* @default true
|
|
392
|
+
*
|
|
393
|
+
* @example
|
|
394
|
+
* // UTC format example
|
|
395
|
+
* new ConsoleTransport("{date} {time} [{type}] {message}");
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* // Local time with colors disabled
|
|
399
|
+
* new ConsoleTransport("{time-local} - {message}", false);
|
|
286
400
|
*/
|
|
287
401
|
constructor(format?: string, colors?: boolean);
|
|
288
402
|
/**
|
|
289
|
-
*
|
|
290
|
-
*
|
|
403
|
+
* Formats and outputs a log entry to the console.
|
|
404
|
+
*
|
|
405
|
+
* Applies the configured format with these features:
|
|
406
|
+
* - All specified placeholders are replaced
|
|
407
|
+
* - Colors are applied to level names and messages
|
|
408
|
+
* - Timestamps are dimmed for better readability
|
|
409
|
+
*
|
|
410
|
+
* @param entry The log entry containing:
|
|
411
|
+
* - message: string - The primary log content
|
|
412
|
+
* - level: Levels - The severity level
|
|
413
|
+
* - timestamp: number - Creation time (ms since epoch)
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* // With all placeholder types
|
|
417
|
+
* transport.log({
|
|
418
|
+
* message: "User logged in",
|
|
419
|
+
* level: Levels.INFO,
|
|
420
|
+
* timestamp: Date.now()
|
|
421
|
+
* });
|
|
291
422
|
*/
|
|
292
423
|
log(entry: LogEntry): void;
|
|
293
424
|
}
|
|
294
425
|
/**
|
|
295
|
-
* Transport that collects logs in NDJSON (Newline Delimited JSON) format
|
|
426
|
+
* Transport that collects logs in NDJSON (Newline Delimited JSON) format.
|
|
427
|
+
*
|
|
428
|
+
* This transport accumulates log entries in memory as NDJSON strings,
|
|
429
|
+
* which can be retrieved or cleared as needed. Useful for:
|
|
430
|
+
* - Log aggregation
|
|
431
|
+
* - Bulk exporting logs
|
|
432
|
+
* - Integration with log processing pipelines
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* // Basic usage
|
|
436
|
+
* const transport = new NDJsonTransport();
|
|
437
|
+
* const logger = new Logger({ transports: [transport] });
|
|
438
|
+
*
|
|
439
|
+
* // Get logs as NDJSON string
|
|
440
|
+
* const logs = transport.getData();
|
|
441
|
+
*
|
|
442
|
+
* @example
|
|
443
|
+
* // Periodic log flushing
|
|
444
|
+
* setInterval(() => {
|
|
445
|
+
* const logs = transport.getData();
|
|
446
|
+
* if (logs) {
|
|
447
|
+
* sendToServer(logs);
|
|
448
|
+
* transport.reset();
|
|
449
|
+
* }
|
|
450
|
+
* }, 60000);
|
|
296
451
|
*/
|
|
297
452
|
export declare class NDJsonTransport implements Transport {
|
|
298
453
|
private data;
|
|
299
454
|
/**
|
|
300
|
-
*
|
|
301
|
-
*
|
|
455
|
+
* Appends a log entry to the internal NDJSON buffer.
|
|
456
|
+
*
|
|
457
|
+
* Automatically adds newline separators between entries.
|
|
458
|
+
*
|
|
459
|
+
* @param entry The log entry to append. Must contain:
|
|
460
|
+
* - message: string
|
|
461
|
+
* - level: Levels
|
|
462
|
+
* - timestamp: number
|
|
463
|
+
* - metadata?: object
|
|
464
|
+
*
|
|
465
|
+
* @example
|
|
466
|
+
* transport.log({
|
|
467
|
+
* message: "System started",
|
|
468
|
+
* level: Levels.INFO,
|
|
469
|
+
* timestamp: Date.now()
|
|
470
|
+
* });
|
|
302
471
|
*/
|
|
303
472
|
log(entry: LogEntry): void;
|
|
304
473
|
/**
|
|
305
|
-
*
|
|
306
|
-
*
|
|
474
|
+
* Retrieves all accumulated logs as an NDJSON string.
|
|
475
|
+
*
|
|
476
|
+
* The returned string will contain one log entry per line,
|
|
477
|
+
* with each line being a valid JSON string.
|
|
478
|
+
*
|
|
479
|
+
* @returns {string} NDJSON formatted log data. Returns empty string if no logs.
|
|
480
|
+
*
|
|
481
|
+
* @example
|
|
482
|
+
* // Get logs for API response
|
|
483
|
+
* app.get('/logs', (req, res) => {
|
|
484
|
+
* res.type('application/x-ndjson');
|
|
485
|
+
* res.send(transport.getData());
|
|
486
|
+
* });
|
|
307
487
|
*/
|
|
308
488
|
getData(): string;
|
|
309
489
|
/**
|
|
310
|
-
*
|
|
490
|
+
* Clears all accumulated log data from memory.
|
|
491
|
+
*
|
|
492
|
+
* Typically called after successfully transmitting logs
|
|
493
|
+
* to prevent duplicate processing.
|
|
494
|
+
*
|
|
495
|
+
* @example
|
|
496
|
+
* // Clear after successful upload
|
|
497
|
+
* if (uploadLogs(transport.getData())) {
|
|
498
|
+
* transport.reset();
|
|
499
|
+
* }
|
|
311
500
|
*/
|
|
312
501
|
reset(): void;
|
|
313
502
|
}
|
|
314
503
|
/**
|
|
315
|
-
* Transport that sends logs to a Grafana Loki server
|
|
504
|
+
* Transport that sends logs to a Grafana Loki server with batching and retry support.
|
|
505
|
+
*
|
|
506
|
+
* Features:
|
|
507
|
+
* - Automatic batching of logs for efficient transmission
|
|
508
|
+
* - Configurable batch size and timeout
|
|
509
|
+
* - Label management with cardinality control
|
|
510
|
+
* - Multi-tenancy support via X-Scope-OrgID
|
|
511
|
+
* - Basic authentication support
|
|
512
|
+
*
|
|
513
|
+
* @example
|
|
514
|
+
* // Basic configuration
|
|
515
|
+
* const lokiTransport = new LokiTransport({
|
|
516
|
+
* url: "http://localhost:3100",
|
|
517
|
+
* labels: { app: "my-app", env: "production" }
|
|
518
|
+
* });
|
|
519
|
+
*
|
|
520
|
+
* @example
|
|
521
|
+
* // With authentication and custom batching
|
|
522
|
+
* const securedTransport = new LokiTransport({
|
|
523
|
+
* url: "http://loki.example.com",
|
|
524
|
+
* basicAuth: { username: "user", password: "pass" },
|
|
525
|
+
* batchSize: 20,
|
|
526
|
+
* batchTimeout: 10000 // 10 seconds
|
|
527
|
+
* });
|
|
316
528
|
*/
|
|
317
529
|
export declare class LokiTransport implements Transport {
|
|
318
530
|
private config;
|
|
@@ -323,19 +535,48 @@ export declare class LokiTransport implements Transport {
|
|
|
323
535
|
private maxLabelCount;
|
|
324
536
|
private debug;
|
|
325
537
|
/**
|
|
326
|
-
*
|
|
538
|
+
* Creates a new LokiTransport instance
|
|
327
539
|
* @param config Configuration options for Loki
|
|
540
|
+
* @param config.url Required Loki server URL (e.g., "http://localhost:3100")
|
|
541
|
+
* @param config.labels Base labels to attach to all log entries
|
|
542
|
+
* @param config.basicAuth Basic authentication credentials
|
|
543
|
+
* @param config.batchSize Maximum number of logs to batch before sending (default: 10)
|
|
544
|
+
* @param config.batchTimeout Maximum time (ms) to wait before sending a batch (default: 5000)
|
|
545
|
+
* @param config.tenantID Tenant ID for multi-tenant Loki setups
|
|
546
|
+
* @param config.maxLabelCount Maximum number of labels allowed (default: 50)
|
|
547
|
+
* @param config.debug Enable debug logging for transport errors (default: false)
|
|
328
548
|
* @throws {Error} If URL is not provided
|
|
329
549
|
*/
|
|
330
550
|
constructor(config: LokiConfig);
|
|
331
551
|
/**
|
|
332
|
-
*
|
|
333
|
-
*
|
|
552
|
+
* Adds a log entry to the current batch. Automatically sends the batch when:
|
|
553
|
+
* - The batch reaches the configured size, OR
|
|
554
|
+
* - The batch timeout is reached
|
|
555
|
+
*
|
|
556
|
+
* @param entry The log entry to send. Metadata will be converted to Loki labels
|
|
557
|
+
* following the configured maxLabelCount rules.
|
|
558
|
+
*
|
|
559
|
+
* @example
|
|
560
|
+
* transport.log({
|
|
561
|
+
* message: "User logged in",
|
|
562
|
+
* level: Levels.INFO,
|
|
563
|
+
* timestamp: Date.now(),
|
|
564
|
+
* metadata: { userId: "123", device: "mobile" }
|
|
565
|
+
* });
|
|
334
566
|
*/
|
|
335
567
|
log(entry: LogEntry): void;
|
|
336
568
|
/**
|
|
337
|
-
*
|
|
569
|
+
* Immediately sends the current batch of logs to Loki.
|
|
338
570
|
* @private
|
|
571
|
+
*
|
|
572
|
+
* Handles:
|
|
573
|
+
* - HTTP headers including auth and tenant ID
|
|
574
|
+
* - Batch timeout clearing
|
|
575
|
+
* - Error logging (when debug enabled)
|
|
576
|
+
* - Batch management
|
|
577
|
+
*
|
|
578
|
+
* Note: This method is called automatically by the transport
|
|
579
|
+
* and typically doesn't need to be called directly.
|
|
339
580
|
*/
|
|
340
581
|
private sendBatch;
|
|
341
582
|
}
|
package/module/logger.js
CHANGED
|
@@ -26,38 +26,68 @@ var Levels;
|
|
|
26
26
|
((Levels2) => {
|
|
27
27
|
Levels2[Levels2["ERROR"] = 0] = "ERROR";
|
|
28
28
|
Levels2[Levels2["WARN"] = 1] = "WARN";
|
|
29
|
-
Levels2[Levels2["
|
|
30
|
-
Levels2[Levels2["
|
|
31
|
-
Levels2[Levels2["
|
|
29
|
+
Levels2[Levels2["AUDIT"] = 2] = "AUDIT";
|
|
30
|
+
Levels2[Levels2["INFO"] = 3] = "INFO";
|
|
31
|
+
Levels2[Levels2["HTTP"] = 4] = "HTTP";
|
|
32
32
|
Levels2[Levels2["DEBUG"] = 5] = "DEBUG";
|
|
33
|
-
Levels2[Levels2["
|
|
33
|
+
Levels2[Levels2["VERBOSE"] = 6] = "VERBOSE";
|
|
34
|
+
Levels2[Levels2["SILLY"] = 7] = "SILLY";
|
|
34
35
|
})(Levels ||= {});
|
|
35
36
|
var LevelColors = {
|
|
36
37
|
[0 /* ERROR */]: "\x1B[31m" /* RED */,
|
|
37
38
|
[1 /* WARN */]: "\x1B[93m" /* BRIGHT_YELLOW */,
|
|
38
|
-
[2 /*
|
|
39
|
-
[3 /*
|
|
40
|
-
[4 /*
|
|
41
|
-
[5 /* DEBUG */]: "\x1B[
|
|
42
|
-
[6 /*
|
|
39
|
+
[2 /* AUDIT */]: "\x1B[35m" /* MAGENTA */,
|
|
40
|
+
[3 /* INFO */]: "\x1B[36m" /* CYAN */,
|
|
41
|
+
[4 /* HTTP */]: "\x1B[34m" /* BLUE */,
|
|
42
|
+
[5 /* DEBUG */]: "\x1B[34m" /* BLUE */,
|
|
43
|
+
[6 /* VERBOSE */]: "\x1B[90m" /* BRIGHT_BLACK */,
|
|
44
|
+
[7 /* SILLY */]: "\x1B[90m" /* BRIGHT_BLACK */
|
|
43
45
|
};
|
|
44
46
|
// src/formatters/consoleFormatter.ts
|
|
45
47
|
function formatConsoleMessage(message, logLevel, format, colorsEnabled) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
const now = new Date;
|
|
49
|
+
const type = Levels[logLevel];
|
|
50
|
+
const utcFormats = {
|
|
51
|
+
"{iso}": now.toISOString(),
|
|
52
|
+
"{datetime}": now.toISOString().split(".")[0].replace("T", " "),
|
|
53
|
+
"{time}": now.toISOString().split("T")[1].split(".")[0],
|
|
54
|
+
"{date}": now.toISOString().split("T")[0],
|
|
55
|
+
"{utc}": now.toUTCString(),
|
|
56
|
+
"{ms}": now.getTime().toString()
|
|
57
|
+
};
|
|
58
|
+
const localFormats = {
|
|
59
|
+
"{datetime-local}": now.toLocaleString("sv-SE").replace(" ", "T").split(".")[0].replace("T", " "),
|
|
60
|
+
"{time-local}": now.toLocaleTimeString("sv-SE"),
|
|
61
|
+
"{date-local}": now.toLocaleDateString("sv-SE"),
|
|
62
|
+
"{full-local}": now.toString()
|
|
63
|
+
};
|
|
64
|
+
let coloredType = type;
|
|
65
|
+
let coloredMessage = message;
|
|
48
66
|
if (colorsEnabled) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
67
|
+
const color = LevelColors[logLevel];
|
|
68
|
+
const colorize = (text) => "\x1B[90m" /* BRIGHT_BLACK */ + text + "\x1B[0m" /* RESET */;
|
|
69
|
+
Object.keys(utcFormats).forEach((key) => {
|
|
70
|
+
utcFormats[key] = colorize(utcFormats[key]);
|
|
71
|
+
});
|
|
72
|
+
Object.keys(localFormats).forEach((key) => {
|
|
73
|
+
localFormats[key] = colorize(localFormats[key]);
|
|
74
|
+
});
|
|
75
|
+
coloredType = "\x1B[1m" /* BOLD */ + color + type + "\x1B[0m" /* RESET */;
|
|
76
|
+
coloredMessage = color + message + "\x1B[0m" /* RESET */;
|
|
52
77
|
}
|
|
53
|
-
|
|
78
|
+
let output = format;
|
|
79
|
+
const allFormats = { ...utcFormats, ...localFormats };
|
|
80
|
+
for (const [placeholder, value] of Object.entries(allFormats)) {
|
|
81
|
+
output = output.replace(new RegExp(placeholder, "g"), value);
|
|
82
|
+
}
|
|
83
|
+
return output.replace(/{type}/g, coloredType).replace(/{message}/g, coloredMessage);
|
|
54
84
|
}
|
|
55
85
|
|
|
56
86
|
// src/transports/consoleTransport.ts
|
|
57
87
|
class ConsoleTransport {
|
|
58
88
|
format;
|
|
59
89
|
colors;
|
|
60
|
-
constructor(format = "[{
|
|
90
|
+
constructor(format = "[{datetime-local}] {type} {message}", colors = true) {
|
|
61
91
|
this.format = format;
|
|
62
92
|
this.colors = colors;
|
|
63
93
|
}
|
|
@@ -68,7 +98,7 @@ class ConsoleTransport {
|
|
|
68
98
|
|
|
69
99
|
// src/logger.ts
|
|
70
100
|
class Logger {
|
|
71
|
-
level =
|
|
101
|
+
level = 3 /* INFO */;
|
|
72
102
|
transports = [new ConsoleTransport];
|
|
73
103
|
constructor(config) {
|
|
74
104
|
if (config?.level !== undefined) {
|
|
@@ -102,20 +132,23 @@ class Logger {
|
|
|
102
132
|
warn(message, metadata) {
|
|
103
133
|
this.processEntry(this.createLogEntry(message, 1 /* WARN */, metadata));
|
|
104
134
|
}
|
|
135
|
+
audit(message, metadata) {
|
|
136
|
+
this.processEntry(this.createLogEntry(message, 2 /* AUDIT */, metadata));
|
|
137
|
+
}
|
|
105
138
|
info(message, metadata) {
|
|
106
|
-
this.processEntry(this.createLogEntry(message,
|
|
139
|
+
this.processEntry(this.createLogEntry(message, 3 /* INFO */, metadata));
|
|
107
140
|
}
|
|
108
141
|
http(message, metadata) {
|
|
109
|
-
this.processEntry(this.createLogEntry(message,
|
|
110
|
-
}
|
|
111
|
-
verbose(message, metadata) {
|
|
112
|
-
this.processEntry(this.createLogEntry(message, 4 /* VERBOSE */, metadata));
|
|
142
|
+
this.processEntry(this.createLogEntry(message, 4 /* HTTP */, metadata));
|
|
113
143
|
}
|
|
114
144
|
debug(message, metadata) {
|
|
115
145
|
this.processEntry(this.createLogEntry(message, 5 /* DEBUG */, metadata));
|
|
116
146
|
}
|
|
147
|
+
verbose(message, metadata) {
|
|
148
|
+
this.processEntry(this.createLogEntry(message, 6 /* VERBOSE */, metadata));
|
|
149
|
+
}
|
|
117
150
|
silly(message, metadata) {
|
|
118
|
-
this.processEntry(this.createLogEntry(message,
|
|
151
|
+
this.processEntry(this.createLogEntry(message, 7 /* SILLY */, metadata));
|
|
119
152
|
}
|
|
120
153
|
addTransport(transport) {
|
|
121
154
|
this.transports.push(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rabbit-company/logger",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "A simple and lightweight logger",
|
|
5
5
|
"main": "./module/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"logger",
|
|
32
32
|
"console",
|
|
33
33
|
"ndjson",
|
|
34
|
+
"grafana",
|
|
34
35
|
"loki"
|
|
35
36
|
],
|
|
36
37
|
"devDependencies": {
|