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 | ||||
|  | ||||
| ## 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) | ||||
| Update devDependencies for tstest and Node types | ||||
|  | ||||
|   | ||||
							
								
								
									
										820
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										820
									
								
								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) | ||||
| pnpm add @push.rocks/smartlog | ||||
|  | ||||
| # Using npm | ||||
| npm install @push.rocks/smartlog --save | ||||
| npm install @push.rocks/smartlog | ||||
|  | ||||
| # Using yarn | ||||
| yarn add @push.rocks/smartlog | ||||
| ``` | ||||
|  | ||||
| Ensure you have TypeScript and Node.js installed for TypeScript projects. | ||||
| ## 🚀 Quick Start | ||||
|  | ||||
| ## Package Exports | ||||
|  | ||||
| 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: | ||||
| ### Your First Logger | ||||
|  | ||||
| ```typescript | ||||
| import { Smartlog } from '@push.rocks/smartlog'; | ||||
|  | ||||
| // Create a logger with context | ||||
| const logger = new Smartlog({ | ||||
|   logContext: { | ||||
|     company: 'My Company', | ||||
|     companyunit: 'Cloud Team', | ||||
|     containerName: 'api-service', | ||||
|     environment: 'production', // 'local', 'test', 'staging', 'production' | ||||
|     runtime: 'node',           // 'node', 'chrome', 'rust', 'deno', 'cloudflare_workers' | ||||
|     zone: 'us-west', | ||||
|   }, | ||||
|   minimumLogLevel: 'info',     // Optional, defaults to 'silly' | ||||
|     company: 'MyStartup', | ||||
|     companyunit: 'Backend Team', | ||||
|     containerName: 'api-gateway', | ||||
|     environment: 'production', | ||||
|     runtime: 'node', | ||||
|     zone: 'eu-central' | ||||
|   } | ||||
| }); | ||||
|  | ||||
| // Enable console output | ||||
| // Enable beautiful console output | ||||
| 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 | ||||
|  | ||||
| ```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: | ||||
| For quick prototyping and simple applications: | ||||
|  | ||||
| ```typescript | ||||
| 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 | ||||
| // Create a log group with optional transaction ID | ||||
| const requestGroup = logger.createLogGroup('tx-123456'); | ||||
| // Lifecycle events | ||||
| logger.log('lifecycle', '🔄 Container starting up...'); | ||||
|  | ||||
| // Logs within this group will be correlated | ||||
| requestGroup.log('info', 'Processing payment request'); | ||||
| requestGroup.log('debug', 'Validating payment details'); | ||||
| requestGroup.log('success', 'Payment processed successfully'); | ||||
| // Success states | ||||
| logger.log('success', '✅ Payment processed'); | ||||
| logger.log('ok', '👍 Health check passed'); | ||||
|  | ||||
| // 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 | ||||
| import { Smartlog, ILogDestination } from '@push.rocks/smartlog'; | ||||
| // Track a user request through multiple operations | ||||
| const requestGroup = logger.createLogGroup('req-7f3a2b'); | ||||
|  | ||||
| class DatabaseLogDestination implements ILogDestination { | ||||
|   async handleLog(logPackage) { | ||||
|     // Store log in database | ||||
|     await db.logs.insert({ | ||||
|       timestamp: new Date(logPackage.timestamp), | ||||
|       level: logPackage.level, | ||||
|       message: logPackage.message, | ||||
|       data: logPackage.data, | ||||
|       context: logPackage.context | ||||
| requestGroup.log('info', 'Received POST /api/users'); | ||||
| requestGroup.log('debug', 'Validating request body'); | ||||
| requestGroup.log('info', 'Creating user in database'); | ||||
| requestGroup.log('success', 'User created successfully', { userId: 'usr_123' }); | ||||
|  | ||||
| // 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, | ||||
|         message: logPackage.message, | ||||
|         context: logPackage.context, | ||||
|         data: logPackage.data, | ||||
|         correlation: logPackage.correlation | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Add the custom destination to your logger | ||||
| logger.addLogDestination(new DatabaseLogDestination()); | ||||
| ``` | ||||
|  | ||||
| ### 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' | ||||
| // Use your custom destination | ||||
| logger.addLogDestination(new ElasticsearchDestination({ | ||||
|   node: 'https://elasticsearch.example.com' | ||||
| })); | ||||
| ``` | ||||
|  | ||||
| ### 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 | ||||
| import { SmartlogSourceInteractive, SmartlogProgressBar } from '@push.rocks/smartlog/source-interactive'; | ||||
| ``` | ||||
| import { SmartlogSourceInteractive } from '@push.rocks/smartlog/source-interactive'; | ||||
|  | ||||
| #### Spinners | ||||
|  | ||||
| ```typescript | ||||
| const spinner = new SmartlogSourceInteractive(); | ||||
|  | ||||
| // Start a spinner with text | ||||
| spinner.text('Loading data...'); | ||||
| // Basic usage | ||||
| 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 | ||||
| spinner.setSpinnerStyle('dots');  // 'dots', 'line', 'star', 'simple' | ||||
| spinner.setColor('blue');         // 'red', 'green', 'yellow', 'blue', etc. | ||||
| spinner.setSpeed(80);             // Animation speed in milliseconds | ||||
| spinner | ||||
|   .setSpinnerStyle('dots')  // dots, line, star, simple | ||||
|   .setColor('cyan')         // any terminal color | ||||
|   .setSpeed(80)            // animation speed in ms | ||||
|   .text('🚀 Deploying application...'); | ||||
|  | ||||
| // Update spinner status | ||||
| spinner.text('Processing records...'); | ||||
|  | ||||
| // Complete with success or failure | ||||
| spinner.finishSuccess('Data loaded successfully!'); | ||||
| spinner.finishFail('Failed to load data!'); | ||||
|  | ||||
| // Chain operations | ||||
| spinner.text('Connecting to server') | ||||
|   .successAndNext('Fetching records') | ||||
|   .successAndNext('Processing data') | ||||
|   .finishSuccess('All done!'); | ||||
| // Handle failures | ||||
| try { | ||||
|   await deployApp(); | ||||
|   spinner.finishSuccess('✅ Deployed!'); | ||||
| } catch (error) { | ||||
|   spinner.finishFail('❌ Deployment failed'); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| #### Progress Bars | ||||
| ### Progress Bars | ||||
|  | ||||
| Track long-running operations with style: | ||||
|  | ||||
| ```typescript | ||||
| const progressBar = new SmartlogProgressBar({ | ||||
|   total: 100,                // Total number of items | ||||
|   width: 40,                 // Width of the progress bar | ||||
|   complete: '█',             // Character for completed section | ||||
|   incomplete: '░',           // Character for incomplete section | ||||
|   showEta: true,             // Show estimated time remaining | ||||
|   showPercent: true,         // Show percentage | ||||
|   showCount: true            // Show count (e.g., "50/100") | ||||
| import { SmartlogProgressBar } from '@push.rocks/smartlog/source-interactive'; | ||||
|  | ||||
| // Create a progress bar | ||||
| const progress = new SmartlogProgressBar({ | ||||
|   total: 100, | ||||
|   width: 40, | ||||
|   complete: '█', | ||||
|   incomplete: '░', | ||||
|   showEta: true, | ||||
|   showPercent: true, | ||||
|   showCount: true | ||||
| }); | ||||
|  | ||||
| // Update progress | ||||
| progressBar.update(25);      // Set to 25% progress | ||||
| for (let i = 0; i <= 100; i++) { | ||||
|   progress.update(i); | ||||
|   await someAsyncWork(); | ||||
| } | ||||
|  | ||||
| // Increment progress | ||||
| progressBar.increment(5);    // Increase by 5 units | ||||
| progress.complete(); | ||||
|  | ||||
| // Change color | ||||
| progressBar.setColor('blue'); | ||||
| // Real-world example: Processing files | ||||
| const files = await getFiles(); | ||||
| const progress = new SmartlogProgressBar({ | ||||
|   total: files.length, | ||||
|   width: 50 | ||||
| }); | ||||
|  | ||||
| // Complete the progress bar | ||||
| progressBar.complete(); | ||||
| for (const [index, file] of files.entries()) { | ||||
|   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 | ||||
| [Success] Connected to server | ||||
| [Loading] Fetching records | ||||
| [Loading] Connecting to database | ||||
| [Success] Connected to database | ||||
| [Loading] Running migrations | ||||
| Progress: 25% (25/100) | ||||
| Progress: 50% (50/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 | ||||
| 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 | ||||
|  | ||||
| For metrics and counters: | ||||
| Perfect for metrics and counters: | ||||
|  | ||||
| ```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 | ||||
| logger.log('info', 'Request received', { userId: 'user-123' }, { | ||||
|   id: 'req-abc-123', | ||||
|   type: 'service', | ||||
|   transaction: 'tx-payment-456' | ||||
| logger.enableConsole({  | ||||
|   captureAll: true  // Capture all console.* methods | ||||
| }); | ||||
|  | ||||
| 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.  | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,6 @@ | ||||
|  */ | ||||
| export const commitinfo = { | ||||
|   name: '@push.rocks/smartlog', | ||||
|   version: '3.1.8', | ||||
|   version: '3.1.9', | ||||
|   description: 'A minimalistic, distributed, and extensible logging tool supporting centralized log management.' | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user