Appearance
Logger System - @xcons/common
The XCons Common Package logger system provides comprehensive logging capabilities with package-based logging control and global configuration support.
🚀 Quick Start
Usage with HTML (Recommended)
html
<!DOCTYPE html>
<html>
<head>
<title>My Application</title>
<!-- STEP 1: Define global configuration BEFORE loading the package -->
<script>
window.__XCONS_LOGGER_CONFIG__ = {
'@xcons/widget': {
enabled: true,
level: 3, // DEBUG level (0=ERROR, 1=WARN, 2=INFO, 3=DEBUG, 4=TRACE)
prefix: 'WIDGET',
timestamp: true,
colors: true
},
'@xcons/grid': {
enabled: true,
level: 2 // INFO level
},
'@xcons/datasource': {
enabled: false // Completely disabled
}
};
</script>
<!-- STEP 2: Load the package -->
<script src="https://unpkg.com/@xcons/common@latest/core.js"></script>
</head>
<body>
<script>
// STEP 3: Use the logger
const { logger, ComponentLogLevel } = XConsCommon;
const myLogger = logger.createChild(
'@xcons/widget',
'COMPONENT-NAME',
ComponentLogLevel.BASIC
);
myLogger.info('Application started!');
myLogger.debug('Debug information');
</script>
</body>
</html>Usage with NPM/Node.js
bash
npm install @xcons/commonjavascript
import { logger, LoggerRegistry, LoggerLogLevel } from '@xcons/common';
// Package logging configuration
LoggerRegistry.registerPackage('@xcons/widget', {
enabled: true,
level: LoggerLogLevel.DEBUG
});
// Create and use logger
const widgetLogger = logger.createChild('@xcons/widget', 'CORE');
widgetLogger.info('Widget initialized!');✨ Key Features
- 🌍 Global Configuration - Set logging rules before code loads
- 🔒 Protected Settings - Global configuration cannot be overwritten (unless force: true)
- 📦 Package-based Control - Enable/disable logging per package
- 🎯 TypeScript - Full TypeScript support
- 🚀 Universal - Works in Browser and Node.js
- 🔧 Child Loggers - Component-specific logging with namespace
- ⚡ Lightweight - Minimal dependencies
- 🎨 Configurable - Log levels and settings per package
🔧 Global Configuration (Priority System)
⚠️ Priority Rules
CRITICAL: Global configuration ALWAYS has the highest priority!
Priority Order (Highest to Lowest):
1. ✅ Global config (window.__XCONS_LOGGER_CONFIG__) - CANNOT BE OVERWRITTEN
2. ✅ Package registration - Merged with global config
3. ✅ Runtime updates - Cannot change global (unless force: true)Setting Global Configuration
Method 1: HTML (Before Package Load)
html
<!DOCTYPE html>
<html>
<head>
<!-- Define BEFORE @xcons/common loads -->
<script>
window.__XCONS_LOGGER_CONFIG__ = {
'@xcons/widget': {
enabled: true,
level: 3, // DEBUG (0=ERROR, 1=WARN, 2=INFO, 3=DEBUG, 4=TRACE)
prefix: 'WIDGET',
timestamp: true,
colors: true
},
'@xcons/grid': {
enabled: true,
level: 2 // INFO
},
'@xcons/datasource': {
enabled: false // Completely disabled
}
};
</script>
<!-- Now load the package -->
<script src="https://unpkg.com/@xcons/common@latest/core.js"></script>
</head>Method 2: Programmatic (Runtime)
javascript
import { LoggerRegistry, LoggerLogLevel } from '@xcons/common';
// Set global configuration
LoggerRegistry.setGlobalConfig({
'@xcons/widget': {
enabled: true,
level: LoggerLogLevel.DEBUG,
prefix: 'WIDGET'
},
'@xcons/grid': {
enabled: false
}
});
// This automatically reloads and applies to all packagesLog Levels Reference
javascript
LoggerLogLevel.ERROR // 0 - Errors only
LoggerLogLevel.WARN // 1 - Errors + warnings
LoggerLogLevel.INFO // 2 - Errors + warnings + info
LoggerLogLevel.DEBUG // 3 - All of the above + debug
LoggerLogLevel.TRACE // 4 - Most detailed logsConfiguration Options
typescript
interface LoggerConfig {
enabled: boolean; // Enable/disable logging
level: LoggerLogLevel; // Minimum log level (0-4)
prefix: string; // Log prefix (e.g., 'WIDGET')
timestamp: boolean; // Show timestamp
colors: boolean; // Enable colored output
}📦 Package-based Logging
Registering Packages
javascript
import { LoggerRegistry, LoggerLogLevel } from '@xcons/common';
// Enable detailed logging for widgets
LoggerRegistry.registerPackage('@xcons/widget', {
enabled: true,
level: LoggerLogLevel.DEBUG,
prefix: 'WIDGET'
});
// Disable grid logging in production
LoggerRegistry.registerPackage('@xcons/grid', {
enabled: false,
level: LoggerLogLevel.ERROR
});
// Only errors and warnings for datasource
LoggerRegistry.registerPackage('@xcons/datasource', {
enabled: true,
level: LoggerLogLevel.WARN
});Using Package Loggers
javascript
import { logger, ComponentLogLevel } from '@xcons/common';
// Create logger for @xcons/widget package
const widgetLogger = logger.createChild(
'@xcons/widget', // package namespace
'WIDGET-DECORATOR', // component name
ComponentLogLevel.DETAILED // component log level
);
// Logs respect package configuration
widgetLogger.info('Widget created');
widgetLogger.debug('Configuration loaded', { config });
widgetLogger.trace('Detailed trace'); // Only at DETAILED levelDynamic Configuration
javascript
// Standard update (respects global config)
LoggerRegistry.updatePackage('@xcons/grid', {
enabled: true,
level: LoggerLogLevel.INFO
});
// ⚠️ If global config exists, it will be preserved
// Force update (override global config)
LoggerRegistry.updatePackage('@xcons/grid', {
enabled: true,
level: LoggerLogLevel.INFO
}, true); // force=true
// ✅ This overrides global config
// Check if package has global protection
if (LoggerRegistry.hasGlobalConfig('@xcons/widget')) {
console.log('Widget is protected by global config');
}
// Get global config for specific package
const globalConfig = LoggerRegistry.getGlobalPackageConfig('@xcons/widget');
// Clear global protection
LoggerRegistry.clearGlobalConfig('@xcons/widget');
// Now package can be freely configured
// Check registration
if (LoggerRegistry.hasPackage('@xcons/widget')) {
console.log('Widget package is registered');
}
// Get package config
const config = LoggerRegistry.getPackageConfig('@xcons/widget');
// List all packages
const packages = LoggerRegistry.getRegisteredPackages();
// Get all configs
const allConfigs = LoggerRegistry.getAllConfigs();🎯 Basic Usage
Simple Logging
javascript
import { logger } from '@xcons/common';
logger.info('Application started');
logger.warn('Warning message');
logger.error('Error occurred', error);
logger.debug('Debug data', { userId: 123 });Child Loggers
javascript
// Without package (uses parent config)
const simpleLogger = logger.createChild('ComponentName');
// With package namespace
const packageLogger = logger.createChild('@xcons/widget', 'CORE');
// With component log level
const detailedLogger = logger.createChild(
'@xcons/widget',
'UI',
ComponentLogLevel.DETAILED
);Component Log Levels
javascript
import { ComponentLogLevel } from '@xcons/common';
ComponentLogLevel.OFF // 0 - No component logging
ComponentLogLevel.BASIC // 1 - Basic component logs
ComponentLogLevel.DETAILED // 2 - Detailed component logs🔥 Advanced Features
Performance Timing
javascript
const perfLogger = logger.createChild('@xcons/widget', 'PERF');
perfLogger.time('render');
// ... render logic
perfLogger.timeEnd('render'); // Logs: [@xcons/widget:PERF] render: 45.2msTable Logging
javascript
const dataLogger = logger.createChild('@xcons/datasource', 'LOADER');
dataLogger.table([
{ id: 1, name: 'Item A', status: 'active' },
{ id: 2, name: 'Item B', status: 'inactive' }
]);Grouped Logging
javascript
const widgetLogger = logger.createChild('@xcons/widget', 'MANAGER');
widgetLogger.group('Widget Initialization');
widgetLogger.info('Loading configuration');
widgetLogger.debug('Parsing options');
widgetLogger.groupEnd();🌍 Environment Setup
Development Environment
javascript
import { LoggerRegistry, LoggerLogLevel } from '@xcons/common';
// Development - detailed logging
LoggerRegistry.registerPackage('@xcons/widget', {
enabled: true,
level: LoggerLogLevel.TRACE,
colors: true,
timestamp: true
});
LoggerRegistry.registerPackage('@xcons/grid', {
enabled: true,
level: LoggerLogLevel.DEBUG
});Production Environment
javascript
// Production - minimal logging
LoggerRegistry.registerPackage('@xcons/widget', {
enabled: true,
level: LoggerLogLevel.WARN, // Only warnings and errors
colors: false
});
LoggerRegistry.registerPackage('@xcons/grid', {
enabled: false // Completely disabled
});Environment-based Configuration
html
<script>
// Environment detection
const isDev = window.location.hostname === 'localhost' ||
window.location.hostname === '127.0.0.1';
// Configure based on environment
window.__XCONS_LOGGER_CONFIG__ = isDev ? {
// Development settings
'@xcons/widget': { enabled: true, level: 3 },
'@xcons/grid': { enabled: true, level: 3 },
'@xcons/datasource': { enabled: true, level: 3 }
} : {
// Production settings
'@xcons/widget': { enabled: true, level: 1 },
'@xcons/grid': { enabled: false, level: 0 },
'@xcons/datasource': { enabled: false, level: 0 }
};
</script>💼 Real World Example
javascript
import {
logger,
LoggerRegistry,
LoggerLogLevel,
ComponentLogLevel
} from '@xcons/common';
// Register package with global config
LoggerRegistry.registerPackage('@xcons/widget', {
enabled: true,
level: LoggerLogLevel.DEBUG
});
// Widget class with package logger
export class Widget {
private logger = logger.createChild(
'@xcons/widget',
'WIDGET-CORE',
ComponentLogLevel.BASIC
);
constructor(private id: string) {
this.logger.info('Widget created', { id });
}
async initialize() {
this.logger.debug('Initializing widget');
this.logger.time('init');
try {
await this.loadConfig();
await this.setupUI();
this.logger.info('Widget ready');
} catch (error) {
this.logger.error('Initialization failed', error);
throw error;
} finally {
this.logger.timeEnd('init');
}
}
private async loadConfig() {
this.logger.debug('Loading configuration');
// Config loading logic
}
private async setupUI() {
this.logger.debug('Setting up UI');
// UI setup logic
}
}
// Usage
const widget = new Widget('widget-1');
await widget.initialize();🔍 Debug and Global Access
Browser Console
javascript
// Access logger registry
window.__XCONS_LOGGER_REGISTRY__
// Display all package configs
LoggerRegistry.getAllConfigs()
// Display global config
LoggerRegistry.getGlobalConfigSnapshot()
// Enable package instantly (if not protected)
LoggerRegistry.updatePackage('@xcons/grid', {
enabled: true,
level: 3
})
// Force enable (override global config)
LoggerRegistry.updatePackage('@xcons/grid', {
enabled: true,
level: 3
}, true)
// List registered packages
LoggerRegistry.getRegisteredPackages()
// Check global protection
LoggerRegistry.hasGlobalConfig('@xcons/widget')
// Clear global protection
LoggerRegistry.clearGlobalConfig('@xcons/widget')Node.js
javascript
// Access global logger
global.__XCONS_LOGGER_REGISTRY__📚 Complete HTML Example
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XCons Common - Complete Example</title>
<!-- STEP 1: Global Configuration -->
<script>
// Environment detection
const isDev = location.hostname === 'localhost';
// Global logger configuration
window.__XCONS_LOGGER_CONFIG__ = {
'@xcons/widget': {
enabled: true,
level: isDev ? 3 : 1, // DEBUG in dev, WARN in prod
prefix: 'WIDGET',
timestamp: true,
colors: true
},
'@xcons/grid': {
enabled: isDev, // Only in development
level: 3,
prefix: 'GRID'
},
'@xcons/datasource': {
enabled: true,
level: 2, // INFO level
prefix: 'DS'
}
};
</script>
<!-- STEP 2: Load Package -->
<script src="https://unpkg.com/@xcons/common@latest/core.js"></script>
</head>
<body>
<h1>XCons Common Logger Example</h1>
<button onclick="testLogs()">Test Logs</button>
<button onclick="showConfigs()">Show Configs</button>
<script>
// STEP 3: Import and Usage
const {
logger,
LoggerRegistry,
LoggerLogLevel,
ComponentLogLevel
} = XConsCommon;
// Create loggers for different packages
const widgetLogger = logger.createChild(
'@xcons/widget',
'UI-COMPONENT',
ComponentLogLevel.BASIC
);
const gridLogger = logger.createChild(
'@xcons/grid',
'DATA-GRID',
ComponentLogLevel.DETAILED
);
const dsLogger = logger.createChild(
'@xcons/datasource',
'API-CLIENT'
);
// Test function
function testLogs() {
console.clear();
// Widget logs (level: WARN in prod, DEBUG in dev)
widgetLogger.error('Widget error message');
widgetLogger.warn('Widget warning message');
widgetLogger.info('Widget info message');
widgetLogger.debug('Widget debug message');
// Grid logs (disabled in production)
gridLogger.info('Grid initialized');
gridLogger.debug('Grid rendering data');
// Datasource logs (INFO level)
dsLogger.info('Fetching data from API');
dsLogger.debug('API response received');
}
// Show configurations
function showConfigs() {
console.group('📋 Logger Configurations');
console.log('Global Config:',
LoggerRegistry.getGlobalConfigSnapshot());
console.log('All Configs:',
LoggerRegistry.getAllConfigs());
console.log('Registered Packages:',
LoggerRegistry.getRegisteredPackages());
console.groupEnd();
}
// Run automatically on load
window.addEventListener('load', () => {
widgetLogger.info('Application loaded successfully! 🎉');
showConfigs();
});
</script>
</body>
</html>📖 API Reference
LoggerRegistry
| Method | Description |
|---|---|
setGlobalConfig(config) | Set global configuration programmatically |
getGlobalConfigSnapshot() | Get current global configuration |
registerPackage(name, config, force?) | Register package with config |
getPackageConfig(name) | Get package configuration |
hasPackage(name) | Check if package is registered |
hasGlobalConfig(name) | Check if package has global protection |
getGlobalPackageConfig(name) | Get global config for specific package |
clearGlobalConfig(name) | Clear global protection for package |
clearAllGlobalConfigs() | Clear all global protections |
unregisterPackage(name) | Remove package from registry |
updatePackage(name, config, force?) | Update package configuration |
getRegisteredPackages() | Get all registered packages |
getAllConfigs() | Get all package configs |
reloadFromGlobal() | Reload from global config |
clear() | Clear all packages |
CoreLogger
| Method | Description |
|---|---|
createChild(namespace, component?, level?) | Create child logger with package support |
configure(config) | Update logger configuration |
setLevel(level) | Set minimum log level |
enable() / disable() | Enable/disable logging |
getConfig() | Get current configuration |
ChildLogger
| Method | Description |
|---|---|
info(message, ...data) | Info level logging |
warn(message, ...data) | Warning level logging |
error(message, ...data) | Error level logging |
debug(message, ...data) | Debug level logging |
trace(message, ...data) | Trace level logging |
group(title) / groupEnd() | Group related logs |
time(label) / timeEnd(label) | Measure execution time |
table(data) | Display data in table format |
getNamespace() | Get package namespace |
getComponentName() | Get component name |
🌍 Browser Support
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
🔧 Node.js Support
- Node.js 16+
💡 Tips and Best Practices
1. Global Configuration Priority
javascript
// ✅ GOOD: Define global config before package loads
window.__XCONS_LOGGER_CONFIG__ = { /* ... */ };
// <script src="@xcons/common"></script>
// ❌ BAD: Try to change after package loads (requires force)
LoggerRegistry.updatePackage('@xcons/widget', config); // Global config is preserved2. Environment Based Configuration
javascript
// Different settings for Development and Production
const logConfig = process.env.NODE_ENV === 'production' ? {
level: LoggerLogLevel.WARN,
colors: false
} : {
level: LoggerLogLevel.TRACE,
colors: true
};3. Package Naming
javascript
// ✅ GOOD: Consistent package naming
'@xcons/widget'
'@xcons/grid'
'@xcons/datasource'
// ❌ BAD: Inconsistent naming
'widget-package'
'GridModule'
'DS_SOURCE'4. Component Log Levels
javascript
// OFF for performance critical components
const perfCritical = logger.createChild('@xcons/widget', 'RENDER', ComponentLogLevel.OFF);
// DETAILED for components that need debugging
const debugComponent = logger.createChild('@xcons/widget', 'DEBUG', ComponentLogLevel.DETAILED);💡 Tip: The logger system automatically detects browser and Node.js environments and applies appropriate formatting. Colored outputs during development, optimized logs in production.
🔗 Global Access: You can always access the logger instance via
window.__XCONS_LOGGER_REGISTRY__(browser) orglobal.__XCONS_LOGGER_REGISTRY__(Node.js).