100% Generic Multi-Environment Logger with Advanced Configuration
A sophisticated, fully generic logging system that automatically detects its environment (browser, CLI, server) and provides optimal logging experience for any JavaScript project, with powerful file-level overrides and granular control.
- π― 100% Generic - New in v1.2.0! Zero hardcoded assumptions, works with any project type
- π Zero-Boilerplate Integration - Eliminates 200+ lines of project setup code
- π§ Auto-Discovery Components - Both camelCase and kebab-case component access
- β‘ Built-in Performance Logging - Static utilities with auto-getInstance
- π‘οΈ Non-Destructive Error Handling - Missing components log but don't break apps
- π§ Smart Environment Detection - Auto-adapts to browser, CLI, or server
- π¨ Beautiful Visual Output - Emoji, colors, and structured context display
- π± Multi-Environment - Browser console, terminal, and production JSON
- πͺ Log Store - In-memory storage for debugging and popup interfaces
- βοΈ Runtime Controls - Dynamic log level adjustment and configuration
- π Component Organization - Separate loggers for different system components
- π§ External Configuration - JSON-based configuration system
- π File-Level Overrides - Per-file and pattern-based control
- β° Timestamp Modes - Absolute, readable, relative, or disabled
- ποΈ Display Toggles - Control every aspect of log output
- π― Smart Level Resolution - Hierarchical level determination
β οΈ Breaking Change: v1.2.0 requires defining components in your logger-config.json. The logger is now 100% generic with no hardcoded assumptions.
import JSGLogger from '@crimsonsunset/jsg-logger';
// Enhanced singleton with built-in configuration loading
const logger = await JSGLogger.getInstance({
configPath: './logger-config.json'
});
// Use your project-specific components immediately
logger.api.info('Server started on port 3000');
logger.database.debug('Query executed', { query: 'SELECT * FROM users' });
logger.ui.info('Component mounted', { component: 'UserProfile' });
// Built-in static performance logging
const startTime = performance.now();
// ... do work ...
JSGLogger.logPerformance('Page Generation', startTime, 'api');
// Non-destructive error handling - missing components auto-created
const dynamicLogger = logger.getComponent('new-feature');
dynamicLogger.info('Auto-created component!'); // Works immediately
import logger from '@crimsonsunset/jsg-logger';
// Use component-specific loggers with smart level resolution
const log = logger.api;
log.info('API handler initialized', {
endpoint: 'https://api.example.com',
isReady: true
});
// Runtime controls
logger.controls.enableDebugMode(); // Enable debug for all components
logger.controls.setLevel('websocket', 'trace'); // Set specific component level
logger.controls.addFileOverride('src/popup.js', { level: 'trace' }); // File-specific control
The logger uses intelligent level resolution with the following priority:
- File Override -
fileOverrides["src/popup.js"].level
- Component Level -
components["websocket"].level
- Global Level -
globalLevel
This allows surgical debugging - you can turn on trace logging for just one problematic file while keeping everything else quiet.
{
"projectName": "My Advanced Project",
"globalLevel": "info",
"timestampMode": "absolute",
"display": {
"timestamp": true,
"emoji": true,
"component": true,
"level": false,
"message": true,
"jsonPayload": true,
"stackTrace": true
},
"components": {
"api": {
"emoji": "π",
"color": "#4A90E2",
"name": "API",
"level": "debug"
},
"database": {
"emoji": "πΎ",
"color": "#00C896",
"name": "Database",
"level": "warn"
}
},
"fileOverrides": {
"src/auth/login.js": {
"level": "trace",
"emoji": "π",
"display": {
"level": true,
"jsonPayload": true
}
},
"src/managers/*.js": {
"level": "warn",
"display": {
"jsonPayload": false
}
},
"src/popup.js": {
"level": "debug",
"timestampMode": "relative",
"display": {
"jsonPayload": false
}
}
}
}
File overrides support powerful pattern matching:
- Exact files:
"src/popup.js"
- Wildcards:
"src/managers/*.js"
- Patterns:
"src/test-*.js"
- Directories:
"src/sites/*.js"
Each override can specify:
level
- Log level for this file/patternemoji
- Custom emoji overridetimestampMode
- File-specific timestamp modedisplay
- Individual display toggles
Control how timestamps are displayed:
absolute
-22:15:30.123
(default)readable
-10:15 PM
relative
-2s ago
,5m ago
disable
- No timestamp
// Set globally
logger.controls.setTimestampMode('relative');
// Or per-file in config
"fileOverrides": {
"src/popup.js": { "timestampMode": "relative" }
}
Toggle individual parts of log output:
// Available display options
const displayConfig = {
timestamp: true, // Show/hide timestamp
emoji: true, // Show/hide level emoji
component: true, // Show/hide [COMPONENT-NAME]
level: false, // Show/hide level name (DEBUG, INFO, etc.)
message: true, // Show/hide log message
jsonPayload: true, // Show/hide context data trees
stackTrace: true // Show/hide error stack traces
};
// Runtime control
logger.controls.setDisplayOption('jsonPayload', false);
logger.controls.toggleDisplayOption('level');
logger/
βββ index.js # Main entry point with smart initialization
βββ config/
β βββ config-manager.js # Smart configuration system
β βββ default-config.json # Default configuration
β βββ component-schemes.js # Component styling definitions
βββ formatters/
β βββ browser-formatter.js # Advanced browser console output
β βββ cli-formatter.js # Terminal output with pino-colada
β βββ server-formatter.js # Production JSON logging
βββ stores/
β βββ log-store.js # In-memory log storage with filtering
βββ utils/
β βββ environment-detector.js # Environment detection
βββ examples/
βββ advanced-config.json # Full configuration example
// Different components at different levels
logger.controls.setComponentLevel('websocket', 'warn'); // Quiet websocket
logger.controls.setComponentLevel('soundcloud', 'trace'); // Verbose SoundCloud
logger.controls.setComponentLevel('popup', 'debug'); // Debug popup
// Turn on trace logging for just one problematic file
logger.controls.addFileOverride('src/sites/soundcloud.js', {
level: 'trace',
display: { level: true, jsonPayload: true }
});
// Quiet all manager files
logger.controls.addFileOverride('src/managers/*.js', {
level: 'warn',
display: { jsonPayload: false }
});
// Hide JSON payloads but keep error stacks
logger.controls.setDisplayOption('jsonPayload', false);
logger.controls.setDisplayOption('stackTrace', true);
// Show level names for debugging
logger.controls.setDisplayOption('level', true);
// Use relative timestamps for popup
logger.controls.addFileOverride('src/popup.js', {
timestampMode: 'relative'
});
logger.api.error('Request failed', {
url: window.location.href,
selectors: {
title: '.track-title',
artist: '.track-artist'
},
retryCount: 3,
lastError: error.message,
userAgent: navigator.userAgent
});
// With file override for src/sites/soundcloud.js level: "trace":
// 22:15:30.123 π¨ [API] Request failed
// ββ url: https://soundcloud.com/track/example
// ββ selectors: {title: ".track-title", artist: ".track-artist"}
// ββ retryCount: 3
// ββ lastError: "Element not found"
// ββ userAgent: "Mozilla/5.0..."
logger.controls.setLevel(component, level) // Set component level
logger.controls.getLevel(component) // Get effective level
logger.controls.setComponentLevel(component, level) // Set in config
logger.controls.enableDebugMode() // All components β debug
logger.controls.enableTraceMode() // All components β trace
logger.controls.addFileOverride(path, config) // Add file override
logger.controls.removeFileOverride(path) // Remove override
logger.controls.listFileOverrides() // List all overrides
logger.controls.setDisplayOption(option, enabled) // Set display option
logger.controls.getDisplayConfig() // Get current config
logger.controls.toggleDisplayOption(option) // Toggle option
logger.controls.setTimestampMode(mode) // Set timestamp mode
logger.controls.getTimestampMode() // Get current mode
logger.controls.getTimestampModes() // List available modes
logger.controls.refresh() // Refresh all loggers
logger.controls.reset() // Reset to defaults
logger.controls.getConfigSummary() // Get config summary
logger.controls.getStats() // Get logging stats
// Get recent logs with file context
const recentLogs = logger.logStore.getRecent(20);
const websocketLogs = logger.logStore.getByComponent('websocket', 10);
const errorLogs = logger.logStore.getByLevel(50, 5); // Errors only
// Enhanced log entries include:
// - filePath: 'src/sites/soundcloud.js'
// - effectiveLevel: 'trace'
// - component: 'soundcloud'
// - displayConfig: { timestamp: true, ... }
const stats = logger.controls.getStats();
// Returns:
// {
// total: 156,
// byLevel: { debug: 45, info: 89, warn: 15, error: 7 },
// byComponent: { soundcloud: 67, websocket: 23, popup: 66 },
// timeRange: { start: 1627846260000, end: 1627846320000 }
// }
// Direct browser logger with 100% style control:
12:00 AM π― [JSG-CORE] β¨ JSG Application v1.0.0 - Logger Ready!
12:00 AM π΅ [SOUNDCLOUD] MediaSession track change detected
ββ title: Alt-J - Breezeblocks (Gkat Remix)
ββ artist: Gkat
ββ hasArtwork: true
12:00 AM π― [JSG-CORE] π§ͺ Testing JSON context display
ββ testData: {nested: {...}, simple: 'test string', boolean: true}
ββ location: {href: 'https://soundcloud.com/discover', hostname: 'soundcloud.com'}
ββ timestamp: 2025-07-29T06:00:53.837Z
// src/sites/soundcloud.js with level: "trace" override:
12:00 AM π΅ TRACE [SOUNDCLOUD] Detailed selector matching
ββ selector: ".playButton"
ββ found: true
ββ timing: 2.3ms
// src/managers/websocket-manager.js with level: "warn" (quiet):
(no debug/info logs shown)
// src/popup.js with timestampMode: "relative":
2s ago ποΈ [POPUP] User clicked debug button
ββ component: "soundcloud"
// With display: { level: true, jsonPayload: false }:
12:00 AM π¨ ERROR [SOUNDCLOUD] Track extraction failed
// With display: { timestamp: false, level: true, jsonPayload: true }:
π¨ ERROR [SOUNDCLOUD] Track extraction failed
ββ url: https://soundcloud.com/track/example
ββ retryCount: 3
npm install @crimsonsunset/jsg-logger
Latest: v1.1.0 includes major project simplification enhancements!
The logger automatically detects its environment and uses optimal implementations:
- Browser: π BREAKTHROUGH - Custom direct logger (bypasses Pino) for 100% console styling control
- CLI: Uses pino-colada for beautiful terminal output
- Server: Uses structured JSON for production logging
Why Browser is Different: Our testing revealed that Pino's browser detection was interfering with custom formatters, especially in Chrome extensions. By creating a custom direct browser logger that bypasses Pino entirely, we achieved:
- Perfect emoji and color display
- Readable timestamp formatting (
12:00 AM
) - Beautiful JSON tree expansion
- Seamless Chrome extension integration
- Zero compromises on functionality
The browser formatter automatically detects which file is logging by analyzing the call stack, enabling seamless file override functionality.
The three-tier hierarchy (file β component β global) provides maximum flexibility with sensible defaults.
File overrides support glob patterns with *
and ?
wildcards for powerful bulk configuration.
All settings can be changed at runtime without restarting, perfect for debugging complex issues.
If you're upgrading from a basic logger:
// Before: Simple global level
logger.level = 'debug';
// After: Granular control
logger.controls.setComponentLevel('websocket', 'warn'); // Quiet websocket
logger.controls.addFileOverride('src/popup.js', { // Debug popup
level: 'debug',
timestampMode: 'relative'
});
In browser environments, runtime controls are available globally:
// Available as window.JSG_Logger
JSG_Logger.enableDebugMode();
JSG_Logger.setDisplayOption('level', true);
JSG_Logger.addFileOverride('src/popup.js', { level: 'trace' });
JSG_Logger.getStats();
This software is provided "AS IS" without warranty of any kind. Use at your own risk. The author is not responsible for any damages, data loss, or issues that may result from using this logger. See the LICENSE file for full legal terms.
License: ISC
This logger system provides the foundation for sophisticated debugging and monitoring across complex multi-file applications with surgical precision and beautiful output.