UNPKG

snes-disassembler

Version:

A Super Nintendo (SNES) ROM disassembler for 65816 assembly

244 lines 8.44 kB
"use strict"; /** * Central Logger Configuration for SNES Disassembler * * Provides a robust logging system using Pino with: * - Environment-specific configuration * - Structured logging with context * - Performance tracking * - File and console output * - Log rotation support */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Logger = void 0; exports.createLogger = createLogger; exports.logApplicationStartup = logApplicationStartup; exports.logApplicationShutdown = logApplicationShutdown; exports.measurePerformance = measurePerformance; const pino_1 = __importDefault(require("pino")); const perf_hooks_1 = require("perf_hooks"); // Log levels enum for type safety var LogLevel; (function (LogLevel) { LogLevel["FATAL"] = "fatal"; LogLevel["ERROR"] = "error"; LogLevel["WARN"] = "warn"; LogLevel["INFO"] = "info"; LogLevel["DEBUG"] = "debug"; LogLevel["TRACE"] = "trace"; })(LogLevel || (LogLevel = {})); // Default configuration based on environment const getDefaultConfig = () => { const isDevelopment = process.env.NODE_ENV !== 'production'; const logLevel = process.env.LOG_LEVEL || (isDevelopment ? LogLevel.DEBUG : LogLevel.INFO); return { level: logLevel, prettyPrint: isDevelopment, timestamp: true, fileOutput: { enabled: !isDevelopment, filepath: './logs/snes-disassembler.log', maxSize: '10M', maxFiles: 5 } }; }; // Create the main logger instance const config = getDefaultConfig(); const pinoConfig = { level: config.level, timestamp: config.timestamp ? pino_1.default.stdTimeFunctions.isoTime : false, formatters: { level: (label) => { return { level: label }; } }, serializers: { error: pino_1.default.stdSerializers.err, req: pino_1.default.stdSerializers.req, res: pino_1.default.stdSerializers.res } }; // Add pretty printing for development if (config.prettyPrint) { pinoConfig.transport = { target: 'pino-pretty', options: { colorize: true, translateTime: 'yyyy-mm-dd HH:MM:ss', ignore: 'pid,hostname', messageFormat: '[{component}] {msg}', errorLikeObjectKeys: ['err', 'error'] } }; } // Create base logger const baseLogger = (0, pino_1.default)(pinoConfig); // Enhanced logger class with additional functionality class Logger { constructor(component, parentLogger) { this.performanceTrackers = new Map(); this.component = component; this.logger = (parentLogger ?? baseLogger).child({ component }); } // Basic logging methods fatal(message, data) { this.logger.fatal(data, message); } error(message, error) { if (error instanceof Error) { this.logger.error({ err: error }, message); } else { this.logger.error(error, message); } } warn(message, data) { this.logger.warn(data, message); } info(message, data) { this.logger.info(data, message); } debug(message, data) { this.logger.debug(data, message); } trace(message, data) { this.logger.trace(data, message); } // Performance tracking methods startPerformanceTracking(operation, metadata) { const trackingId = `${operation}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; const context = { operation, startTime: perf_hooks_1.performance.now(), metadata }; this.performanceTrackers.set(trackingId, context); this.debug(`Started performance tracking for ${operation}`, { trackingId, metadata }); return trackingId; } endPerformanceTracking(trackingId, additionalData) { const context = this.performanceTrackers.get(trackingId); if (!context) { this.warn('Performance tracking context not found', { trackingId }); return null; } const endTime = perf_hooks_1.performance.now(); const duration = endTime - context.startTime; this.info(`Completed ${context.operation}`, { duration: `${duration.toFixed(2)}ms`, trackingId, metadata: context.metadata, ...additionalData }); this.performanceTrackers.delete(trackingId); return duration; } // ROM processing specific methods logROMInfo(romPath, size, checksum) { this.info('ROM loaded successfully', { path: romPath, sizeBytes: size, sizeKB: Math.round(size / 1024), checksum }); } logDisassemblyProgress(address, instruction, progress) { this.debug('Disassembling instruction', { address: `0x${address.toString(16).toUpperCase()}`, instruction, progress: progress ? `${progress.toFixed(1)}%` : undefined }); } logAnalysisResult(analysisType, result) { this.info(`Analysis completed: ${analysisType}`, result); } // Audio processing specific methods logAudioProcessing(operation, sampleRate, channels, duration) { this.info(`Audio processing: ${operation}`, { sampleRate, channels, durationMs: duration }); } logBRRDecoding(blockCount, sampleCount, compressionRatio) { this.info('BRR decoding completed', { blocks: blockCount, samples: sampleCount, compressionRatio: compressionRatio ? `${compressionRatio.toFixed(2)}:1` : undefined }); } // Error handling with context logErrorWithContext(error, context, additionalData) { this.error(`Error in ${context}`, { err: error, context, stack: error.stack, ...additionalData }); } // Memory usage logging logMemoryUsage(operation) { const memUsage = process.memoryUsage(); this.debug('Memory usage', { operation, heapUsed: `${Math.round(memUsage.heapUsed / 1024 / 1024)}MB`, heapTotal: `${Math.round(memUsage.heapTotal / 1024 / 1024)}MB`, external: `${Math.round(memUsage.external / 1024 / 1024)}MB`, rss: `${Math.round(memUsage.rss / 1024 / 1024)}MB` }); } // Create child logger for sub-components child(childComponent) { return new Logger(`${this.component}:${childComponent}`, this.logger); } // Get the underlying Pino logger for advanced usage getPinoLogger() { return this.logger; } } exports.Logger = Logger; // Create and export the main application logger const mainLogger = new Logger('SNES-Disassembler'); // Factory function to create component-specific loggers function createLogger(component) { return new Logger(component); } // Utility functions for application lifecycle logging function logApplicationStartup(version, config) { mainLogger.info('🚀 SNES Disassembler starting up', { version, nodeVersion: process.version, platform: process.platform, arch: process.arch, config }); } function logApplicationShutdown(exitCode = 0) { mainLogger.info('🛑 SNES Disassembler shutting down', { exitCode }); } // Performance measurement decorator function measurePerformance(logger, operation) { return function (target, propertyName, descriptor) { const method = descriptor.value; descriptor.value = async function (...args) { const trackingId = logger.startPerformanceTracking(`${target.constructor.name}.${propertyName}`, { operation, arguments: args.length }); try { const result = await method.apply(this, args); logger.endPerformanceTracking(trackingId, { success: true }); return result; } catch (error) { logger.endPerformanceTracking(trackingId, { success: false, error: error instanceof Error ? error.message : String(error) }); throw error; } }; }; } //# sourceMappingURL=logger.js.map