Minimal lightweight logging for JavaScript, adding reliable log level methods to any available console.log methods
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Create and manage multiple independent logger instances for modular applications, allowing different parts of your application to have separate logging configurations.
/**
* Create or retrieve a named logger instance
* Returns the same instance when called repeatedly with the same name
* @param {string | symbol} name - Logger name (non-empty string or symbol)
* @returns {Logger} Logger instance with independent level settings
* @throws {TypeError} When name is empty string, undefined, or invalid type
*/
getLogger(name: string | symbol): Logger;
// Type definitions
type LogLevelNumbers = 0 | 1 | 2 | 3 | 4 | 5;
type LogLevelNames = 'trace' | 'debug' | 'info' | 'warn' | 'error';
type LogLevelDesc = LogLevelNumbers | LogLevelNames | 'silent' | keyof LogLevel;
// Logger interface (individual loggers)
interface Logger {
// All logging methods
trace(...msg: any[]): void;
debug(...msg: any[]): void;
log(...msg: any[]): void;
info(...msg: any[]): void;
warn(...msg: any[]): void;
error(...msg: any[]): void;
// Level control methods
setLevel(level: LogLevelDesc, persist?: boolean): void;
getLevel(): LogLevelNumbers;
setDefaultLevel(level: LogLevelDesc): void;
resetLevel(): void;
enableAll(persist?: boolean): void;
disableAll(persist?: boolean): void;
// Plugin system
methodFactory: MethodFactory;
rebuild(): void;
// Properties
readonly levels: LogLevel;
readonly name: string | symbol;
}Usage Examples:
import log from 'loglevel';
// Create named loggers for different modules
const dbLogger = log.getLogger('database');
const apiLogger = log.getLogger('api');
const uiLogger = log.getLogger('ui');
// Each logger has independent level settings
dbLogger.setLevel('debug');
apiLogger.setLevel('info');
uiLogger.setLevel('warn');
// Use loggers independently
dbLogger.debug('Connection established'); // Shows (debug level)
apiLogger.debug('Request details'); // Hidden (info level)
apiLogger.info('API call successful'); // Shows (info level)
uiLogger.info('Button clicked'); // Hidden (warn level)
uiLogger.warn('Validation failed'); // Shows (warn level)
// Same name returns same instance
const dbLogger2 = log.getLogger('database');
console.log(dbLogger === dbLogger2); // true
// Symbol names for private loggers
const privateLogger = log.getLogger(Symbol('internal'));/**
* Get dictionary of all created loggers
* Returns object with logger names as keys and instances as values
* @returns {Object} Object mapping logger names to Logger instances
*/
getLoggers(): { [name: string]: Logger };Usage Examples:
import log from 'loglevel';
// Create some loggers
const moduleA = log.getLogger('moduleA');
const moduleB = log.getLogger('moduleB');
// Get all loggers
const allLoggers = log.getLoggers();
console.log(Object.keys(allLoggers)); // ['moduleA', 'moduleB']
// Iterate over all loggers
Object.entries(allLoggers).forEach(([name, logger]) => {
console.log(`Logger ${name} is at level ${logger.getLevel()}`);
});
// Bulk operations on all loggers
function setAllLoggersLevel(level) {
Object.values(log.getLoggers()).forEach(logger => {
logger.setLevel(level);
});
}
setAllLoggersLevel('error'); // Set all named loggers to error level/**
* Release global 'log' variable and return loglevel instance
* Resolves naming conflicts with other libraries
* @returns {RootLogger} The loglevel root logger instance
*/
noConflict(): RootLogger;Usage Examples:
// Browser environment with conflicting 'log' global
<script src="other-library-with-log.js"></script>
<script src="loglevel.min.js"></script>
<script>
// Resolve conflict and get loglevel instance
const loglevel = log.noConflict();
// Now 'log' refers to the other library
// Use 'loglevel' for loglevel functionality
loglevel.setLevel('debug');
loglevel.info('Using loglevel via noConflict');
</script>Named loggers inherit their initial level from the root logger but maintain independence:
import log from 'loglevel';
// Set root logger level
log.setLevel('warn');
// New loggers start with inherited level
const childLogger = log.getLogger('child');
console.log(childLogger.getLevel()); // 3 (warn level)
// Child can have independent level
childLogger.setLevel('debug');
console.log(log.getLevel()); // 3 (warn - unchanged)
console.log(childLogger.getLevel()); // 1 (debug - independent)
// Changing root level doesn't affect existing children
log.setLevel('error');
console.log(childLogger.getLevel()); // 1 (debug - still independent)import log from 'loglevel';
// Application modules with separate logging
class DatabaseManager {
constructor() {
this.logger = log.getLogger('database');
this.logger.setLevel('debug'); // Detailed DB logging
}
connect() {
this.logger.debug('Attempting connection...');
this.logger.info('Connected to database');
}
query(sql) {
this.logger.debug('Executing query:', sql);
}
}
class APIService {
constructor() {
this.logger = log.getLogger('api');
this.logger.setLevel('info'); // Moderate API logging
}
request(url) {
this.logger.info('API request:', url);
this.logger.debug('This debug message is hidden');
}
}
class UserInterface {
constructor() {
this.logger = log.getLogger('ui');
this.logger.setLevel('warn'); // Minimal UI logging
}
render() {
this.logger.info('This info message is hidden');
this.logger.warn('Rendering warning');
}
}
// Usage
const db = new DatabaseManager();
const api = new APIService();
const ui = new UserInterface();
db.connect(); // Shows debug and info messages
api.request('/'); // Shows info message only
ui.render(); // Shows warn message onlyNamed loggers have independent persistence with namespaced storage keys:
import log from 'loglevel';
// Root logger uses "loglevel" storage key
log.setLevel('warn');
// Named loggers use "loglevel:name" format
const moduleLogger = log.getLogger('mymodule');
moduleLogger.setLevel('debug'); // Stored as "loglevel:mymodule"
// Levels persist independently across sessions
// Root logger: localStorage["loglevel"] = "WARN"
// Named logger: localStorage["loglevel:mymodule"] = "DEBUG"
// Symbol-named loggers don't persist (no string key)
const symbolLogger = log.getLogger(Symbol('temp'));
symbolLogger.setLevel('trace'); // Not persisted