UNPKG

datapilot-cli

Version:

Enterprise-grade streaming multi-format data analysis with comprehensive statistical insights and intelligent relationship detection - supports CSV, JSON, Excel, TSV, Parquet - memory-efficient, cross-platform

294 lines 9.21 kB
"use strict"; /** * Simple logger utility for DataPilot */ Object.defineProperty(exports, "__esModule", { value: true }); exports.LogUtils = exports.logger = exports.Logger = exports.LogLevel = void 0; var LogLevel; (function (LogLevel) { LogLevel[LogLevel["ERROR"] = 0] = "ERROR"; LogLevel[LogLevel["WARN"] = 1] = "WARN"; LogLevel[LogLevel["INFO"] = 2] = "INFO"; LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG"; LogLevel[LogLevel["TRACE"] = 4] = "TRACE"; })(LogLevel || (exports.LogLevel = LogLevel = {})); class Logger { static instance; level = LogLevel.INFO; logHistory = []; maxHistorySize = 1000; enableHistory = process.env.NODE_ENV === 'development'; constructor() { } static getInstance() { if (!Logger.instance) { Logger.instance = new Logger(); } return Logger.instance; } setLevel(level) { this.level = level; } error(message, context, ...args) { const entry = { level: LogLevel.ERROR, message, context, timestamp: new Date(), args, }; this.addToHistory(entry); if (this.level >= LogLevel.ERROR) { const contextStr = this.formatContext(context); console.error(`❌ ERROR: ${message}${contextStr}`, ...args); } } warn(message, context, ...args) { const entry = { level: LogLevel.WARN, message, context, timestamp: new Date(), args, }; this.addToHistory(entry); if (this.level >= LogLevel.WARN) { const contextStr = this.formatContext(context); console.warn(`⚠️ WARN: ${message}${contextStr}`, ...args); } } info(message, context, ...args) { const entry = { level: LogLevel.INFO, message, context, timestamp: new Date(), args, }; this.addToHistory(entry); if (this.level >= LogLevel.INFO) { const contextStr = this.formatContext(context); console.log(`ℹ️ INFO: ${message}${contextStr}`, ...args); } } debug(message, context, ...args) { const entry = { level: LogLevel.DEBUG, message, context, timestamp: new Date(), args, }; this.addToHistory(entry); if (this.level >= LogLevel.DEBUG) { const contextStr = this.formatContext(context); console.log(`🐛 DEBUG: ${message}${contextStr}`, ...args); } } progress(message, context) { if (this.level >= LogLevel.INFO) { const contextStr = this.formatContext(context); process.stdout.write(`\r⏳ ${message}${contextStr}`); } } success(message, context) { if (this.level >= LogLevel.INFO) { const contextStr = this.formatContext(context); console.log(`\r✅ ${message}${contextStr}`); } } trace(message, context, ...args) { const entry = { level: LogLevel.TRACE, message, context, timestamp: new Date(), args, }; this.addToHistory(entry); if (this.level >= LogLevel.TRACE) { const contextStr = this.formatContext(context); console.log(`🔍 TRACE: ${message}${contextStr}`, ...args); } } /** * Log performance metrics */ performance(operation, duration, context) { const perfContext = { ...context, operation, timestamp: new Date(), }; if (duration > 5000) { this.warn(`Slow operation: ${operation} took ${duration}ms`, perfContext); } else if (duration > 1000) { this.info(`Operation completed: ${operation} took ${duration}ms`, perfContext); } else { this.debug(`Operation completed: ${operation} took ${duration}ms`, perfContext); } } /** * Log memory usage */ memory(context) { const memUsage = process.memoryUsage(); const memContext = { ...context, memoryUsage: memUsage.heapUsed, }; const heapMB = Math.round(memUsage.heapUsed / 1024 / 1024); const rssMode = Math.round(memUsage.rss / 1024 / 1024); if (heapMB > 512) { this.warn(`High memory usage: ${heapMB}MB heap, ${rssMode}MB RSS`, memContext); } else { this.debug(`Memory usage: ${heapMB}MB heap, ${rssMode}MB RSS`, memContext); } } /** * Log error with stack trace and context */ errorWithStack(error, context) { const errorContext = { ...context, errorCode: error.name, }; this.error(error.message, errorContext); if (this.level >= LogLevel.DEBUG && error.stack) { console.error('Stack trace:'); console.error(error.stack); } } /** * Get recent log entries */ getRecentLogs(level, limit) { let filtered = this.logHistory; if (level !== undefined) { filtered = filtered.filter((entry) => entry.level <= level); } if (limit) { filtered = filtered.slice(-limit); } return filtered; } /** * Get error summary for debugging */ getErrorSummary() { const errors = this.logHistory.filter((entry) => entry.level === LogLevel.ERROR); const warnings = this.logHistory.filter((entry) => entry.level === LogLevel.WARN); const recentErrors = errors.slice(-10); return { errorCount: errors.length, warningCount: warnings.length, recentErrors, }; } /** * Enable or disable log history */ setHistoryEnabled(enabled) { this.enableHistory = enabled; if (!enabled) { this.logHistory = []; } } /** * Clear log history */ clearHistory() { this.logHistory = []; } /** * Export logs for debugging */ exportLogs() { return JSON.stringify(this.logHistory, null, 2); } newline() { console.log(); } formatContext(context) { if (!context) return ''; const parts = []; if (context.section) parts.push(`section:${context.section}`); if (context.analyzer) parts.push(`analyzer:${context.analyzer}`); if (context.operation) parts.push(`op:${context.operation}`); if (context.filePath) { // Show only filename for brevity const filename = context.filePath.split('/').pop() || context.filePath; parts.push(`file:${filename}`); } if (context.rowIndex !== undefined) parts.push(`row:${context.rowIndex}`); if (context.memoryUsage) { const memMB = Math.round(context.memoryUsage / 1024 / 1024); parts.push(`mem:${memMB}MB`); } return parts.length > 0 ? ` [${parts.join(', ')}]` : ''; } addToHistory(entry) { if (!this.enableHistory) return; this.logHistory.push(entry); // Trim history if it gets too large if (this.logHistory.length > this.maxHistorySize) { this.logHistory = this.logHistory.slice(-Math.floor(this.maxHistorySize * 0.8)); } } } exports.Logger = Logger; exports.logger = Logger.getInstance(); /** * Utility functions for structured logging */ class LogUtils { /** * Create a logger context for a specific operation */ static createContext(section, analyzer, filePath, operation) { return { section, analyzer, filePath, operation, timestamp: new Date(), }; } /** * Log operation start */ static logOperationStart(operation, context) { const startTime = new Date(); exports.logger.debug(`Starting operation: ${operation}`, { ...context, operation }); return startTime; } /** * Log operation end with duration */ static logOperationEnd(operation, startTime, context) { const duration = Date.now() - startTime.getTime(); exports.logger.performance(operation, duration, context); } /** * Create a scoped logger that automatically includes context */ static createScopedLogger(context) { return { error: (message, ...args) => exports.logger.error(message, context, ...args), warn: (message, ...args) => exports.logger.warn(message, context, ...args), info: (message, ...args) => exports.logger.info(message, context, ...args), debug: (message, ...args) => exports.logger.debug(message, context, ...args), trace: (message, ...args) => exports.logger.trace(message, context, ...args), }; } } exports.LogUtils = LogUtils; //# sourceMappingURL=logger.js.map