UNPKG

logstack-zee

Version:

Complete Node.js logging solution with 6 integration methods, S3 bidirectional operations, advanced analytics, and multi-cloud storage support for enterprise-scale applications.

1,575 lines (1,249 loc) 43.8 kB
# logstack Production-ready Node.js package for automated hourly API logs processing and cloud storage uploads with MongoDB and cron jobs. ## ✨ Features - **� Automated Processing**: Hourly cron jobs for API logs processing and uploads - **☁️ Multi-Cloud Storage**: AWS S3, Google Cloud, Azure Blob, and local file storage - **�️ Database Flexibility**: Custom collection names to avoid conflicts - **📁 Organized Structure**: Clean output directories and file organization - **⚡ High Performance**: Batch processing for large datasets (163+ records/sec) - **🎯 TypeScript Support**: Full type safety and IntelliSense - **�️ Production Ready**: Comprehensive error handling and retry logic ## 🚀 Installation ```bash npm install logstack ``` ## 📋 Quick Start ```typescript import { init, createDailyJobs } from "logstack"; // Initialize with your preferred configuration await init({ dbUri: "mongodb://localhost:27017/cronlog", uploadProvider: "s3", // 'local', 's3', 'gcs', 'azure' fileFormat: "json", retryAttempts: 3, // 📁 Organized output directory (keeps project clean) outputDirectory: "production-logs", // 🗃️ Custom collection names (avoid database conflicts) collections: { jobsCollectionName: "myapp_jobs", // Instead of default "jobs" logsCollectionName: "myapp_logs", // Instead of default "logs" apiLogsCollectionName: "myapp_apilogs", // Instead of default "apilogs" }, s3: { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, region: "us-east-1", bucket: "my-logs-bucket", }, logging: { level: "info", enableConsole: true, enableFile: true, }, }); // Create daily jobs (automatically done via cron) await createDailyJobs(); ``` ## 🔧 Configuration Options ### Storage Providers #### AWS S3 ```typescript { uploadProvider: "s3", outputDirectory: "production-logs", // Organized S3 structure collections: { jobsCollectionName: "prod_jobs", // Avoid conflicts logsCollectionName: "prod_logs" }, s3: { accessKeyId: "your-access-key-id", secretAccessKey: "your-secret-access-key", region: "us-east-1", bucket: "your-bucket-name", endpoint: "https://custom-s3-endpoint.com" // Optional for S3-compatible services } } ``` **🧪 Test AWS Setup:** ```bash npm run test:aws # Basic AWS S3 testing npm run test:aws-performance # Performance testing npm run test:aws-regions # Multi-region testing ``` **📁 S3 File Structure:** ``` s3://your-bucket/ ├── production-logs/2025-08-25/14-15.json ├── dev-logs/2025-08-25/14-15.json └── organized-structure/ ``` #### Google Cloud Storage ```typescript { uploadProvider: "gcs", gcs: { projectId: "your-gcp-project-id", keyFilename: "./path/to/service-account-key.json", // or use credentials bucket: "your-gcs-bucket-name" } } ``` #### Azure Blob Storage ```typescript { uploadProvider: "azure", azure: { connectionString: "DefaultEndpointsProtocol=https;AccountName=...", containerName: "your-container-name" } } ``` #### Local Storage ```typescript { uploadProvider: "local"; // Files saved to local filesystem } ``` ### Complete Configuration Interface ```typescript interface Config { dbUri: string; uploadProvider: "local" | "s3" | "gcs" | "azure"; fileFormat?: "json" | "csv" | "txt"; retryAttempts?: number; dailyCron?: string; // Default: '0 0 * * *' (midnight) hourlyCron?: string; // Default: '0 * * * *' (every hour) timezone?: string; // Default: 'UTC' // 📁 Organized output directory for clean project structure outputDirectory?: string; // Default: "uploads" // 🗃️ Custom collection names to avoid database conflicts collections?: { jobsCollectionName?: string; // Default: "jobs" logsCollectionName?: string; // Default: "logs" apiLogsCollectionName?: string; // Default: "apilogs" }; // 📊 API Logs Configuration (for existing collections) apiLogs?: { existingCollection?: { name: string; // Your existing collection name timestampField: string; // Field to filter by time requiredFields?: { /* field mappings */ }; }; createNew?: { collectionName?: string; enableMiddleware?: boolean; autoFields?: boolean; }; }; logging?: { level: "debug" | "info" | "warn" | "error"; enableConsole?: boolean; enableFile?: boolean; logFilePath?: string; }; // Cloud storage configurations s3?: { /* AWS S3 config */ }; gcs?: { /* Google Cloud config */ }; azure?: { /* Azure Blob config */ }; } ``` ### 📁 Organized Output Directory Keep your project clean by organizing generated files in a dedicated directory: ```typescript await init({ dbUri: "mongodb://localhost:27017/your-db", uploadProvider: "local", // Organize files in a dedicated directory outputDirectory: "logs", // Files saved in logs/{date}/ // Before: Files created in project root: 2025-08-25/00-01.json // After: Files created in: logs/2025-08-25/00-01.json }); ``` ### 🗂️ Custom Collection Names Avoid database conflicts by using custom collection names:```typescript await init({ dbUri: "mongodb://localhost:27017/your-db", uploadProvider: "local", // Use custom collection names to prevent conflicts collections: { jobsCollectionName: "my_file_processing_jobs", // Instead of "jobs" logsCollectionName: "my_file_processing_logs", // Instead of "logs" }, }); ```` This is especially useful when: - Running multiple instances of the service - Avoiding conflicts with existing collections - Organizing collections with meaningful names - Separating environments (dev/staging/prod) ## 🚀 Complete Node.js Implementation ### 📦 1. Installation & Setup ```bash # Install the package npm install logstack # Install required dependencies npm install mongodb mongoose npm install dotenv # For environment variables # Optional: AWS SDK for S3 npm install aws-sdk # Optional: Express.js for API middleware npm install express @types/express ``` ### 🔧 2. Environment Configuration Create a `.env` file in your project root: ```env # Database Configuration DB_URI=mongodb://localhost:27017/your-app-name # AWS S3 Configuration (if using S3) AWS_ACCESS_KEY_ID=your-access-key-id AWS_SECRET_ACCESS_KEY=your-secret-access-key AWS_REGION=us-east-1 S3_BUCKET=your-bucket-name # Application Configuration NODE_ENV=production LOG_LEVEL=info ``` ### 💻 3. Basic Implementation (CommonJS) ```javascript // basic-setup.js const { init, createDailyJobs, processSpecificHour } = require('logstack'); require('dotenv').config(); async function setupCronLogService() { try { // Basic configuration const config = { dbUri: process.env.DB_URI || 'mongodb://localhost:27017/myapp', uploadProvider: 'local', // Start with local storage fileFormat: 'json', // Organized file structure outputDirectory: 'api-logs', // Custom collections to avoid conflicts collections: { jobsCollectionName: 'myapp_jobs', logsCollectionName: 'myapp_logs', apiLogsCollectionName: 'myapp_apilogs' }, logging: { level: 'info', enableConsole: true, enableFile: true } }; // Initialize the service console.log('🚀 Initializing logstack...'); await init(config); console.log('✅ Service initialized successfully'); // Create daily jobs for today const today = new Date().toISOString().split('T')[0]; const job = await createDailyJobs(today, config); console.log(`📅 Created daily job with ${job.hours.length} hour slots`); // Process specific hour (example) const currentHour = new Date().getHours(); await processSpecificHour(today, currentHour, config); console.log(`⚡ Processed hour ${currentHour}:00-${currentHour + 1}:00`); } catch (error) { console.error('❌ Setup failed:', error); process.exit(1); } } // Run the setup setupCronLogService(); ``` ### 🎯 4. Advanced Implementation (ES Modules) ```javascript // advanced-setup.mjs import { init, createDailyJobs, processSpecificHour, saveApiLog } from 'logstack'; import dotenv from 'dotenv'; dotenv.config(); class CronLogManager { constructor() { this.config = { dbUri: process.env.DB_URI, uploadProvider: process.env.UPLOAD_PROVIDER || 'local', fileFormat: 'json', // Production-ready configuration outputDirectory: process.env.OUTPUT_DIR || 'production-logs', // Environment-specific collections collections: { jobsCollectionName: `${process.env.NODE_ENV || 'dev'}_jobs`, logsCollectionName: `${process.env.NODE_ENV || 'dev'}_logs`, apiLogsCollectionName: `${process.env.NODE_ENV || 'dev'}_apilogs` }, // AWS S3 configuration s3: process.env.UPLOAD_PROVIDER === 's3' ? { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, region: process.env.AWS_REGION || 'us-east-1', bucket: process.env.S3_BUCKET } : undefined, logging: { level: process.env.LOG_LEVEL || 'info', enableConsole: true, enableFile: true, logFilePath: './logs/cron-service.log' } }; } async initialize() { try { console.log('🚀 Initializing CronLogManager...'); await init(this.config); console.log('✅ CronLogManager initialized successfully'); // Log configuration summary console.log('📋 Configuration Summary:'); console.log(` 📁 Output Directory: ${this.config.outputDirectory}`); console.log(` ☁️ Upload Provider: ${this.config.uploadProvider}`); console.log(` 🗃️ Collections: ${Object.values(this.config.collections).join(', ')}`); return true; } catch (error) { console.error('❌ Initialization failed:', error); throw error; } } async createJobsForDateRange(startDate, endDate) { const jobs = []; const start = new Date(startDate); const end = new Date(endDate); for (let d = start; d <= end; d.setDate(d.getDate() + 1)) { const dateStr = d.toISOString().split('T')[0]; const job = await createDailyJobs(dateStr, this.config); jobs.push(job); console.log(`📅 Created job for ${dateStr} with ${job.hours.length} hours`); } return jobs; } async processHourRange(date, startHour, endHour) { const results = []; for (let hour = startHour; hour <= endHour; hour++) { try { console.log(`⚡ Processing ${date} ${hour}:00-${hour + 1}:00...`); const result = await processSpecificHour(date, hour, this.config); results.push({ hour, status: 'success', result }); console.log(`✅ Hour ${hour} processed successfully`); } catch (error) { console.error(`❌ Hour ${hour} failed:`, error.message); results.push({ hour, status: 'failed', error: error.message }); } } return results; } async addApiLog(logData) { return await saveApiLog(logData, this.config); } getConfig() { return { ...this.config }; } } // Usage example async function main() { const manager = new CronLogManager(); try { // Initialize await manager.initialize(); // Create jobs for the next 7 days const today = new Date(); const nextWeek = new Date(today.getTime() + 7 * 24 * 60 * 60 * 1000); await manager.createJobsForDateRange( today.toISOString().split('T')[0], nextWeek.toISOString().split('T')[0] ); // Process today's business hours (9 AM to 5 PM) const todayStr = today.toISOString().split('T')[0]; await manager.processHourRange(todayStr, 9, 17); console.log('🎉 Setup completed successfully!'); } catch (error) { console.error('❌ Setup failed:', error); process.exit(1); } } // Run if this file is executed directly if (import.meta.url === `file://${process.argv[1]}`) { main(); } export default CronLogManager; ``` ### 🌐 5. Express.js Integration ```javascript // express-integration.js const express = require('express'); const { init, createApiLogMiddleware, getApiLogs } = require('logstack'); require('dotenv').config(); const app = express(); app.use(express.json()); async function setupExpressApp() { // Initialize logstack const config = { dbUri: process.env.DB_URI, uploadProvider: 'local', outputDirectory: 'api-logs', collections: { jobsCollectionName: 'express_jobs', logsCollectionName: 'express_logs', apiLogsCollectionName: 'express_apilogs' } }; await init(config); // Add API logging middleware app.use(createApiLogMiddleware(config)); // Your API routes app.get('/api/users', (req, res) => { res.json({ users: [ { id: 1, name: 'John Doe', email: 'john@example.com' }, { id: 2, name: 'Jane Smith', email: 'jane@example.com' } ] }); }); app.post('/api/users', (req, res) => { const { name, email } = req.body; const newUser = { id: Date.now(), name, email }; res.status(201).json({ user: newUser, message: 'User created successfully' }); }); // API logs endpoint app.get('/api/logs', async (req, res) => { try { const { method, startDate, endDate, limit = 100 } = req.query; const filters = {}; if (method) filters.method = method; if (startDate) filters.startDate = new Date(startDate); if (endDate) filters.endDate = new Date(endDate); filters.limit = parseInt(limit); const logs = await getApiLogs(filters, config); res.json({ logs, count: logs.length }); } catch (error) { res.status(500).json({ error: error.message }); } }); // Health check endpoint app.get('/health', (req, res) => { res.json({ status: 'healthy', timestamp: new Date().toISOString(), service: 'logstack-express' }); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`🚀 Express server running on port ${PORT}`); console.log(`📊 API logs automatically captured`); console.log(`🔗 View logs: http://localhost:${PORT}/api/logs`); }); } setupExpressApp().catch(console.error); ``` ### ☁️ 6. AWS S3 Production Setup ```javascript // aws-production.js const { init, createDailyJobs, processSpecificHour } = require('logstack'); require('dotenv').config(); class AWSProductionSetup { constructor() { this.config = { dbUri: process.env.DB_URI, uploadProvider: 's3', fileFormat: 'json', // Production AWS configuration outputDirectory: 'production-api-logs', collections: { jobsCollectionName: 'prod_jobs', logsCollectionName: 'prod_logs', apiLogsCollectionName: 'prod_apilogs' }, s3: { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, region: process.env.AWS_REGION || 'us-east-1', bucket: process.env.S3_BUCKET }, retryAttempts: 5, logging: { level: 'info', enableConsole: true, enableFile: true, logFilePath: '/var/log/cron-service/production.log' } }; } async validateAWSCredentials() { console.log('🔐 Validating AWS credentials...'); const required = ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'S3_BUCKET']; const missing = required.filter(key => !process.env[key]); if (missing.length > 0) { throw new Error(`Missing AWS environment variables: ${missing.join(', ')}`); } console.log('✅ AWS credentials validated'); } async initialize() { await this.validateAWSCredentials(); console.log('🚀 Initializing AWS Production Setup...'); await init(this.config); console.log('✅ Production setup initialized'); console.log('📋 Production Configuration:'); console.log(` 🪣 S3 Bucket: ${this.config.s3.bucket}`); console.log(` 🌍 Region: ${this.config.s3.region}`); console.log(` 📁 Output Directory: ${this.config.outputDirectory}`); } async setupDailyProcessing() { // Setup for the next 30 days const jobs = []; const today = new Date(); for (let i = 0; i < 30; i++) { const date = new Date(today.getTime() + i * 24 * 60 * 60 * 1000); const dateStr = date.toISOString().split('T')[0]; const job = await createDailyJobs(dateStr, this.config); jobs.push(job); if (i % 7 === 0) { console.log(`📅 Created jobs for week starting ${dateStr}`); } } console.log(`🎉 Created ${jobs.length} daily job configurations`); return jobs; } async processBacklog(startDate, endDate) { console.log(`⏮️ Processing backlog from ${startDate} to ${endDate}`); const start = new Date(startDate); const end = new Date(endDate); const results = []; for (let d = start; d <= end; d.setDate(d.getDate() + 1)) { const dateStr = d.toISOString().split('T')[0]; // Process all 24 hours for each day for (let hour = 0; hour < 24; hour++) { try { await processSpecificHour(dateStr, hour, this.config); results.push({ date: dateStr, hour, status: 'success' }); } catch (error) { console.error(`❌ Failed ${dateStr} ${hour}:00:`, error.message); results.push({ date: dateStr, hour, status: 'failed', error: error.message }); } } console.log(`✅ Processed all hours for ${dateStr}`); } const successful = results.filter(r => r.status === 'success').length; const failed = results.filter(r => r.status === 'failed').length; console.log(`📊 Backlog processing complete:`); console.log(` ✅ Successful: ${successful}`); console.log(` ❌ Failed: ${failed}`); console.log(` 📈 Success rate: ${((successful / (successful + failed)) * 100).toFixed(2)}%`); return results; } } // Production deployment script async function deployProduction() { const setup = new AWSProductionSetup(); try { // Initialize await setup.initialize(); // Setup daily processing await setup.setupDailyProcessing(); // Process any backlog (last 7 days) const today = new Date(); const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); await setup.processBacklog( weekAgo.toISOString().split('T')[0], today.toISOString().split('T')[0] ); console.log('🎉 AWS Production deployment completed successfully!'); console.log('🔄 Cron jobs will now run automatically every hour'); } catch (error) { console.error('❌ Production deployment failed:', error); process.exit(1); } } // Run deployment if (require.main === module) { deployProduction(); } module.exports = AWSProductionSetup; ``` ### 📊 7. Performance Testing & Monitoring ```javascript // performance-test.js const { init, processSpecificHour, getApiLogs } = require('logstack'); require('dotenv').config(); class PerformanceMonitor { constructor() { this.metrics = { processedRecords: 0, failedRecords: 0, totalDuration: 0, averagePerRecord: 0, memoryUsage: [] }; } async testPerformance() { const config = { dbUri: process.env.DB_URI, uploadProvider: 'local', outputDirectory: 'performance-test', collections: { jobsCollectionName: 'perf_jobs', logsCollectionName: 'perf_logs', apiLogsCollectionName: 'apilogs' // Use your real data } }; await init(config); console.log('⚡ Starting performance test...'); const startTime = Date.now(); // Test processing multiple hours in parallel const today = new Date().toISOString().split('T')[0]; const hours = [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]; const promises = hours.map(async (hour) => { const hourStart = Date.now(); try { await processSpecificHour(today, hour, config); const duration = Date.now() - hourStart; this.metrics.processedRecords++; console.log(`✅ Hour ${hour}: ${duration}ms`); return { hour, duration, status: 'success' }; } catch (error) { this.metrics.failedRecords++; console.error(`❌ Hour ${hour}: ${error.message}`); return { hour, status: 'failed', error: error.message }; } }); const results = await Promise.all(promises); const endTime = Date.now(); this.metrics.totalDuration = endTime - startTime; this.metrics.averagePerRecord = this.metrics.totalDuration / this.metrics.processedRecords; console.log('\n📊 Performance Test Results:'); console.log(`⏱️ Total Duration: ${this.metrics.totalDuration}ms`); console.log(`✅ Processed Records: ${this.metrics.processedRecords}`); console.log(`❌ Failed Records: ${this.metrics.failedRecords}`); console.log(`📈 Average per Record: ${this.metrics.averagePerRecord.toFixed(2)}ms`); console.log(`🎯 Success Rate: ${((this.metrics.processedRecords / (this.metrics.processedRecords + this.metrics.failedRecords)) * 100).toFixed(2)}%`); const memUsage = process.memoryUsage(); console.log(`💾 Memory Usage: ${(memUsage.heapUsed / 1024 / 1024).toFixed(2)} MB`); return results; } } // Run performance test if (require.main === module) { const monitor = new PerformanceMonitor(); monitor.testPerformance().catch(console.error); } ``` ### 🧪 8. Testing Your Implementation ```bash # Run comprehensive tests npm run test:final-local # Complete local test npm run test:final-local:quick # Quick local test npm run test:final-local:analytics # Analytics only npm run test:final-local:validate # Validate existing files # AWS testing npm run test:aws # Basic AWS test npm run test:aws-performance # Performance test npm run test:aws-regions # Multi-region test # Custom examples npm run example:custom-collections # Custom collections demo npm run example:organized-output # Organized directories demo ``` ### 📈 9. Production Deployment Checklist ```bash # 1. Environment setup cp .env.example .env # Edit .env with your credentials # 2. Database setup mongosh your-mongodb-uri # Verify connection and permissions # 3. AWS setup (if using S3) aws configure list aws s3 ls s3://your-bucket-name # 4. Install and test npm install npm run test:final-local # 5. Deploy to production node production-setup.js # 6. Monitor logs tail -f /var/log/cron-service/production.log ``` ### 🎯 10. Real-World Usage Scenarios **Scenario 1: E-commerce API Logs** ```javascript const ecommerceConfig = { dbUri: process.env.DB_URI, uploadProvider: 's3', outputDirectory: 'ecommerce-api-logs', collections: { jobsCollectionName: 'ecommerce_jobs', logsCollectionName: 'ecommerce_logs', apiLogsCollectionName: 'api_requests' // Your existing collection }, s3: { /* AWS config */ } }; ``` **Scenario 2: Multi-tenant SaaS** ```javascript const createTenantConfig = (tenantId) => ({ dbUri: process.env.DB_URI, uploadProvider: 'local', outputDirectory: `tenant-${tenantId}-logs`, collections: { jobsCollectionName: `tenant_${tenantId}_jobs`, logsCollectionName: `tenant_${tenantId}_logs`, apiLogsCollectionName: `tenant_${tenantId}_apilogs` } }); ``` **Scenario 3: Microservices Architecture** ```javascript const services = ['user-service', 'order-service', 'payment-service']; services.forEach(async (service) => { const config = { dbUri: process.env.DB_URI, uploadProvider: 's3', outputDirectory: `${service}-logs`, collections: { jobsCollectionName: `${service.replace('-', '_')}_jobs`, logsCollectionName: `${service.replace('-', '_')}_logs`, apiLogsCollectionName: `${service.replace('-', '_')}_apilogs` } }; await init(config); }); ``` ## 🎯 API Request Logging Built-in Express.js middleware for automatic API request logging: ```typescript import express from "express"; import { createApiLogMiddleware, getApiLogs, init } from "logstack"; const app = express(); // Initialize the service await init({ dbUri: "mongodb://localhost:27017/cronlog", uploadProvider: "local", }); // Add API logging middleware app.use(createApiLogMiddleware()); // Your API routes app.get("/api/users", (req, res) => { res.json({ users: [] }); }); // Query API logs app.get("/api/logs", async (req, res) => { const logs = await getApiLogs({ method: "GET", startDate: new Date("2025-08-25T00:00:00Z"), endDate: new Date("2025-08-25T23:59:59Z"), limit: 100, }); res.json(logs); }); ```` ## 📊 Job Management ### Manual Operations ```typescript import { createDailyJobs, runHourlyJob, getLogs, getJobStatus, retryFailedJobs, } from "logstack"; // Create jobs for specific date await createDailyJobs("2025-08-25"); // Manually run hourly job await runHourlyJob(config); // Get job status const status = await getJobStatus("2025-08-25", "09-10"); // Get logs const logs = await getLogs("2025-08-25"); // Retry failed jobs await retryFailedJobs(config); ``` ## 🧪 Testing & Validation ### 📊 Comprehensive Test Results Our final comprehensive test processed **500 API logs** with perfect results: ``` 🎉 Final Test Results: ⏱️ Total Duration: 3.06 seconds 📄 Records Processed: 500 📁 Files Created: 52 💾 Total Size: 0.55 MB ⚡ Processing Rate: 163.29 records/second 🧠 Memory Usage: 1025.97 MB 📈 Success Rate: 100.00% ``` ### 🗂️ Generated File Structure ``` final-test-outputs/ ├── 2025-08-25/ │ ├── api-logs-06-00.json (20 records) │ ├── api-logs-07-00.json (20 records) │ └── ... (all 24 hours) ├── 2025-08-26/ │ ├── 09-10.json (21 records) │ ├── 12-13.json (9 records) │ └── api-logs-{hour}-00.json ├── streaming/ │ ├── 2025-08-25/stream-api-logs-{hour}-00.json │ └── 2025-08-26/stream-api-logs-{hour}-00.json └── analytics/ └── final-test-analytics.json ``` ### 🧪 Running Tests ```bash # Complete final test (recommended) npm run test:final-local # Quick tests npm run test:final-local:quick # Faster with fewer records npm run test:final-local:analytics # Analytics generation only npm run test:final-local:validate # Validate existing files # AWS S3 testing npm run test:aws # Basic AWS functionality npm run test:aws-performance # High-performance AWS test npm run test:aws-regions # Multi-region AWS test # Feature-specific examples npm run example:custom-collections # Custom collection names npm run example:organized-output # Organized directory structure # API logging examples npm run test:apilogs # API logs processing npm run inspect:apilogs # Inspect existing API logs ``` ### ✅ Test Coverage - **✅ Local File Storage**: 100% success rate with organized structure - **✅ AWS S3 Integration**: Multi-environment testing with real credentials - **✅ High-Performance Processing**: 163+ records/second processing rate - **✅ Memory Efficiency**: Streaming prevents memory overflow - **✅ Custom Collections**: No database conflicts with custom names - **✅ Error Handling**: Robust retry mechanisms and error recovery - **✅ File Validation**: 100% JSON validation success rate - **✅ Analytics Reporting**: Comprehensive performance metrics ## 📁 Examples & Use Cases ### 🚀 Quick Start Examples ```bash # Basic local setup npm run example:custom-collections # Custom collection names demo npm run example:organized-output # Organized directory structure # API logging examples npm run test:apilogs # Process API logs from database npm run inspect:apilogs # Inspect existing API logs data # Production examples npm run practical:setup # Production-ready setup npm run practical:cloud # Cloud storage configuration npm run practical:inspect # Inspect production data # Job processing examples npm run job:create-and-process # Create and process jobs npm run job:current-hour # Process current hour npm run job:date-range # Process date range # Multi-provider examples npm run example:s3 # AWS S3 example npm run example:gcs # Google Cloud Storage example npm run example:azure # Azure Blob Storage example ``` ### 💡 Real-World Implementation Examples **1. E-commerce Platform:** ```javascript // E-commerce API logs processing const ecommerceConfig = { dbUri: process.env.DB_URI, uploadProvider: "s3", outputDirectory: "ecommerce-api-logs", collections: { jobsCollectionName: "ecommerce_jobs", logsCollectionName: "ecommerce_logs", apiLogsCollectionName: "api_requests", }, s3: { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, region: "us-east-1", bucket: "ecommerce-logs-bucket", }, }; ``` **2. Multi-tenant SaaS:** ```javascript // Separate logs per tenant const createTenantConfig = (tenantId) => ({ dbUri: process.env.DB_URI, uploadProvider: "local", outputDirectory: `tenant-${tenantId}-logs`, collections: { jobsCollectionName: `tenant_${tenantId}_jobs`, logsCollectionName: `tenant_${tenantId}_logs`, apiLogsCollectionName: `tenant_${tenantId}_apilogs`, }, }); ``` **3. Microservices Architecture:** ```javascript // Separate configs per service const services = ["user-service", "order-service", "payment-service"]; services.forEach(async (service) => { const config = { outputDirectory: `${service}-logs`, collections: { jobsCollectionName: `${service.replace("-", "_")}_jobs`, logsCollectionName: `${service.replace("-", "_")}_logs`, apiLogsCollectionName: `${service.replace("-", "_")}_apilogs`, }, }; await init(config); }); ``` ## 🏗️ Project Structure ``` logstack/ ├── src/ │ ├── main.ts # Main initialization │ ├── jobs.ts # Job management logic │ ├── logs.ts # Log querying │ └── apiLogs.ts # API logging functionality ├── lib/ │ ├── db.ts # Database connection │ ├── cron.ts # Cron job setup │ ├── fileProcessor.ts # File processing logic │ ├── fileWriters.ts # File format writers │ ├── uploadProviders.ts # Cloud storage providers │ ├── validation.ts # Configuration validation │ ├── logger.ts # Winston logging setup │ └── userDataProvider.ts # Custom data provider ├── models/ │ ├── job.ts # Job schema │ ├── log.ts # Log schema │ └── apiLog.ts # API log schema ├── types/ │ └── config.d.ts # TypeScript definitions ├── examples/ │ ├── basic.ts # Basic usage │ ├── advanced.ts # Advanced configuration │ ├── multiProvider.ts # Multi-cloud examples │ └── apiLogs.ts # API logging examples └── test/ ├── jobs.test.ts # Job tests └── comprehensive.test.ts # Full test suite ``` ## 🔧 Custom Data Provider Override the default data provider to use your own data source: ```typescript // lib/userDataProvider.ts export async function getDataForHour( date: string, hourRange: string ): Promise<any> { // Your custom data fetching logic const logs = await YourDatabase.find({ timestamp: { $gte: new Date(`${date}T${hourRange.split("-")[0]}:00:00Z`), $lt: new Date(`${date}T${hourRange.split("-")[1]}:00:00Z`), }, }); return logs; } ``` ## � Production Deployment ### 📋 Pre-deployment Checklist ```bash # 1. Environment Configuration cp .env.example .env # Configure: DB_URI, AWS credentials, etc. # 2. Test Local Setup npm run test:final-local # Verify: 100% success rate, file generation working # 3. Test Cloud Storage (if using) npm run test:aws # Verify: S3 uploads working, credentials valid # 4. Validate Database Connection npm run inspect:apilogs # Verify: Can access your API logs collection # 5. Performance Testing npm run test:final-local:quick # Verify: Processing speed meets requirements ``` ### 🌟 Production Performance Metrics Based on comprehensive testing with **real API logs data**: | Metric | Result | Status | | ---------------------- | ---------------------- | ------------ | | **Processing Rate** | 163+ records/sec | ✅ Excellent | | **Memory Usage** | ~1GB for 500 records | ✅ Efficient | | **File Generation** | 52 files in 3.06 sec | ✅ Fast | | **Success Rate** | 100% | ✅ Perfect | | **Storage Efficiency** | 0.55MB for 500 records | ✅ Optimized | ### �🔄 Cron Schedule & Automation The package automatically sets up these production cron jobs: ```javascript // Automatic cron jobs (no manual setup required) { dailyCron: '0 0 * * *', // Create daily jobs at midnight hourlyCron: '0 * * * *', // Process each hour retryCron: '*/30 * * * *' // Retry failed jobs every 30 min } ``` **What happens automatically:** 1. **Midnight**: Creates 24 hourly job slots for the new day 2. **Every Hour**: Processes the current hour's API logs 3. **Every 30 Minutes**: Retries any failed processing jobs 4. **Continuous**: Monitors and logs all operations ### 📊 Monitoring & Analytics **Real-time Monitoring:** ```bash # View live logs tail -f logs/cron-service.log # Check analytics npm run test:final-local:analytics # Validate generated files npm run test:final-local:validate ``` **Analytics Include:** - Processing performance metrics - Success/failure rates - Memory usage patterns - File size and count statistics - Method and status code distributions ## 🏗️ Project Structure ``` your-project/ ├── node_modules/ │ └── logstack/ ├── final-test-outputs/ # Generated files (organized) │ ├── 2025-08-25/ │ │ ├── api-logs-09-00.json # Hour 9-10 API logs │ │ ├── api-logs-10-00.json # Hour 10-11 API logs │ │ └── 09-10.json # Job-generated files │ ├── streaming/ # Streaming processor output │ └── analytics/ # Performance reports ├── logs/ # Service logs │ └── cron-service.log ├── .env # Environment configuration ├── package.json └── your-app.js # Your implementation ``` ## 🎯 Best Practices ### 🗃️ Database Organization ```javascript // ✅ Good: Environment-specific collections const prodConfig = { collections: { jobsCollectionName: "prod_jobs", logsCollectionName: "prod_logs", apiLogsCollectionName: "prod_apilogs", }, }; const devConfig = { collections: { jobsCollectionName: "dev_jobs", logsCollectionName: "dev_logs", apiLogsCollectionName: "dev_apilogs", }, }; // ❌ Avoid: Using default collection names in production const badConfig = { // Will conflict with other instances // collections: undefined // Uses defaults: 'jobs', 'logs', 'apilogs' }; ``` ### 📁 File Organization ```javascript // ✅ Good: Organized directory structure const organizedConfig = { outputDirectory: "production-api-logs", // Clean separation uploadProvider: "s3", s3: { bucket: "company-api-logs-prod" }, }; // ❌ Avoid: Files in project root const messyConfig = { // outputDirectory: undefined, // Files in project root uploadProvider: "local", }; ``` ### ⚡ Performance Optimization ```javascript // ✅ Good: Batch processing for large datasets const performantConfig = { retryAttempts: 5, // Handle transient failures fileFormat: "json", // Most efficient for APIs logging: { level: "info" }, // Reduce log noise }; // Configure batch size for your data volume const batchSize = process.env.NODE_ENV === "production" ? 1000 : 100; ``` ## 🔧 Configuration Best Practices ### 🌍 Environment-Specific Configs ```javascript // config/production.js module.exports = { dbUri: process.env.PROD_DB_URI, uploadProvider: "s3", outputDirectory: "production-api-logs", collections: { jobsCollectionName: "prod_jobs", logsCollectionName: "prod_logs", apiLogsCollectionName: "prod_apilogs", }, s3: { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, region: process.env.AWS_REGION, bucket: process.env.PROD_S3_BUCKET, }, retryAttempts: 5, logging: { level: "info", enableFile: true }, }; // config/development.js module.exports = { dbUri: process.env.DEV_DB_URI, uploadProvider: "local", outputDirectory: "dev-api-logs", collections: { jobsCollectionName: "dev_jobs", logsCollectionName: "dev_logs", apiLogsCollectionName: "dev_apilogs", }, retryAttempts: 3, logging: { level: "debug", enableConsole: true }, }; ``` ## 🐛 Troubleshooting ### Common Issues 1. **MongoDB Connection**: Ensure MongoDB is running and the connection string is correct 2. **Cloud Storage Permissions**: Verify credentials have proper read/write permissions 3. **File Path Issues**: Check that the application has write permissions for local storage 4. **Timezone Issues**: Set the correct timezone in configuration ### Debug Logging Enable debug logging for detailed information: ```typescript await init({ // ... other config logging: { level: "debug", enableConsole: true, enableFile: true, logFilePath: "./debug.log", }, }); ``` ## 📄 License MIT License - see LICENSE file for details ## 🤝 Contributing 1. Fork the repository 2. Create a feature branch 3. Add tests for new functionality 4. Submit a pull request ## � Complete Documentation ### 🚀 Getting Started - **[Quick Start Guide](./examples/quickStart.ts)** - Copy-paste examples for immediate use - **[Implementation Checklist](./IMPLEMENTATION_CHECKLIST.md)** - Step-by-step setup guide - **[Complete Step-by-Step Guide](./COMPLETE_STEP_BY_STEP_GUIDE.md)** - Comprehensive usage documentation ### 🎯 Key Features - **[Custom Collection Names](./CUSTOM_COLLECTIONS.md)** - Avoid database conflicts - **[Organized Output Directory](./OUTPUT_DIRECTORY.md)** - Clean project structure - **[Implementation Complete](./IMPLEMENTATION_COMPLETE.md)** - Features overview ### 🧪 Testing & Examples - **[Testing Guide](./TESTING_GUIDE.md)** - How to test your setup - **[API Logs Testing](./APILOGS_TESTING_GUIDE.md)** - API logging validation - **[Examples Folder](./examples/)** - Working code samples ### 📋 Reference - **[Configuration Options](./FLEXIBLE_API_LOGS.md)** - All available settings - **[Usage Guide](./COMPLETE_USAGE_GUIDE.md)** - Detailed API reference ## 🎯 Quick Implementation **Choose your setup:** 1. **Basic Setup** (Recommended for beginners): ```typescript const config = { dbUri: "mongodb://localhost:27017/myapp", uploadProvider: "local", outputDirectory: "api-logs", collections: { jobsCollectionName: "myapp_jobs", logsCollectionName: "myapp_logs", }, }; ``` 2. **Production Setup**: ```typescript const config = { dbUri: process.env.DB_URI, uploadProvider: "s3", outputDirectory: "production-logs", collections: { jobsCollectionName: "prod_jobs", logsCollectionName: "prod_logs", }, s3: { /* S3 credentials */ }, }; ``` 3. **Multi-Service Setup**: ```typescript const createConfig = (serviceName) => ({ dbUri: process.env.DB_URI, uploadProvider: "local", outputDirectory: `${serviceName}-logs`, collections: { jobsCollectionName: `${serviceName}_jobs`, logsCollectionName: `${serviceName}_logs`, }, }); ``` **Start here:** [Implementation Checklist](./IMPLEMENTATION_CHECKLIST.md) ✅ ## 📞 Support - **📖 Documentation**: Check the comprehensive guides above - **🐛 Issues**: Create an issue on GitHub for bugs or feature requests - **💡 Examples**: Review the examples folder for usage patterns - **🧪 Testing**: Use the testing guides to validate your setup ```` #### Local Storage ```typescript { uploadProvider: "local" // Files saved to local filesystem } ```` ### Complete Configuration Interface ```typescript interface Config { dbUri: string; uploadProvider: "local" | "s3" | "gcs" | "azure"; fileFormat?: "json" | "csv" | "txt"; retryAttempts?: number; dailyCron?: string; // Default: '0 0 * * *' (midnight) hourlyCron?: string; // Default: '0 * * * *' (every hour) timezone?: string; // Default: 'UTC' logging?: { level: "debug" | "info" | "warn" | "error"; enableConsole?: boolean; enableFile?: boolean; logFilePath?: string; }; // ... provider-specific configs } ``` // Manually trigger daily job creation await createDailyJobs(); // Manually trigger hourly job await runHourlyJob(); // Fetch logs const logs = await getLogs("2025-08-25", "09-10"); // Fetch job status const status = await getJobStatus("2025-08-25", "09-10"); ``` ## Custom Data Provider Override `lib/userDataProvider.ts` to provide your own data for file generation. ## Running Tests This package uses Jest for testing. To run tests: ``` npm run build npx jest ``` ## Examples See the `examples/` folder for usage samples. To run the basic example: ``` npm run build node examples/basic.js ``` Or use ts-node for TypeScript: ``` npx ts-node examples/basic.ts ``` ## License MIT ```