fix(docs): Update README: expand documentation, examples and usage guides
This commit is contained in:
		
							
								
								
									
										10
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -1,5 +1,15 @@ | |||||||
| # Changelog | # Changelog | ||||||
|  |  | ||||||
|  | ## 2025-09-01 - 3.1.9 - fix(docs) | ||||||
|  | Update README: expand documentation, examples and usage guides | ||||||
|  |  | ||||||
|  | - Fully rewrote README to a comprehensive documentation page with badges, motivation and feature overview. | ||||||
|  | - Added Quick Start, detailed usage examples and code snippets for Smartlog, destinations, and custom destinations. | ||||||
|  | - Documented interactive console features (spinners, progress bars) including non-interactive fallbacks and configuration options. | ||||||
|  | - Expanded sections on built-in destinations (console, file, devtools, ClickHouse, receiver) with practical examples and env-driven configuration. | ||||||
|  | - Added integration examples (PM2, Docker), CLI usage, advanced features (context management, scoped logging, minimum log levels) and best practices. | ||||||
|  | - Included API reference pointers and contributing / license information. | ||||||
|  |  | ||||||
| ## 2025-05-20 - 3.1.8 - fix(devDependencies) | ## 2025-05-20 - 3.1.8 - fix(devDependencies) | ||||||
| Update devDependencies for tstest and Node types | Update devDependencies for tstest and Node types | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										814
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										814
									
								
								readme.md
									
									
									
									
									
								
							| @@ -1,286 +1,734 @@ | |||||||
| # @push.rocks/smartlog | # @push.rocks/smartlog 🚀 | ||||||
|  | *The ultimate TypeScript logging solution for modern applications* | ||||||
|  |  | ||||||
| Minimalistic distributed and extensible logging tool for TypeScript and JavaScript applications. | [](https://www.npmjs.com/package/@push.rocks/smartlog) | ||||||
|  | [](https://opensource.org/licenses/MIT) | ||||||
|  |  | ||||||
| ## Install | > **smartlog** is a powerful, distributed, and extensible logging system designed for the cloud-native era. Whether you're debugging locally, monitoring production systems, or building complex microservices, smartlog adapts to your needs with style. 🎯 | ||||||
|  |  | ||||||
| Install `@push.rocks/smartlog` using pnpm (recommended), npm, or yarn: | ## 🌟 Why smartlog? | ||||||
|  |  | ||||||
| ```sh | - **🎨 Beautiful Console Output**: Color-coded, formatted logs that are actually readable | ||||||
|  | - **🔌 Extensible Architecture**: Plug in any destination - databases, files, remote servers | ||||||
|  | - **🌍 Distributed by Design**: Built for microservices with correlation and context tracking | ||||||
|  | - **⚡ Zero-Config Start**: Works out of the box, scales when you need it | ||||||
|  | - **🎭 Interactive CLI Tools**: Spinners and progress bars that handle non-TTY environments gracefully | ||||||
|  | - **📊 Structured Logging**: JSON-based for easy parsing and analysis | ||||||
|  | - **🔍 Smart Filtering**: Log levels and context-based filtering | ||||||
|  |  | ||||||
|  | ## 📦 Installation | ||||||
|  |  | ||||||
|  | ```bash | ||||||
| # Using pnpm (recommended) | # Using pnpm (recommended) | ||||||
| pnpm add @push.rocks/smartlog | pnpm add @push.rocks/smartlog | ||||||
|  |  | ||||||
| # Using npm | # Using npm | ||||||
| npm install @push.rocks/smartlog --save | npm install @push.rocks/smartlog | ||||||
|  |  | ||||||
| # Using yarn | # Using yarn | ||||||
| yarn add @push.rocks/smartlog | yarn add @push.rocks/smartlog | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Ensure you have TypeScript and Node.js installed for TypeScript projects. | ## 🚀 Quick Start | ||||||
|  |  | ||||||
| ## Package Exports | ### Your First Logger | ||||||
|  |  | ||||||
| The package provides the following exports: |  | ||||||
|  |  | ||||||
| ```javascript |  | ||||||
| // Main module |  | ||||||
| import { Smartlog, LogGroup, ConsoleLog } from '@push.rocks/smartlog'; |  | ||||||
|  |  | ||||||
| // Type definitions and interfaces |  | ||||||
| import { ILogPackage, ILogDestination, TLogLevel } from '@push.rocks/smartlog/interfaces'; |  | ||||||
|  |  | ||||||
| // Interactive console features (spinners, progress bars) |  | ||||||
| import { SmartlogSourceInteractive, SmartlogProgressBar } from '@push.rocks/smartlog/source-interactive'; |  | ||||||
|  |  | ||||||
| // Context management |  | ||||||
| import { ... } from '@push.rocks/smartlog/context'; |  | ||||||
|  |  | ||||||
| // Log destinations |  | ||||||
| import { SmartlogDestinationClickhouse } from '@push.rocks/smartlog/destination-clickhouse'; |  | ||||||
| import { SmartlogDestinationDevtools } from '@push.rocks/smartlog/destination-devtools'; |  | ||||||
| import { SmartlogDestinationFile } from '@push.rocks/smartlog/destination-file'; |  | ||||||
| import { DestinationLocal } from '@push.rocks/smartlog/destination-local'; |  | ||||||
| import { SmartlogDestinationReceiver } from '@push.rocks/smartlog/destination-receiver'; |  | ||||||
|  |  | ||||||
| // Receiver functionality |  | ||||||
| import { SmartlogReceiver } from '@push.rocks/smartlog/receiver'; |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Usage |  | ||||||
|  |  | ||||||
| `@push.rocks/smartlog` is a flexible, extensible logging tool designed for distributed systems. It provides a consistent logging interface across different environments while being lightweight and customizable. |  | ||||||
|  |  | ||||||
| ### Creating a Logger Instance |  | ||||||
|  |  | ||||||
| Start by importing `Smartlog` and create a logger instance: |  | ||||||
|  |  | ||||||
| ```typescript | ```typescript | ||||||
| import { Smartlog } from '@push.rocks/smartlog'; | import { Smartlog } from '@push.rocks/smartlog'; | ||||||
|  |  | ||||||
|  | // Create a logger with context | ||||||
| const logger = new Smartlog({ | const logger = new Smartlog({ | ||||||
|   logContext: { |   logContext: { | ||||||
|     company: 'My Company', |     company: 'MyStartup', | ||||||
|     companyunit: 'Cloud Team', |     companyunit: 'Backend Team', | ||||||
|     containerName: 'api-service', |     containerName: 'api-gateway', | ||||||
|     environment: 'production', // 'local', 'test', 'staging', 'production' |     environment: 'production', | ||||||
|     runtime: 'node',           // 'node', 'chrome', 'rust', 'deno', 'cloudflare_workers' |     runtime: 'node', | ||||||
|     zone: 'us-west', |     zone: 'eu-central' | ||||||
|   }, |   } | ||||||
|   minimumLogLevel: 'info',     // Optional, defaults to 'silly' |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
| // Enable console output | // Enable beautiful console output | ||||||
| logger.enableConsole(); | logger.enableConsole(); | ||||||
|  |  | ||||||
|  | // Start logging! | ||||||
|  | logger.log('info', '🎉 Application started successfully'); | ||||||
|  | logger.log('error', '💥 Database connection failed', {  | ||||||
|  |   errorCode: 'DB_TIMEOUT', | ||||||
|  |   attemptCount: 3  | ||||||
|  | }); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| The context enriches logs with valuable information for filtering and analysis across distributed systems. | ### Using the Default Logger | ||||||
|  |  | ||||||
| ### Logging Messages | For quick prototyping and simple applications: | ||||||
|  |  | ||||||
| ```typescript |  | ||||||
| // Basic logging |  | ||||||
| logger.log('info', 'User authenticated successfully'); |  | ||||||
| logger.log('error', 'Database connection failed', { errorCode: 'DB_CONN_ERR', retryCount: 3 }); |  | ||||||
| logger.log('warn', 'Rate limit approaching', { currentRate: 95, limit: 100 }); |  | ||||||
|  |  | ||||||
| // Log levels: 'silly', 'info', 'debug', 'note', 'ok', 'success', 'warn', 'error', 'lifecycle' |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| The third parameter accepts any additional data to attach to the log entry. |  | ||||||
|  |  | ||||||
| ### Default Logger |  | ||||||
|  |  | ||||||
| For simple cases, use the built-in default logger: |  | ||||||
|  |  | ||||||
| ```typescript | ```typescript | ||||||
| import { defaultLogger } from '@push.rocks/smartlog'; | import { defaultLogger } from '@push.rocks/smartlog'; | ||||||
|  |  | ||||||
| defaultLogger.log('info', 'Application started'); | defaultLogger.log('info', 'This is so easy!'); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Log Groups | ## 📚 Core Concepts | ||||||
|  |  | ||||||
| Group related logs for better traceability: | ### Log Levels | ||||||
|  |  | ||||||
|  | smartlog supports semantic log levels for different scenarios: | ||||||
|  |  | ||||||
| ```typescript | ```typescript | ||||||
| // Create a log group with optional transaction ID | // Lifecycle events | ||||||
| const requestGroup = logger.createLogGroup('tx-123456'); | logger.log('lifecycle', '🔄 Container starting up...'); | ||||||
|  |  | ||||||
| // Logs within this group will be correlated | // Success states | ||||||
| requestGroup.log('info', 'Processing payment request'); | logger.log('success', '✅ Payment processed'); | ||||||
| requestGroup.log('debug', 'Validating payment details'); | logger.log('ok', '👍 Health check passed'); | ||||||
| requestGroup.log('success', 'Payment processed successfully'); |  | ||||||
|  | // Information and debugging | ||||||
|  | logger.log('info', '📋 User profile updated'); | ||||||
|  | logger.log('note', '📌 Cache invalidated'); | ||||||
|  | logger.log('debug', '🔍 Query execution plan', { sql: 'SELECT * FROM users' }); | ||||||
|  |  | ||||||
|  | // Warnings and errors | ||||||
|  | logger.log('warn', '⚠️  Memory usage above 80%'); | ||||||
|  | logger.log('error', '❌ Failed to send email'); | ||||||
|  |  | ||||||
|  | // Verbose output | ||||||
|  | logger.log('silly', '🔬 Entering function processPayment()'); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Custom Log Destinations | ### Log Groups for Correlation | ||||||
|  |  | ||||||
| Extend logging capabilities by adding custom destinations: | Perfect for tracking request flows through your system: | ||||||
|  |  | ||||||
| ```typescript | ```typescript | ||||||
| import { Smartlog, ILogDestination } from '@push.rocks/smartlog'; | // Track a user request through multiple operations | ||||||
|  | const requestGroup = logger.createLogGroup('req-7f3a2b'); | ||||||
|  |  | ||||||
| class DatabaseLogDestination implements ILogDestination { | requestGroup.log('info', 'Received POST /api/users'); | ||||||
|   async handleLog(logPackage) { | requestGroup.log('debug', 'Validating request body'); | ||||||
|     // Store log in database | requestGroup.log('info', 'Creating user in database'); | ||||||
|     await db.logs.insert({ | requestGroup.log('success', 'User created successfully', { userId: 'usr_123' }); | ||||||
|       timestamp: new Date(logPackage.timestamp), |  | ||||||
|  | // All logs in the group share the same correlation ID | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## 🎯 Log Destinations | ||||||
|  |  | ||||||
|  | ### Built-in Destinations | ||||||
|  |  | ||||||
|  | #### 🖥️ Local Console (Enhanced) | ||||||
|  |  | ||||||
|  | Beautiful, colored output for local development: | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { DestinationLocal } from '@push.rocks/smartlog/destination-local'; | ||||||
|  |  | ||||||
|  | const localDestination = new DestinationLocal({ | ||||||
|  |   logLevel: 'debug'  // Optional: filter by minimum log level | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | logger.addLogDestination(localDestination); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### 📁 File Logging | ||||||
|  |  | ||||||
|  | Persist logs to files with automatic rotation support: | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { SmartlogDestinationFile } from '@push.rocks/smartlog/destination-file'; | ||||||
|  |  | ||||||
|  | const fileDestination = new SmartlogDestinationFile('./logs/app.log'); | ||||||
|  | logger.addLogDestination(fileDestination); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### 🌐 Browser DevTools | ||||||
|  |  | ||||||
|  | Optimized for browser environments with styled console output: | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { SmartlogDestinationDevtools } from '@push.rocks/smartlog/destination-devtools'; | ||||||
|  |  | ||||||
|  | const devtools = new SmartlogDestinationDevtools(); | ||||||
|  | logger.addLogDestination(devtools); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### 📊 ClickHouse Analytics | ||||||
|  |  | ||||||
|  | Store logs in ClickHouse for powerful analytics: | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { SmartlogDestinationClickhouse } from '@push.rocks/smartlog/destination-clickhouse'; | ||||||
|  |  | ||||||
|  | const clickhouse = await SmartlogDestinationClickhouse.createAndStart({ | ||||||
|  |   host: 'analytics.example.com', | ||||||
|  |   port: 8123, | ||||||
|  |   database: 'logs', | ||||||
|  |   user: 'logger', | ||||||
|  |   password: process.env.CLICKHOUSE_PASSWORD | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | logger.addLogDestination(clickhouse); | ||||||
|  |  | ||||||
|  | // Query your logs with SQL! | ||||||
|  | // SELECT * FROM logs WHERE level = 'error' AND timestamp > now() - INTERVAL 1 HOUR | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### 🔗 Remote Receiver | ||||||
|  |  | ||||||
|  | Send logs to a centralized logging service: | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { SmartlogDestinationReceiver } from '@push.rocks/smartlog/destination-receiver'; | ||||||
|  |  | ||||||
|  | const receiver = new SmartlogDestinationReceiver({ | ||||||
|  |   endpoint: 'https://logs.mycompany.com/ingest', | ||||||
|  |   apiKey: process.env.LOG_API_KEY, | ||||||
|  |   batchSize: 100,  // Send logs in batches | ||||||
|  |   flushInterval: 5000  // Flush every 5 seconds | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | logger.addLogDestination(receiver); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### 🛠️ Custom Destinations | ||||||
|  |  | ||||||
|  | Build your own destination for any logging backend: | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { ILogDestination, ILogPackage } from '@push.rocks/smartlog/interfaces'; | ||||||
|  |  | ||||||
|  | class ElasticsearchDestination implements ILogDestination { | ||||||
|  |   private client: ElasticsearchClient; | ||||||
|  |  | ||||||
|  |   constructor(config: ElasticsearchConfig) { | ||||||
|  |     this.client = new ElasticsearchClient(config); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async handleLog(logPackage: ILogPackage): Promise<void> { | ||||||
|  |     await this.client.index({ | ||||||
|  |       index: `logs-${new Date().toISOString().split('T')[0]}`, | ||||||
|  |       body: { | ||||||
|  |         '@timestamp': logPackage.timestamp, | ||||||
|         level: logPackage.level, |         level: logPackage.level, | ||||||
|         message: logPackage.message, |         message: logPackage.message, | ||||||
|  |         context: logPackage.context, | ||||||
|         data: logPackage.data, |         data: logPackage.data, | ||||||
|       context: logPackage.context |         correlation: logPackage.correlation | ||||||
|  |       } | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| // Add the custom destination to your logger | // Use your custom destination | ||||||
| logger.addLogDestination(new DatabaseLogDestination()); | logger.addLogDestination(new ElasticsearchDestination({ | ||||||
| ``` |   node: 'https://elasticsearch.example.com' | ||||||
|  |  | ||||||
| ### Built-in Destinations |  | ||||||
|  |  | ||||||
| SmartLog comes with several built-in destinations for various logging needs: |  | ||||||
|  |  | ||||||
| ```typescript |  | ||||||
| // Log to a file |  | ||||||
| import { SmartlogDestinationFile } from '@push.rocks/smartlog/destination-file'; |  | ||||||
| logger.addLogDestination(new SmartlogDestinationFile('/path/to/logfile.log')); |  | ||||||
|  |  | ||||||
| // Colorful local console logging |  | ||||||
| import { DestinationLocal } from '@push.rocks/smartlog/destination-local'; |  | ||||||
| logger.addLogDestination(new DestinationLocal()); |  | ||||||
|  |  | ||||||
| // Browser DevTools with colored formatting |  | ||||||
| import { SmartlogDestinationDevtools } from '@push.rocks/smartlog/destination-devtools'; |  | ||||||
| logger.addLogDestination(new SmartlogDestinationDevtools()); |  | ||||||
|  |  | ||||||
| // ClickHouse database logging |  | ||||||
| import { SmartlogDestinationClickhouse } from '@push.rocks/smartlog/destination-clickhouse'; |  | ||||||
| const clickhouse = await SmartlogDestinationClickhouse.createAndStart({ |  | ||||||
|   host: 'clickhouse.example.com', |  | ||||||
|   port: 8123, |  | ||||||
|   user: 'username', |  | ||||||
|   password: 'password', |  | ||||||
|   database: 'logs_db' |  | ||||||
| }); |  | ||||||
| logger.addLogDestination(clickhouse); |  | ||||||
|  |  | ||||||
| // Remote receiver logging |  | ||||||
| import { SmartlogDestinationReceiver } from '@push.rocks/smartlog/destination-receiver'; |  | ||||||
| logger.addLogDestination(new SmartlogDestinationReceiver({ |  | ||||||
|   endpoint: 'https://logs.example.com/api/logs' |  | ||||||
| })); | })); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Interactive Console Features | ## 🎨 Interactive Console Features | ||||||
|  |  | ||||||
| For CLI applications, use the interactive console features: | ### Spinners | ||||||
|  |  | ||||||
|  | Create beautiful loading animations that degrade gracefully in CI/CD: | ||||||
|  |  | ||||||
| ```typescript | ```typescript | ||||||
| import { SmartlogSourceInteractive, SmartlogProgressBar } from '@push.rocks/smartlog/source-interactive'; | import { SmartlogSourceInteractive } from '@push.rocks/smartlog/source-interactive'; | ||||||
| ``` |  | ||||||
|  |  | ||||||
| #### Spinners |  | ||||||
|  |  | ||||||
| ```typescript |  | ||||||
| const spinner = new SmartlogSourceInteractive(); | const spinner = new SmartlogSourceInteractive(); | ||||||
|  |  | ||||||
| // Start a spinner with text | // Basic usage | ||||||
| spinner.text('Loading data...'); | spinner.text('🔄 Fetching data from API...'); | ||||||
|  | // ... perform async operation | ||||||
|  | spinner.finishSuccess('✅ Data fetched successfully!'); | ||||||
|  |  | ||||||
|  | // Chained operations | ||||||
|  | spinner | ||||||
|  |   .text('📡 Connecting to database') | ||||||
|  |   .successAndNext('🔍 Running migrations') | ||||||
|  |   .successAndNext('🌱 Seeding data') | ||||||
|  |   .finishSuccess('🎉 Database ready!'); | ||||||
|  |  | ||||||
| // Customize appearance | // Customize appearance | ||||||
| spinner.setSpinnerStyle('dots');  // 'dots', 'line', 'star', 'simple' | spinner | ||||||
| spinner.setColor('blue');         // 'red', 'green', 'yellow', 'blue', etc. |   .setSpinnerStyle('dots')  // dots, line, star, simple | ||||||
| spinner.setSpeed(80);             // Animation speed in milliseconds |   .setColor('cyan')         // any terminal color | ||||||
|  |   .setSpeed(80)            // animation speed in ms | ||||||
|  |   .text('🚀 Deploying application...'); | ||||||
|  |  | ||||||
| // Update spinner status | // Handle failures | ||||||
| spinner.text('Processing records...'); | try { | ||||||
|  |   await deployApp(); | ||||||
| // Complete with success or failure |   spinner.finishSuccess('✅ Deployed!'); | ||||||
| spinner.finishSuccess('Data loaded successfully!'); | } catch (error) { | ||||||
| spinner.finishFail('Failed to load data!'); |   spinner.finishFail('❌ Deployment failed'); | ||||||
|  | } | ||||||
| // Chain operations |  | ||||||
| spinner.text('Connecting to server') |  | ||||||
|   .successAndNext('Fetching records') |  | ||||||
|   .successAndNext('Processing data') |  | ||||||
|   .finishSuccess('All done!'); |  | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| #### Progress Bars | ### Progress Bars | ||||||
|  |  | ||||||
|  | Track long-running operations with style: | ||||||
|  |  | ||||||
| ```typescript | ```typescript | ||||||
| const progressBar = new SmartlogProgressBar({ | import { SmartlogProgressBar } from '@push.rocks/smartlog/source-interactive'; | ||||||
|   total: 100,                // Total number of items |  | ||||||
|   width: 40,                 // Width of the progress bar | // Create a progress bar | ||||||
|   complete: '█',             // Character for completed section | const progress = new SmartlogProgressBar({ | ||||||
|   incomplete: '░',           // Character for incomplete section |   total: 100, | ||||||
|   showEta: true,             // Show estimated time remaining |   width: 40, | ||||||
|   showPercent: true,         // Show percentage |   complete: '█', | ||||||
|   showCount: true            // Show count (e.g., "50/100") |   incomplete: '░', | ||||||
|  |   showEta: true, | ||||||
|  |   showPercent: true, | ||||||
|  |   showCount: true | ||||||
| }); | }); | ||||||
|  |  | ||||||
| // Update progress | // Update progress | ||||||
| progressBar.update(25);      // Set to 25% progress | for (let i = 0; i <= 100; i++) { | ||||||
|  |   progress.update(i); | ||||||
|  |   await someAsyncWork(); | ||||||
|  | } | ||||||
|  |  | ||||||
| // Increment progress | progress.complete(); | ||||||
| progressBar.increment(5);    // Increase by 5 units |  | ||||||
|  |  | ||||||
| // Change color | // Real-world example: Processing files | ||||||
| progressBar.setColor('blue'); | const files = await getFiles(); | ||||||
|  | const progress = new SmartlogProgressBar({ | ||||||
|  |   total: files.length, | ||||||
|  |   width: 50 | ||||||
|  | }); | ||||||
|  |  | ||||||
| // Complete the progress bar | for (const [index, file] of files.entries()) { | ||||||
| progressBar.complete(); |   await processFile(file); | ||||||
|  |   progress.increment();  // or progress.update(index + 1) | ||||||
|  | } | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| #### Non-Interactive Environments | ### Non-Interactive Fallback | ||||||
|  |  | ||||||
| Both spinners and progress bars automatically detect non-interactive environments (CI/CD, piped output) and fallback to plain text logging: | Both spinners and progress bars automatically detect non-interactive environments (CI/CD, Docker logs, piped output) and fallback to simple text output: | ||||||
|  |  | ||||||
| ``` | ``` | ||||||
| [Loading] Connecting to server | [Loading] Connecting to database | ||||||
| [Success] Connected to server | [Success] Connected to database | ||||||
| [Loading] Fetching records | [Loading] Running migrations | ||||||
|  | Progress: 25% (25/100) | ||||||
| Progress: 50% (50/100) | Progress: 50% (50/100) | ||||||
| Progress: 100% (100/100) | Progress: 100% (100/100) | ||||||
| [Success] Fetching complete | [Success] Migrations complete | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## Advanced Usage | ## 🔧 Advanced Features | ||||||
|  |  | ||||||
| ### Capturing All Console Output | ### Context Management | ||||||
|  |  | ||||||
| Capture all `console.log` and `console.error` output through Smartlog: | Add context that flows through your entire application: | ||||||
|  |  | ||||||
| ```typescript | ```typescript | ||||||
| logger.enableConsole({ captureAll: true }); | // Set global context | ||||||
|  | logger.addLogContext({ | ||||||
|  |   requestId: 'req-123', | ||||||
|  |   userId: 'user-456', | ||||||
|  |   feature: 'payment-processing' | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // All subsequent logs include this context | ||||||
|  | logger.log('info', 'Processing payment'); | ||||||
|  | // Output includes: { ...context, message: 'Processing payment' } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Scoped Logging | ||||||
|  |  | ||||||
|  | Create scoped loggers for different components: | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | const dbLogger = logger.createScope('database'); | ||||||
|  | const apiLogger = logger.createScope('api'); | ||||||
|  |  | ||||||
|  | dbLogger.log('info', 'Executing query'); | ||||||
|  | apiLogger.log('info', 'Handling request'); | ||||||
|  | // Logs include scope information for filtering | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Minimum Log Levels | ||||||
|  |  | ||||||
|  | Control log verbosity per environment: | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | const logger = new Smartlog({ | ||||||
|  |   logContext: { environment: 'production' }, | ||||||
|  |   minimumLogLevel: 'warn'  // Only warn and above in production | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // These won't be logged in production | ||||||
|  | logger.log('debug', 'Detailed debug info'); | ||||||
|  | logger.log('info', 'Regular info'); | ||||||
|  |  | ||||||
|  | // These will be logged | ||||||
|  | logger.log('warn', 'Warning message'); | ||||||
|  | logger.log('error', 'Error message'); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Increment Logging | ### Increment Logging | ||||||
|  |  | ||||||
| For metrics and counters: | Perfect for metrics and counters: | ||||||
|  |  | ||||||
| ```typescript | ```typescript | ||||||
| logger.increment('info', 'api_requests', { endpoint: '/users' }); | // Track API calls | ||||||
|  | logger.increment('info', 'api.requests', { endpoint: '/users', method: 'GET' }); | ||||||
|  | logger.increment('info', 'api.requests', { endpoint: '/users', method: 'POST' }); | ||||||
|  |  | ||||||
|  | // Track errors by type | ||||||
|  | logger.increment('error', 'payment.failed', { reason: 'insufficient_funds' }); | ||||||
|  | logger.increment('error', 'payment.failed', { reason: 'card_declined' }); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Log Correlation | ### Capture All Console Output | ||||||
|  |  | ||||||
| Correlate logs across services with correlation IDs: | Redirect all console.log and console.error through smartlog: | ||||||
|  |  | ||||||
| ```typescript | ```typescript | ||||||
| logger.log('info', 'Request received', { userId: 'user-123' }, { | logger.enableConsole({  | ||||||
|   id: 'req-abc-123', |   captureAll: true  // Capture all console.* methods | ||||||
|   type: 'service', | }); | ||||||
|   transaction: 'tx-payment-456' |  | ||||||
|  | console.log('This goes through smartlog!'); | ||||||
|  | console.error('This too!'); | ||||||
|  | // All console output is now structured and routed through your destinations | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## 🏗️ Real-World Examples | ||||||
|  |  | ||||||
|  | ### Microservice with Distributed Tracing | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Smartlog } from '@push.rocks/smartlog'; | ||||||
|  | import { SmartlogDestinationClickhouse } from '@push.rocks/smartlog/destination-clickhouse'; | ||||||
|  |  | ||||||
|  | // Initialize logger with service context | ||||||
|  | const logger = new Smartlog({ | ||||||
|  |   logContext: { | ||||||
|  |     company: 'TechCorp', | ||||||
|  |     companyunit: 'Platform', | ||||||
|  |     containerName: 'user-service', | ||||||
|  |     environment: process.env.NODE_ENV, | ||||||
|  |     runtime: 'node', | ||||||
|  |     zone: process.env.CLOUD_ZONE | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // Add ClickHouse for analytics | ||||||
|  | const clickhouse = await SmartlogDestinationClickhouse.createAndStart({ | ||||||
|  |   host: process.env.CLICKHOUSE_HOST, | ||||||
|  |   database: 'microservices_logs' | ||||||
|  | }); | ||||||
|  | logger.addLogDestination(clickhouse); | ||||||
|  |  | ||||||
|  | // Enable local console for development | ||||||
|  | if (process.env.NODE_ENV === 'development') { | ||||||
|  |   logger.enableConsole(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Express middleware for request tracking | ||||||
|  | app.use((req, res, next) => { | ||||||
|  |   const requestId = generateRequestId(); | ||||||
|  |   const logGroup = logger.createLogGroup(requestId); | ||||||
|  |    | ||||||
|  |   // Attach logger to request | ||||||
|  |   req.logger = logGroup; | ||||||
|  |    | ||||||
|  |   // Log request | ||||||
|  |   logGroup.log('info', 'Incoming request', { | ||||||
|  |     method: req.method, | ||||||
|  |     path: req.path, | ||||||
|  |     ip: req.ip | ||||||
|  |   }); | ||||||
|  |    | ||||||
|  |   // Track response | ||||||
|  |   res.on('finish', () => { | ||||||
|  |     logGroup.log('info', 'Request completed', { | ||||||
|  |       statusCode: res.statusCode, | ||||||
|  |       duration: Date.now() - req.startTime | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  |    | ||||||
|  |   next(); | ||||||
| }); | }); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## API Documentation | ### CLI Tool with Progress Tracking | ||||||
|  |  | ||||||
| For detailed API documentation, see the [API.md](API.md) file. | ```typescript | ||||||
|  | import { Smartlog } from '@push.rocks/smartlog'; | ||||||
|  | import { SmartlogSourceInteractive, SmartlogProgressBar } from '@push.rocks/smartlog/source-interactive'; | ||||||
|  |  | ||||||
| ## License and Legal Information | const logger = new Smartlog({ | ||||||
|  |   logContext: { | ||||||
|  |     containerName: 'migration-tool', | ||||||
|  |     environment: 'cli' | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | logger.enableConsole(); | ||||||
|  |  | ||||||
|  | async function migrateDatabase() { | ||||||
|  |   const spinner = new SmartlogSourceInteractive(); | ||||||
|  |    | ||||||
|  |   // Connect to database | ||||||
|  |   spinner.text('🔌 Connecting to database...'); | ||||||
|  |   await connectDB(); | ||||||
|  |   spinner.finishSuccess('✅ Connected to database'); | ||||||
|  |    | ||||||
|  |   // Get migrations | ||||||
|  |   spinner.text('📋 Loading migrations...'); | ||||||
|  |   const migrations = await getMigrations(); | ||||||
|  |   spinner.finishSuccess(`✅ Found ${migrations.length} migrations`); | ||||||
|  |    | ||||||
|  |   // Run migrations with progress bar | ||||||
|  |   const progress = new SmartlogProgressBar({ | ||||||
|  |     total: migrations.length, | ||||||
|  |     width: 40, | ||||||
|  |     showEta: true | ||||||
|  |   }); | ||||||
|  |    | ||||||
|  |   for (const [index, migration] of migrations.entries()) { | ||||||
|  |     logger.log('info', `Running migration: ${migration.name}`); | ||||||
|  |     await runMigration(migration); | ||||||
|  |     progress.update(index + 1); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   progress.complete(); | ||||||
|  |   logger.log('success', '🎉 All migrations completed successfully!'); | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Production Logging with Multiple Destinations | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Smartlog } from '@push.rocks/smartlog'; | ||||||
|  | import { DestinationLocal } from '@push.rocks/smartlog/destination-local'; | ||||||
|  | import { SmartlogDestinationFile } from '@push.rocks/smartlog/destination-file'; | ||||||
|  | import { SmartlogDestinationReceiver } from '@push.rocks/smartlog/destination-receiver'; | ||||||
|  |  | ||||||
|  | const logger = new Smartlog({ | ||||||
|  |   logContext: { | ||||||
|  |     company: 'Enterprise Corp', | ||||||
|  |     containerName: 'payment-processor', | ||||||
|  |     environment: 'production', | ||||||
|  |     runtime: 'node', | ||||||
|  |     zone: 'us-east-1' | ||||||
|  |   }, | ||||||
|  |   minimumLogLevel: 'info'  // No debug logs in production | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // Console for container logs (structured for log aggregators) | ||||||
|  | logger.addLogDestination(new DestinationLocal()); | ||||||
|  |  | ||||||
|  | // File for audit trail | ||||||
|  | logger.addLogDestination(new SmartlogDestinationFile('/var/log/app/audit.log')); | ||||||
|  |  | ||||||
|  | // Central logging service | ||||||
|  | logger.addLogDestination(new SmartlogDestinationReceiver({ | ||||||
|  |   endpoint: 'https://logs.enterprise.com/ingest', | ||||||
|  |   apiKey: process.env.LOG_API_KEY, | ||||||
|  |   batchSize: 100, | ||||||
|  |   flushInterval: 5000 | ||||||
|  | })); | ||||||
|  |  | ||||||
|  | // Critical error alerts | ||||||
|  | logger.addLogDestination({ | ||||||
|  |   async handleLog(logPackage) { | ||||||
|  |     if (logPackage.level === 'error' && logPackage.data?.critical) { | ||||||
|  |       await sendAlert({ | ||||||
|  |         channel: 'ops-team', | ||||||
|  |         message: `🚨 Critical error: ${logPackage.message}`, | ||||||
|  |         data: logPackage | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## 🔌 Integration with Other Tools | ||||||
|  |  | ||||||
|  | ### PM2 Integration | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | // ecosystem.config.js | ||||||
|  | module.exports = { | ||||||
|  |   apps: [{ | ||||||
|  |     name: 'api', | ||||||
|  |     script: './dist/index.js', | ||||||
|  |     error_file: '/dev/null',  // Disable PM2 error log | ||||||
|  |     out_file: '/dev/null',    // Disable PM2 out log | ||||||
|  |     merge_logs: true, | ||||||
|  |     env: { | ||||||
|  |       NODE_ENV: 'production', | ||||||
|  |       // smartlog handles all logging | ||||||
|  |     } | ||||||
|  |   }] | ||||||
|  | }; | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Docker Integration | ||||||
|  |  | ||||||
|  | ```dockerfile | ||||||
|  | FROM node:18-alpine | ||||||
|  | WORKDIR /app | ||||||
|  | COPY . . | ||||||
|  | RUN pnpm install --production | ||||||
|  |  | ||||||
|  | # smartlog handles structured logging | ||||||
|  | # No need for special log drivers | ||||||
|  | CMD ["node", "dist/index.js"] | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | # docker-compose.yml | ||||||
|  | services: | ||||||
|  |   app: | ||||||
|  |     build: . | ||||||
|  |     environment: | ||||||
|  |       - NODE_ENV=production | ||||||
|  |     # Logs are structured JSON, perfect for log aggregators | ||||||
|  |     logging: | ||||||
|  |       driver: "json-file" | ||||||
|  |       options: | ||||||
|  |         max-size: "10m" | ||||||
|  |         max-file: "3" | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## 🏆 Best Practices | ||||||
|  |  | ||||||
|  | ### 1. Use Semantic Log Levels | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | // ✅ Good - semantic and meaningful | ||||||
|  | logger.log('lifecycle', 'Server starting on port 3000'); | ||||||
|  | logger.log('success', 'Database connection established'); | ||||||
|  | logger.log('error', 'Failed to process payment', { orderId, error }); | ||||||
|  |  | ||||||
|  | // ❌ Bad - everything is 'info' | ||||||
|  | logger.log('info', 'Server starting'); | ||||||
|  | logger.log('info', 'Database connected'); | ||||||
|  | logger.log('info', 'Error: payment failed'); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### 2. Include Structured Data | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | // ✅ Good - structured data for analysis | ||||||
|  | logger.log('error', 'API request failed', { | ||||||
|  |   endpoint: '/api/users', | ||||||
|  |   statusCode: 500, | ||||||
|  |   duration: 1234, | ||||||
|  |   userId: 'usr_123', | ||||||
|  |   errorCode: 'INTERNAL_ERROR' | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // ❌ Bad - data embedded in message | ||||||
|  | logger.log('error', `API request to /api/users failed with 500 in 1234ms for user usr_123`); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### 3. Use Log Groups for Correlation | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | // ✅ Good - correlated logs | ||||||
|  | async function processOrder(orderId: string) { | ||||||
|  |   const logGroup = logger.createLogGroup(orderId); | ||||||
|  |    | ||||||
|  |   logGroup.log('info', 'Processing order'); | ||||||
|  |   logGroup.log('debug', 'Validating items'); | ||||||
|  |   logGroup.log('info', 'Charging payment'); | ||||||
|  |   logGroup.log('success', 'Order processed'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ❌ Bad - no correlation | ||||||
|  | async function processOrder(orderId: string) { | ||||||
|  |   logger.log('info', `Processing order ${orderId}`); | ||||||
|  |   logger.log('debug', `Validating items for ${orderId}`); | ||||||
|  |   logger.log('info', `Charging payment for ${orderId}`); | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### 4. Environment-Specific Configuration | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | // ✅ Good - different configs per environment | ||||||
|  | const logger = new Smartlog({ | ||||||
|  |   logContext: { | ||||||
|  |     environment: process.env.NODE_ENV, | ||||||
|  |     // ... other context | ||||||
|  |   }, | ||||||
|  |   minimumLogLevel: process.env.NODE_ENV === 'production' ? 'info' : 'silly' | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // Add destinations based on environment | ||||||
|  | if (process.env.NODE_ENV === 'production') { | ||||||
|  |   logger.addLogDestination(clickhouseDestination); | ||||||
|  |   logger.addLogDestination(alertingDestination); | ||||||
|  | } else { | ||||||
|  |   logger.enableConsole(); | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## 📖 API Reference | ||||||
|  |  | ||||||
|  | ### Smartlog Class | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | class Smartlog { | ||||||
|  |   constructor(options?: ISmartlogOptions) | ||||||
|  |    | ||||||
|  |   // Logging methods | ||||||
|  |   log(level: TLogLevel, message: string, data?: any, correlation?: ILogCorrelation): void | ||||||
|  |   increment(level: TLogLevel, key: string, data?: any): void | ||||||
|  |    | ||||||
|  |   // Configuration | ||||||
|  |   enableConsole(options?: IConsoleOptions): void | ||||||
|  |   addLogDestination(destination: ILogDestination): void | ||||||
|  |   addLogContext(context: Partial<ILogContext>): void | ||||||
|  |    | ||||||
|  |   // Log groups | ||||||
|  |   createLogGroup(transactionId?: string): LogGroup | ||||||
|  |   createScope(scopeName: string): Smartlog | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Log Levels | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | type TLogLevel =  | ||||||
|  |   | 'silly'      // Very verbose debugging | ||||||
|  |   | 'debug'      // Debug information | ||||||
|  |   | 'info'       // Informational messages | ||||||
|  |   | 'note'       // Notable events | ||||||
|  |   | 'ok'         // Success confirmation | ||||||
|  |   | 'success'    // Major success | ||||||
|  |   | 'warn'       // Warning messages | ||||||
|  |   | 'error'      // Error messages | ||||||
|  |   | 'lifecycle'  // Application lifecycle events | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Log Package Structure | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | interface ILogPackage { | ||||||
|  |   timestamp: number; | ||||||
|  |   level: TLogLevel; | ||||||
|  |   message: string; | ||||||
|  |   data?: any; | ||||||
|  |   context: ILogContext; | ||||||
|  |   correlation?: ILogCorrelation; | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | For complete API documentation, see [API.md](API.md). | ||||||
|  |  | ||||||
|  | ## 🤝 Contributing | ||||||
|  |  | ||||||
|  | We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. | ||||||
|  |  | ||||||
|  | ## 📄 License and Legal Information | ||||||
|  |  | ||||||
| This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.  | This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,6 +3,6 @@ | |||||||
|  */ |  */ | ||||||
| export const commitinfo = { | export const commitinfo = { | ||||||
|   name: '@push.rocks/smartlog', |   name: '@push.rocks/smartlog', | ||||||
|   version: '3.1.8', |   version: '3.1.9', | ||||||
|   description: 'A minimalistic, distributed, and extensible logging tool supporting centralized log management.' |   description: 'A minimalistic, distributed, and extensible logging tool supporting centralized log management.' | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user