Skip to main content

Overview

The Logger class provides a centralized logging system for La Urban Radio Player that automatically adjusts verbosity based on the environment. It suppresses development logs in production while maintaining critical error and warning visibility.

Features

  • Automatic environment detection (development vs production)
  • Selective log suppression in production
  • Original console method preservation
  • Emoji-enhanced log levels for visual scanning
  • Global singleton instance

Constructor

const logger = new Logger();
Creates a new Logger instance with automatic environment detection and console initialization.
A global singleton is automatically created and exported:
globalThis.logger = new Logger();
You typically don’t need to construct Logger manually - use the global instance instead.

Properties

isDev
Boolean
Whether the current environment is detected as development
_originalConsole
Object
Stores original console methods (log, info, warn, error, debug) before any modifications

Environment Detection

The logger automatically detects development environments based on hostname:
_isDevelopmentEnvironment() {
  const hostname = globalThis?.location?.hostname ?? '';
  return hostname === 'localhost' || 
         hostname.startsWith('192.168.') || 
         hostname.includes('.local') ||
         hostname.endsWith('.test');
}
Development environments:
  • localhost
  • 192.168.*.* (local network)
  • *.local (mDNS domains)
  • *.test (test domains)
Production:
  • All other hostnames (e.g., laurban.com, player.laurban.com)

Methods

dev()

Logs development messages - only visible in development environments.
logger.dev(message, ...args);
message
any
required
Primary message to log
...args
any
Additional arguments to log
Example:
logger.dev('Lyrics system initialized');
logger.dev('Stream delay:', 4.5, 'seconds');
logger.dev('Config:', { delay: 4.5, interval: 100 });
Output format: [DEV] <message> <args> Behavior:
  • Development: Outputs to console.debug with [DEV] prefix
  • Production: Completely suppressed (no-op)

info()

Logs informational messages - only visible in development.
logger.info(message, ...args);
message
any
required
Primary message to log
...args
any
Additional arguments to log
Example:
logger.info('🎵 Detectado cambio de canción');
logger.info('Fetching radio data...');
Output format: ℹ️ <message> <args> Behavior:
  • Development: Outputs to console.info with ℹ️ emoji
  • Production: Completely suppressed (no-op)

success()

Logs success messages - only visible in development.
logger.success(message, ...args);
message
any
required
Primary message to log
...args
any
Additional arguments to log
Example:
logger.success('Audio player initialized');
logger.success('Connected to stream');
Output format: ✅ <message> <args> Behavior:
  • Development: Outputs to console.log with ✅ emoji
  • Production: Completely suppressed (no-op)

warn()

Logs warning messages - visible in ALL environments.
logger.warn(message, ...args);
message
any
required
Primary message to log
...args
any
Additional arguments to log
Example:
logger.warn('Stream latency detected:', latency);
logger.warn('Failed to fetch lyrics, using fallback');
Output format: ⚠️ <message> <args> Behavior:
  • Development: Outputs to console.warn with ⚠️ emoji
  • Production: Outputs to console.warn with ⚠️ emoji
  • Always visible - use for important warnings users should see

error()

Logs error messages - visible in ALL environments.
logger.error(message, ...args);
message
any
required
Primary message to log
...args
any
Additional arguments to log
Example:
logger.error('Failed to initialize audio player:', error);
logger.error('API request failed:', response.status);
Output format: ❌ <message> <args> Behavior:
  • Development: Outputs to console.error with ❌ emoji
  • Production: Outputs to console.error with ❌ emoji
  • Always visible - use for errors users/developers should see

critical()

Logs critical errors with enhanced styling - visible in ALL environments.
logger.critical(message, ...args);
message
any
required
Primary message to log
...args
any
Additional arguments to log
Example:
logger.critical('Audio context initialization failed');
logger.critical('Unable to connect to stream server');
Output format: ⚠️ CRÍTICO <message> <args> (with red background styling) Styling:
background: #ff0000;
color: white;
padding: 2px 5px;
border-radius: 3px;
Behavior:
  • Development: Outputs to console.error with styled prefix
  • Production: Outputs to console.error with styled prefix
  • Always visible with emphasis - use for critical failures requiring immediate attention

Console Modification

In production environments, the Logger modifies the global console object:
// Production behavior
console.log = () => {};      // Disabled
console.info = () => {};     // Disabled
console.debug = () => {};    // Disabled
console.warn = [original];   // Preserved
console.error = [original];  // Preserved
This prevents development logs from cluttering production consoles while maintaining critical messaging.
Modifying the global console ensures that:
  1. Third-party code logging is also suppressed in production
  2. Legacy code using raw console.log is automatically managed
  3. No code changes needed - existing console calls work transparently
  4. Critical messages (warn/error) remain visible everywhere
Original methods are preserved in _originalConsole for internal use.

Usage Examples

// Development messages
logger.dev('Player state:', playerState);
logger.info('Loading new song...');
logger.success('Song loaded successfully!');

// Production-visible messages
logger.warn('Stream quality degraded');
logger.error('Failed to load artwork:', error);
logger.critical('Audio context suspended');

Log Level Reference

MethodDevelopmentProductionIconUse Case
dev()✅ Visible❌ Hidden[DEV]Debug information, verbose logging
info()✅ Visible❌ Hiddenℹ️Informational messages, state changes
success()✅ Visible❌ HiddenSuccessful operations, confirmations
warn()✅ Visible✅ Visible⚠️Important warnings, degraded functionality
error()✅ Visible✅ VisibleErrors, failures, exceptions
critical()✅ Visible✅ Visible⚠️ CRÍTICOCritical failures requiring attention

Best Practices

  • dev(): Temporary debugging, implementation details, state dumps
  • info(): Normal operation events, user actions, data changes
  • success(): Successful completions, confirmations, milestones
  • warn(): Recoverable errors, deprecation notices, performance issues
  • error(): Failed operations, caught exceptions, validation errors
  • critical(): Unrecoverable failures, system-breaking errors
  • Logger methods are fast no-ops in production for dev/info/success
  • Complex object serialization is skipped in production automatically
  • No need to wrap logger calls in if (isDev) checks for basic usage
  • For heavy computations, use explicit checks:
    if (logger.isDev) {
      const complexData = expensiveComputation();
      logger.dev('Data:', complexData);
    }
    
Module initialization:
logger.dev('Module loading...');
// initialization code
logger.success('Module ready');
Error handling:
try {
  riskyOperation();
} catch (error) {
  logger.error('Operation failed:', error.message);
  logger.dev('Stack trace:', error.stack);
}
State tracking:
logger.info('State changed:', oldState, '->', newState);
logger.dev('Full state object:', this.state);

Global Access

The Logger is automatically available globally:
// Access anywhere in your application
logger.info('Hello from anywhere!');

// Check environment
if (logger.isDev) {
  console.log('Running in development mode');
}

// Access original console if needed
logger._originalConsole.log('Bypasses Logger modifications');

Integration with Other Modules

Both LyricsManager and CacheManager use the Logger:
// LyricsManager example
logger.dev(`🎵 LYRICS CONFIG: Delay adaptativo activado`);
logger.dev(`📱 Dispositivo: ${isIOS ? 'iOS' : 'Desktop/Android'}`);
logger.info('🎵 Detectado cambio de canción');

// CacheManager example with fallback
const logger = globalThis.logger || { /* fallback */ };
logger.info('🎥 Detectado cambio en estado de live');

Build docs developers (and LLMs) love