scribelog 1.0.3 → 1.0.5
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 +221 -1
- package/package.json +69 -69
package/README.md
CHANGED
|
@@ -111,7 +111,7 @@ Create and configure your logger using `createLogger(options?: LoggerOptions)`.
|
|
|
111
111
|
import { createLogger, format, transports } from 'scribelog';
|
|
112
112
|
|
|
113
113
|
const prodLogger = createLogger({
|
|
114
|
-
level: 'info', // Read level from environment or default to info
|
|
114
|
+
level: process.env.LOG_LEVEL || 'info', // Read level from environment or default to info
|
|
115
115
|
format: format.defaultJsonFormat, // Use predefined JSON format
|
|
116
116
|
transports: [
|
|
117
117
|
new transports.Console({
|
|
@@ -335,6 +335,226 @@ logger.info('Application running with error handlers.');
|
|
|
335
335
|
|
|
336
336
|
The logger adds `{ exception: true, eventType: '...', ...errorDetails }` to the log metadata for these events, processed by the `format.errors()` formatter. Remember to have `format.errors()` in your format chain to see detailed error info.
|
|
337
337
|
|
|
338
|
+
## 💻 Showcase
|
|
339
|
+
|
|
340
|
+
You can run this script to see how scribelog works.
|
|
341
|
+
|
|
342
|
+
<details>
|
|
343
|
+
<summary>Click to show/hide showcase.ts code</summary>
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
// showcase.ts
|
|
347
|
+
// Import everything needed from scribelog
|
|
348
|
+
import {
|
|
349
|
+
createLogger,
|
|
350
|
+
format, // Object containing formatters
|
|
351
|
+
transports, // Object containing transports
|
|
352
|
+
Logger, // Logger interface type
|
|
353
|
+
LogLevel, // Log level type ('info', 'debug', etc.)
|
|
354
|
+
LogFormat, // Formatter function type
|
|
355
|
+
Transport, // Transport interface type
|
|
356
|
+
LoggerOptions // Configuration options type
|
|
357
|
+
} from 'scribelog'; // Import from your published package
|
|
358
|
+
// Import 'process' for PID access
|
|
359
|
+
import process from 'process';
|
|
360
|
+
// Import 'crypto' for generating unique IDs
|
|
361
|
+
import crypto from 'crypto';
|
|
362
|
+
// Import 'date-fns' for custom date formatting (used in one example)
|
|
363
|
+
import { format as formatDate } from 'date-fns';
|
|
364
|
+
// Import chalk to demonstrate color control (optional for user)
|
|
365
|
+
import chalk from 'chalk';
|
|
366
|
+
|
|
367
|
+
// --- MAIN DEMO FUNCTION ---
|
|
368
|
+
async function runShowcase() {
|
|
369
|
+
console.log('\n===========================================');
|
|
370
|
+
console.log('🚀 Scribelog Showcase - All Features Demo 🚀');
|
|
371
|
+
console.log('===========================================\n');
|
|
372
|
+
|
|
373
|
+
// === 1. Basic Configuration & Levels ===
|
|
374
|
+
console.log('--- 1. Basic Configuration & Levels ---');
|
|
375
|
+
// Create a logger with a specific level. Default format is 'simple'.
|
|
376
|
+
const logger1 = createLogger({ level: 'debug' }); // Set level to 'debug' to see more logs
|
|
377
|
+
logger1.info('Logger 1 (level: debug, format: simple)');
|
|
378
|
+
logger1.warn('Warning from Logger 1');
|
|
379
|
+
logger1.debug('Debug message from Logger 1 (should appear)');
|
|
380
|
+
logger1.error('Error from Logger 1'); // Default ConsoleTransport sends this to stderr
|
|
381
|
+
|
|
382
|
+
// === 2. Different Formats ===
|
|
383
|
+
console.log('\n--- 2. Different Formats ---');
|
|
384
|
+
|
|
385
|
+
// 2a. JSON Format
|
|
386
|
+
console.log('\n--- 2a. JSON Format ---');
|
|
387
|
+
const logger2a = createLogger({
|
|
388
|
+
format: format.defaultJsonFormat, // Use the predefined JSON format (includes errors, timestamp etc.)
|
|
389
|
+
level: 'info' // Set level for this specific logger
|
|
390
|
+
});
|
|
391
|
+
logger2a.info('Log in JSON format.', { data: true, value: 123 });
|
|
392
|
+
const jsonError = new Error("JSON Formatted Error");
|
|
393
|
+
(jsonError as any).code = "E_JSON"; // Add custom error property
|
|
394
|
+
// Log an error object within metadata
|
|
395
|
+
logger2a.error('An error occurred (JSON)', { error: jsonError, user: 'admin' });
|
|
396
|
+
|
|
397
|
+
// 2b. Custom Simple Format (Colored)
|
|
398
|
+
console.log('\n--- 2b. Custom Simple Format (Colored) ---');
|
|
399
|
+
const customSimpleFormat = format.combine(
|
|
400
|
+
format.timestamp({ format: 'HH:mm:ss' }), // Custom time format only
|
|
401
|
+
format.level(), // Add level string
|
|
402
|
+
format.message(), // Add message string
|
|
403
|
+
format.metadata({ exclude: ['pid'] }), // Add other metadata, but exclude 'pid'
|
|
404
|
+
format.errors({ stack: false }), // Add error info (name, message) but no stack
|
|
405
|
+
format.simple({ colors: true }) // Force colors ON for the output string
|
|
406
|
+
);
|
|
407
|
+
const logger2b = createLogger({ format: customSimpleFormat, level: 'info' });
|
|
408
|
+
const originalChalkLevel2b = chalk.level; // Store current chalk level
|
|
409
|
+
chalk.level = 1; // Force basic colors for this demo section
|
|
410
|
+
logger2b.info('Custom simple format', { pid: 12345, user: 'demo' });
|
|
411
|
+
logger2b.error('Another error (custom simple)', { error: new Error("Simple format error") });
|
|
412
|
+
chalk.level = originalChalkLevel2b; // Restore original chalk level
|
|
413
|
+
|
|
414
|
+
// 2c. Custom JSON Format with Aliases and Nesting
|
|
415
|
+
console.log('\n--- 2c. Custom JSON Format (Aliases & Nesting) ---');
|
|
416
|
+
const customJson = format.combine(
|
|
417
|
+
format.timestamp({ alias: '@timestamp' }), // Rename timestamp field
|
|
418
|
+
format.level({ alias: 'severity' }), // Rename level field
|
|
419
|
+
format.message(), // Keep message field
|
|
420
|
+
format.errors({ stack: true }), // Include full error details + stack
|
|
421
|
+
format.metadata({ alias: 'details' }), // Nest all other metadata under 'details'
|
|
422
|
+
format.json() // Output as JSON
|
|
423
|
+
);
|
|
424
|
+
const logger2c = createLogger({ format: customJson, level: 'info' });
|
|
425
|
+
logger2c.warn('Custom JSON with nested meta', { transactionId: 'xyz', status: 'WARN' });
|
|
426
|
+
const nestedError = new Error("Nested Error");
|
|
427
|
+
nestedError.stack = "Fake stack\n at place";
|
|
428
|
+
logger2c.error("Error with nested meta", { error: nestedError, code: 503 });
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
// === 3. Multiple Transports ===
|
|
432
|
+
console.log('\n--- 3. Multiple Transports ---');
|
|
433
|
+
const originalChalkLevel3 = chalk.level; // Store current chalk level
|
|
434
|
+
chalk.level = 0; // Disable colors globally for easier comparison of output
|
|
435
|
+
const logger3 = createLogger({
|
|
436
|
+
level: 'debug', // Main logger allows all levels through
|
|
437
|
+
transports: [
|
|
438
|
+
// Transport 1: Logs 'info' and above, uses simple format, errors to stderr
|
|
439
|
+
new transports.Console({
|
|
440
|
+
level: 'info', // Transport-specific level filter
|
|
441
|
+
format: format.defaultSimpleFormat, // Use simple format (colors off due to global chalk level)
|
|
442
|
+
useStdErrLevels: ['error'] // Only 'error' level goes to stderr
|
|
443
|
+
}),
|
|
444
|
+
// Transport 2: Logs 'debug' and above, uses JSON format, warn/error to stderr
|
|
445
|
+
new transports.Console({
|
|
446
|
+
level: 'debug', // Transport-specific level filter
|
|
447
|
+
format: format.defaultJsonFormat, // Use JSON format
|
|
448
|
+
useStdErrLevels: ['warn', 'error'] // 'warn' and 'error' go to stderr
|
|
449
|
+
})
|
|
450
|
+
]
|
|
451
|
+
});
|
|
452
|
+
logger3.debug('Debug log (JSON only)'); // Only Transport 2 logs this
|
|
453
|
+
logger3.info('Info log (Simple on stdout & JSON on stdout)'); // Both transports log (both to stdout)
|
|
454
|
+
logger3.warn('Warn log (Simple on stdout & JSON on stderr)'); // Both transports log (JSON to stderr)
|
|
455
|
+
logger3.error('Error log (Simple on stderr & JSON on stderr)'); // Both transports log (both to stderr)
|
|
456
|
+
chalk.level = originalChalkLevel3; // Restore original chalk level
|
|
457
|
+
|
|
458
|
+
// === 4. Child Loggers ===
|
|
459
|
+
console.log('\n--- 4. Child Loggers ---');
|
|
460
|
+
// Parent logger setup
|
|
461
|
+
const parentLogger = createLogger({
|
|
462
|
+
level: 'debug', // Set parent level
|
|
463
|
+
format: format.simple({ colors: false }), // Use simple format without colors for clarity
|
|
464
|
+
defaultMeta: { service: 'MainService' } // Parent's default metadata
|
|
465
|
+
});
|
|
466
|
+
parentLogger.info('Parent log.'); // Contains { service: 'MainService' }
|
|
467
|
+
|
|
468
|
+
// Create first child, inheriting settings but adding 'module'
|
|
469
|
+
const childLogger1 = parentLogger.child({ module: 'ModuleA' });
|
|
470
|
+
childLogger1.info('Child 1 log.'); // Contains { service: 'MainService', module: 'ModuleA' }
|
|
471
|
+
|
|
472
|
+
// Create a child of the first child, inheriting and overriding 'module'
|
|
473
|
+
const childLogger2 = childLogger1.child({ function: 'doWork', module: 'OverrideModule' });
|
|
474
|
+
childLogger2.debug('Child 2 log (debug).', { value: 42 }); // Contains { service: 'MainService', module: 'OverrideModule', function: 'doWork', value: 42 }
|
|
475
|
+
|
|
476
|
+
// === 5. logEntry Method ===
|
|
477
|
+
console.log('\n--- 5. logEntry Method ---');
|
|
478
|
+
// Create a logger specifically for HTTP level logs
|
|
479
|
+
const entryLogger = createLogger({ level: 'http' });
|
|
480
|
+
// Use logEntry to log a pre-structured object.
|
|
481
|
+
// Scribelog will still process it through the format pipeline.
|
|
482
|
+
entryLogger.logEntry({
|
|
483
|
+
level: 'http', // Must be >= logger's level ('http')
|
|
484
|
+
message: 'Manual log entry with custom data',
|
|
485
|
+
// Add any custom fields relevant to this log
|
|
486
|
+
method: 'POST',
|
|
487
|
+
url: '/api/users',
|
|
488
|
+
statusCode: 201,
|
|
489
|
+
});
|
|
490
|
+
// Another example
|
|
491
|
+
entryLogger.logEntry({ level: 'info', message: 'This info entry will also show' }); // info > http
|
|
492
|
+
|
|
493
|
+
// === 6. Exception/Rejection Handling (Simulation) ===
|
|
494
|
+
console.log('\n--- 6. Exception/Rejection Handling (Simulating real events) ---');
|
|
495
|
+
// IMPORTANT: Set this to true ONLY if you want the script to exit upon error.
|
|
496
|
+
// Set to false for this demo to see both handlers potentially log.
|
|
497
|
+
const exitOnHandler = false;
|
|
498
|
+
let errorHandlingLogger: Logger | undefined = undefined;
|
|
499
|
+
|
|
500
|
+
console.log(`Creating logger with handleExceptions/Rejections, exitOnError: ${exitOnHandler}`);
|
|
501
|
+
errorHandlingLogger = createLogger({
|
|
502
|
+
level: 'debug', // Log everything from the handlers
|
|
503
|
+
transports: [new transports.Console({ format: format.defaultSimpleFormat })], // Use simple format for errors
|
|
504
|
+
handleExceptions: true, // Enable uncaughtException handler
|
|
505
|
+
handleRejections: true, // Enable unhandledRejection handler
|
|
506
|
+
exitOnError: exitOnHandler // Control whether process exits
|
|
507
|
+
});
|
|
508
|
+
errorHandlingLogger.info(`Error handlers active (exitOnError: ${exitOnHandler}).`);
|
|
509
|
+
|
|
510
|
+
// --- Simulate Errors ---
|
|
511
|
+
// NOTE: In a real app, these would happen unexpectedly.
|
|
512
|
+
// We use setTimeout to allow the script to reach the end and potentially remove handlers if exitOnError is false.
|
|
513
|
+
|
|
514
|
+
console.log("Simulating unhandled rejection (will be logged)...");
|
|
515
|
+
// Intentionally create an unhandled rejection
|
|
516
|
+
Promise.reject("Simulated rejection reason (handled by logger)");
|
|
517
|
+
|
|
518
|
+
console.log("Simulating uncaught exception in 100ms (will be logged)...");
|
|
519
|
+
const exceptionTimer = setTimeout(() => {
|
|
520
|
+
// Simulate an error that wasn't caught by application code
|
|
521
|
+
throw new Error("Simulated uncaught exception (handled by logger)");
|
|
522
|
+
// Note: If exitOnError were true, the process would exit shortly after logging this.
|
|
523
|
+
}, 100);
|
|
524
|
+
|
|
525
|
+
// --- Wait and Cleanup (only necessary if exitOnError is false) ---
|
|
526
|
+
if (!exitOnHandler) {
|
|
527
|
+
console.log("Waiting briefly for handlers to potentially run...");
|
|
528
|
+
await new Promise(resolve => setTimeout(resolve, 300)); // Wait longer than the exception timeout
|
|
529
|
+
|
|
530
|
+
console.log("Attempting to remove handlers (as exitOnError was false)...");
|
|
531
|
+
if (errorHandlingLogger && typeof (errorHandlingLogger as any).removeExceptionHandlers === 'function') {
|
|
532
|
+
(errorHandlingLogger as any).removeExceptionHandlers();
|
|
533
|
+
errorHandlingLogger.info('Error handlers removed.'); // Log using the same logger
|
|
534
|
+
} else {
|
|
535
|
+
console.warn('[Showcase] Could not remove error handlers (method not found?).');
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// If exitOnError was true, the script might have exited before reaching here.
|
|
540
|
+
console.log('\n===========================================');
|
|
541
|
+
console.log('✅ Scribelog Showcase Finished (Check logs above) ✅');
|
|
542
|
+
console.log('===========================================');
|
|
543
|
+
|
|
544
|
+
} // End runShowcase
|
|
545
|
+
|
|
546
|
+
// Run the main demo function
|
|
547
|
+
runShowcase().catch(e => {
|
|
548
|
+
// This catch is unlikely to be hit if handleExceptions is true,
|
|
549
|
+
// but good practice to have.
|
|
550
|
+
console.error("!!! Unexpected error running showcase:", e);
|
|
551
|
+
});
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
</details>
|
|
555
|
+
If you have any questions about scribelog or would like to know more about how to use any of the features. You can write to me on discord:
|
|
556
|
+
theonlytolon
|
|
557
|
+
|
|
338
558
|
---
|
|
339
559
|
|
|
340
560
|
## 📚 Future Work
|
package/package.json
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "scribelog",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "An advanced, configurable logger for Node.js applications.",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist",
|
|
9
|
-
"README.md",
|
|
10
|
-
"LICENSE"
|
|
11
|
-
],
|
|
12
|
-
"scripts": {
|
|
13
|
-
"build": "tsc",
|
|
14
|
-
"lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
15
|
-
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
16
|
-
"test": "jest",
|
|
17
|
-
"clean": "rimraf dist",
|
|
18
|
-
"prepublishOnly": "npm run clean && npm test && npm run lint && npm run build"
|
|
19
|
-
},
|
|
20
|
-
"keywords": [
|
|
21
|
-
"log",
|
|
22
|
-
"logs",
|
|
23
|
-
"logger",
|
|
24
|
-
"logging",
|
|
25
|
-
"typescript",
|
|
26
|
-
"node",
|
|
27
|
-
"nodejs",
|
|
28
|
-
"console",
|
|
29
|
-
"format",
|
|
30
|
-
"error",
|
|
31
|
-
"exception",
|
|
32
|
-
"scribe",
|
|
33
|
-
"scribelog"
|
|
34
|
-
],
|
|
35
|
-
"publishConfig": {
|
|
36
|
-
"access": "public"
|
|
37
|
-
},
|
|
38
|
-
"author": "tolongames",
|
|
39
|
-
"license": "MIT",
|
|
40
|
-
"devDependencies": {
|
|
41
|
-
"@types/jest": "^29.5.12",
|
|
42
|
-
"@types/node": "^20.11.24",
|
|
43
|
-
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
|
44
|
-
"@typescript-eslint/parser": "^7.1.1",
|
|
45
|
-
"eslint": "^8.57.0",
|
|
46
|
-
"eslint-config-prettier": "^9.1.0",
|
|
47
|
-
"eslint-plugin-prettier": "^5.1.3",
|
|
48
|
-
"jest": "^29.7.0",
|
|
49
|
-
"prettier": "^3.2.5",
|
|
50
|
-
"rimraf": "^6.0.1",
|
|
51
|
-
"ts-jest": "^29.1.2",
|
|
52
|
-
"typescript": "^5.3.3"
|
|
53
|
-
},
|
|
54
|
-
"repository": {
|
|
55
|
-
"type": "git",
|
|
56
|
-
"url": "git+https://github.com/tolongames/scribelog.git"
|
|
57
|
-
},
|
|
58
|
-
"bugs": {
|
|
59
|
-
"url": "https://github.com/tolongames/scribelog/issues"
|
|
60
|
-
},
|
|
61
|
-
"homepage": "https://github.com/tolongames/scribelog#readme",
|
|
62
|
-
"engines": {
|
|
63
|
-
"node": ">=16.0.0"
|
|
64
|
-
},
|
|
65
|
-
"dependencies": {
|
|
66
|
-
"chalk": "^4.1.2",
|
|
67
|
-
"date-fns": "^2.30.0"
|
|
68
|
-
}
|
|
69
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "scribelog",
|
|
3
|
+
"version": "1.0.5",
|
|
4
|
+
"description": "An advanced, configurable logger for Node.js applications.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
15
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
16
|
+
"test": "jest",
|
|
17
|
+
"clean": "rimraf dist",
|
|
18
|
+
"prepublishOnly": "npm run clean && npm test && npm run lint && npm run build"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"log",
|
|
22
|
+
"logs",
|
|
23
|
+
"logger",
|
|
24
|
+
"logging",
|
|
25
|
+
"typescript",
|
|
26
|
+
"node",
|
|
27
|
+
"nodejs",
|
|
28
|
+
"console",
|
|
29
|
+
"format",
|
|
30
|
+
"error",
|
|
31
|
+
"exception",
|
|
32
|
+
"scribe",
|
|
33
|
+
"scribelog"
|
|
34
|
+
],
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"author": "tolongames",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/jest": "^29.5.12",
|
|
42
|
+
"@types/node": "^20.11.24",
|
|
43
|
+
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
|
44
|
+
"@typescript-eslint/parser": "^7.1.1",
|
|
45
|
+
"eslint": "^8.57.0",
|
|
46
|
+
"eslint-config-prettier": "^9.1.0",
|
|
47
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
48
|
+
"jest": "^29.7.0",
|
|
49
|
+
"prettier": "^3.2.5",
|
|
50
|
+
"rimraf": "^6.0.1",
|
|
51
|
+
"ts-jest": "^29.1.2",
|
|
52
|
+
"typescript": "^5.3.3"
|
|
53
|
+
},
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "git+https://github.com/tolongames/scribelog.git"
|
|
57
|
+
},
|
|
58
|
+
"bugs": {
|
|
59
|
+
"url": "https://github.com/tolongames/scribelog/issues"
|
|
60
|
+
},
|
|
61
|
+
"homepage": "https://github.com/tolongames/scribelog#readme",
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=16.0.0"
|
|
64
|
+
},
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"chalk": "^4.1.2",
|
|
67
|
+
"date-fns": "^2.30.0"
|
|
68
|
+
}
|
|
69
|
+
}
|