You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
3.3 KiB
114 lines
3.3 KiB
/** |
|
* Centralized logging utility to reduce console noise and improve performance |
|
* |
|
* Usage: |
|
* - Use logger.debug() for development debugging (only shows in dev mode) |
|
* - Use logger.info() for important information (always shows) |
|
* - Use logger.warn() for warnings (always shows) |
|
* - Use logger.error() for errors (always shows) |
|
* |
|
* In production builds, debug logs are completely removed to improve performance. |
|
*/ |
|
|
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error' |
|
|
|
interface LoggerConfig { |
|
level: LogLevel |
|
enableDebug: boolean |
|
enablePerformance: boolean |
|
} |
|
|
|
class Logger { |
|
private config: LoggerConfig |
|
|
|
constructor() { |
|
// In production, disable debug logging for better performance |
|
const isDev = import.meta.env.DEV |
|
const isDebugEnabled = isDev && (localStorage.getItem('jumble-debug') === 'true' || import.meta.env.VITE_DEBUG === 'true') |
|
|
|
this.config = { |
|
level: isDebugEnabled ? 'debug' : 'info', |
|
enableDebug: isDebugEnabled, |
|
enablePerformance: isDev |
|
} |
|
} |
|
|
|
private shouldLog(level: LogLevel): boolean { |
|
const levels = ['debug', 'info', 'warn', 'error'] |
|
const currentLevelIndex = levels.indexOf(this.config.level) |
|
const messageLevelIndex = levels.indexOf(level) |
|
return messageLevelIndex >= currentLevelIndex |
|
} |
|
|
|
private formatMessage(level: LogLevel, message: string, ...args: any[]): [string, ...any[]] { |
|
const timestamp = new Date().toISOString().substring(11, 23) // HH:mm:ss.SSS |
|
const prefix = `[${timestamp}] [${level.toUpperCase()}]` |
|
return [`${prefix} ${message}`, ...args] |
|
} |
|
|
|
debug(message: string, ...args: any[]): void { |
|
if (!this.config.enableDebug || !this.shouldLog('debug')) return |
|
console.log(...this.formatMessage('debug', message, ...args)) |
|
} |
|
|
|
info(message: string, ...args: any[]): void { |
|
if (!this.shouldLog('info')) return |
|
console.log(...this.formatMessage('info', message, ...args)) |
|
} |
|
|
|
warn(message: string, ...args: any[]): void { |
|
if (!this.shouldLog('warn')) return |
|
console.warn(...this.formatMessage('warn', message, ...args)) |
|
} |
|
|
|
error(message: string, ...args: any[]): void { |
|
if (!this.shouldLog('error')) return |
|
console.error(...this.formatMessage('error', message, ...args)) |
|
} |
|
|
|
// Performance logging for development |
|
perf(message: string, ...args: any[]): void { |
|
if (!this.config.enablePerformance) return |
|
console.log(`[PERF] ${message}`, ...args) |
|
} |
|
|
|
// Group logging for related operations |
|
group(label: string, fn: () => void): void { |
|
if (!this.config.enableDebug) { |
|
fn() |
|
return |
|
} |
|
console.group(label) |
|
fn() |
|
console.groupEnd() |
|
} |
|
|
|
// Conditional logging based on environment |
|
dev(message: string, ...args: any[]): void { |
|
if (import.meta.env.DEV) { |
|
console.log(message, ...args) |
|
} |
|
} |
|
|
|
// Enable/disable debug mode at runtime |
|
setDebugMode(enabled: boolean): void { |
|
this.config.enableDebug = enabled |
|
this.config.level = enabled ? 'debug' : 'info' |
|
localStorage.setItem('jumble-debug', enabled.toString()) |
|
} |
|
|
|
// Check if debug mode is enabled |
|
isDebugEnabled(): boolean { |
|
return this.config.enableDebug |
|
} |
|
} |
|
|
|
// Create singleton instance |
|
const logger = new Logger() |
|
|
|
// Expose debug toggle for development |
|
if (import.meta.env.DEV) { |
|
;(window as any).jumbleLogger = logger |
|
} |
|
|
|
export default logger
|
|
|