Skip to content

Widget Logging Guide

XCon Widget Framework provides a comprehensive logging system that allows you to effectively debug and monitor your widget behaviors.

Basic Widget Logging

Each widget instance has access to a safeLog method that provides type-safe logging with automatic console logging fallback.

Simple Logging Example

javascript
import { Widget } from '@xcons/widget';

@Widget({
  widgetName: 'MyWidget',
  selector: '.my-widget'
})
class MyWidget {
  
  init() {
    // Basic logging levels
    this.safeLog('info', 'Widget initialization started');
    this.safeLog('debug', 'Debug information', { someData: 'value' });
    this.safeLog('warn', 'Warning message');
    this.safeLog('error', 'Error occurred', new Error('Something went wrong'));
    this.safeLog('trace', 'Detailed trace information');
  }
  
  onWidgetReady(templateReady) {
    this.safeLog('info', `Widget ready - Template: ${templateReady ? 'Ready' : 'Not provided'}`);
  }
}

Log Levels

The logging system supports five log levels in order of importance:

  1. trace - Most detailed logging (🔍)
  2. debug - Debug information (🔧)
  3. info - General information (ℹ️)
  4. warn - Warning messages (⚠️)
  5. error - Error messages (❌)

Example Output

ℹ️ [XCon Widget:MyWidget] Widget initialization started
🔧 [XCon Widget:MyWidget] Debug information { someData: 'value' }
⚠️ [XCon Widget:MyWidget] Warning message
❌ [XCon Widget:MyWidget] Error occurred Error: Something went wrong

Lifecycle Logging

Automatic logging is available in widget lifecycle methods:

javascript
@Widget({
  widgetName: 'LifecycleWidget',
  selector: '.lifecycle-widget'
})
class LifecycleWidget {
  
  onWidgetInit() {
    this.safeLog('info', 'Widget init lifecycle called');
  }
  
  onWidgetReady(templateReady) {
    this.safeLog('info', 'Widget ready lifecycle called');
  }
  
  onWidgetRendered(container) {
    this.safeLog('info', 'Widget rendered lifecycle called');
  }
  
  onWidgetDestroy() {
    this.safeLog('info', 'Widget destroy lifecycle called');
  }
  
  onWidgetInitializationError(error) {
    this.safeLog('error', 'Widget initialization error', error);
  }
}

Logger Configuration

You can configure the logger in the widget decorator:

javascript
@Widget({
  widgetName: 'ConfiguredWidget',
  selector: '.configured-widget',
  logger: {
    enabled: true,           // Enable/disable logging
    level: LoggerLogLevel.DEBUG,  // Minimum log level
    timestamp: true,         // Add timestamp
    colors: true            // Colored output
  }
})
class ConfiguredWidget {
  
  init() {
    this.safeLog('debug', 'This debug message will be shown');
    this.safeLog('trace', 'This trace message will not be shown (level DEBUG)');
  }
}

Reactive Property Logging

Reactive properties automatically log changes:

javascript
import { Widget, property } from '@xcons/widget';

@Widget({
  widgetName: 'ReactiveWidget',
  selector: '.reactive-widget'
})
class ReactiveWidget {
  
  @property()
  count = 0;
  
  incrementCount() {
    this.count++; // Automatic log: "Reactive property changed: count = 1"
    this.safeLog('info', `Count incremented: ${this.count}`);
  }
}

Custom Logger Usage

For advanced use, you can access the logger instance directly:

javascript
@Widget({
  widgetName: 'AdvancedWidget',
  selector: '.advanced-widget'
})
class AdvancedWidget {
  
  performComplexOperation() {
    // Grouped logging
    this.logger?.group('Complex Operation');
    this.logger?.debug('Step 1: Initializing');
    this.logger?.debug('Step 2: Processing');
    this.logger?.info('Operation completed');
    this.logger?.groupEnd();
    
    // Table view
    const data = [
      { name: 'Ali', age: 25 },
      { name: 'Veli', age: 30 }
    ];
    this.logger?.table(data);
    
    // Time measurement
    this.logger?.time('operation-duration');
    // ... long operation
    this.logger?.timeEnd('operation-duration');
  }
}

Performance Logging

You can log performance information:

javascript
@Widget({
  widgetName: 'PerformanceWidget',
  selector: '.performance-widget'
})
class PerformanceWidget {
  
  onWidgetRendered(container) {
    const perfInfo = this.reactiveManager?.getReactiveElement()?.getPerformanceInfo();
    
    if (perfInfo) {
      this.safeLog('debug', 'Widget Performance Information', {
        reactiveProperties: perfInfo.reactivePropertiesCount,
        computedProperties: perfInfo.computedPropertiesCount,
        activeBinding: perfInfo.elementManagerStats?.activeElements
      });
    }
  }
}

Disabling Logger

You can disable logging in production environment:

javascript
@Widget({
  widgetName: 'ProductionWidget',
  selector: '.production-widget',
  logger: {
    enabled: false  // Disable all logging
  }
})
class ProductionWidget {
  
  init() {
    // These log messages will not be shown
    this.safeLog('debug', 'This debug message is invisible');
    this.safeLog('info', 'This info message is also invisible');
  }
}

Fallback Behavior

If the logger system is not available, safeLog automatically falls back to console methods:

javascript
// If logger is not available:
this.safeLog('info', 'Message');  
// Converts to: console.info('[XCon Widget:WidgetName] Message')

this.safeLog('error', 'Error', error);
// Converts to: console.error('[XCon Widget:WidgetName] Error', error)

Best Practices

  1. Write meaningful messages: Make your log messages helpful when debugging
  2. Use the right level: debug for development, info for general information, error for errors
  3. Provide additional data: Include important variables and objects in log messages
  4. Be careful in production: Be mindful not to log sensitive information
  5. Consider performance: Too many trace/debug logs can affect performance

With this logging system, you can debug your widgets more effectively and accelerate your development process.