import {monitor} from "./frameloop"; /** * Centralized logging system with performance monitoring integration * @class Logger */ export class Logger { /** @type {boolean} Enable/disable logging */ static enabled = import.meta.env.MODE !== 'production'; /** @type {string} Log level: 'debug', 'info', 'warn', 'error', 'none' */ static level = import.meta.env.VITE_LOG_LEVEL || (import.meta.env.MODE === 'production' ? 'error' : 'debug'); /** @type {Object} Log level priorities */ static levels = { debug: 0, info: 1, warn: 2, error: 3, none: 99 }; /** * Log debug messages (development only) * @param {...any} args - Arguments to log */ static debug(...args) { this._write('log', '[DEBUG]', args, 'debug'); } /** * Log general information * @param {...any} args - Arguments to log */ static log(...args) { this._write('log', '[LOG]', args, 'info'); } /** * Log informational messages * @param {...any} args - Arguments to log */ static info(...args) { this._write('info', '[INFO]', args, 'info'); } /** * Log warning messages * @param {...any} args - Arguments to log */ static warn(...args) { this._write('warn', '[WARN]', args, 'warn'); } /** * Log error messages * @param {...any} args - Arguments to log */ static error(...args) { this._write('error', '[ERROR]', args, 'error'); } /** * Internal method to write log messages * @private * @param {string} consoleMethod - Console method to use * @param {string} prefix - Log level prefix * @param {Array} args - Arguments to log * @param {string} logLevel - Log level (debug, info, warn, error) */ static _write(consoleMethod, prefix, args, logLevel = 'info') { if (!this.enabled) return; // Check if this log level should be output const currentLevelPriority = this.levels[this.level] || this.levels.info; const messageLevelPriority = this.levels[logLevel] || this.levels.info; if (messageLevelPriority < currentLevelPriority) { return; } const date = new Date(); const timestamp = date.toLocaleTimeString('de-DE'); const msg = `${prefix} [${timestamp}] ${args.map(a => { if (a instanceof Error) { return `${a.name}: ${a.message}\n${a.stack || ''}`; } else if (typeof a === 'object' && a !== null) { try { return JSON.stringify(a); } catch (e) { return '[Circular Object]'; } } return a; }).join(' ')}`; if(typeof console[consoleMethod] === 'function') { console[consoleMethod](msg); } // Safe monitor logging if (monitor && typeof monitor.log === 'function') { try { monitor.log(msg); } catch (e) { // Silent fail if monitor fails } } } /** * Set log level dynamically * @param {string} level - New log level (debug, info, warn, error, none) */ static setLevel(level) { if (this.levels.hasOwnProperty(level)) { this.level = level; this.info(`[Logger] Log level set to: ${level}`); } else { this.warn(`[Logger] Invalid log level: ${level}. Valid levels:`, Object.keys(this.levels)); } } /** * Enable/disable logging * @param {boolean} enabled - Enable or disable logging */ static setEnabled(enabled) { this.enabled = !!enabled; if (enabled) { console.log('[Logger] Logging enabled'); } } }