CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-loglevel

Minimal lightweight logging for JavaScript, adding reliable log level methods to any available console.log methods

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

multi-logger.mddocs/

Multi-Logger System

Create and manage multiple independent logger instances for modular applications, allowing different parts of your application to have separate logging configurations.

Capabilities

getLogger

/**
 * 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'));

getLoggers

/**
 * 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

noConflict

/**
 * 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>

Logger Hierarchies and Inheritance

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)

Modular Application Example

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 only

Logger Persistence

Named 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

docs

basic-logging.md

index.md

level-control.md

multi-logger.md

plugins.md

tile.json