CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-signale

Hackable console logger for Node.js applications with 17 out-of-the-box logger types and advanced features including integrated timers, scoped loggers, secrets filtering, and custom pluggable loggers.

Pending
Overview
Eval results
Files

scoped-loggers.mddocs/

Scoped Loggers

Create hierarchical scoped loggers with inheritance for organized logging across different modules and components. Scoped loggers help organize log output by adding contextual prefixes while maintaining all functionality of the parent logger.

Capabilities

Scope Creation

Create scoped logger instances that inherit all configuration and custom loggers from the parent.

/**
 * Create a scoped logger instance
 * @param name - One or more scope names (nested scopes supported)
 * @returns New Signale instance with the specified scope
 */
function scope(...name: string[]): Signale;

/**
 * Get the current scope name
 */
readonly scopeName: string;

Scope Removal

Remove scope from a logger instance.

/**
 * Clear the scope name from the logger
 */
function unscope(): void;

Single Scope Creation

Create loggers with a single scope identifier.

Usage Examples:

const signale = require('signale');

// Create scoped logger
const dbLogger = signale.scope('database');
dbLogger.info('Connection established');
// Output: [database] › ℹ  info  Connection established

dbLogger.success('Query executed successfully'); 
// Output: [database] › ✔  success  Query executed successfully

dbLogger.error('Connection timeout');
// Output: [database] › ✖  error  Connection timeout

Multiple Scope Levels

Create nested scopes for hierarchical organization.

Usage Examples:

const signale = require('signale');

// Create multi-level scoped logger
const apiLogger = signale.scope('api', 'v2', 'users');
apiLogger.info('Processing user request');
// Output: [api] [v2] [users] › ℹ  info  Processing user request

apiLogger.warn('Rate limit approaching');
// Output: [api] [v2] [users] › ⚠  warning  Rate limit approaching

// Create from existing scope
const authLogger = apiLogger.scope('auth');
authLogger.success('User authenticated');  
// Output: [api] [v2] [users] [auth] › ✔  success  User authenticated

Scope Inheritance

Scoped loggers inherit all properties and custom types from their parent logger.

Usage Examples:

const { Signale } = require('signale');

// Create parent logger with custom types
const parent = new Signale({
  types: {
    deploy: {
      badge: '🚀',
      color: 'magenta',
      label: 'deploy'
    }
  }
});

// Create scoped logger - inherits custom types
const prodLogger = parent.scope('production');

// Use inherited custom logger
prodLogger.deploy('Starting production deployment');
// Output: [production] › 🚀  deploy  Starting production deployment

// Use inherited default loggers
prodLogger.success('Deployment completed');
// Output: [production] › ✔  success  Deployment completed

Configuration Inheritance

Scoped loggers inherit configuration, secrets, streams, and all other settings.

Usage Examples:

const { Signale } = require('signale');

// Parent with configuration
const parent = new Signale({
  secrets: ['password123', 'secret-key'],
  logLevel: 'warn',
  stream: process.stderr
});

parent.addSecrets(['additional-secret']);

// Create scoped logger - inherits all settings
const moduleLogger = parent.scope('auth-module');

// Secrets filtering inherited
moduleLogger.warn('Login failed for password123');
// Output: [auth-module] › ⚠  warning  Login failed for [secure]

// Log level inherited
moduleLogger.info('This will not appear'); // Filtered due to warn level
moduleLogger.error('Authentication error');  // Appears

Scope Management

Manage scope names and create scope chains.

Usage Examples:

const signale = require('signale');

// Create initial scope
const appLogger = signale.scope('myapp');
console.log(appLogger.scopeName); // "myapp"

// Create nested scope
const moduleLogger = appLogger.scope('users', 'controller');
console.log(moduleLogger.scopeName); // ["myapp", "users", "controller"]

// Remove scope
moduleLogger.unscope();
moduleLogger.info('No scope now');
// Output: ℹ  info  No scope now

// Scope with array parameter
const serviceLogger = signale.scope('service-layer');  
serviceLogger.info('Service started');
// Output: [service-layer] › ℹ  info  Service started

Functional Scope Patterns

Common patterns for organizing scoped loggers in applications.

Usage Examples:

const signale = require('signale');

// Module-based scoping
function createModuleLogger(moduleName) {
  return signale.scope('app', moduleName);
}

const userLogger = createModuleLogger('users');
const orderLogger = createModuleLogger('orders');

userLogger.info('User service initialized');
// Output: [app] [users] › ℹ  info  User service initialized

orderLogger.info('Order processing started');  
// Output: [app] [orders] › ℹ  info  Order processing started

// Request-based scoping
function handleRequest(requestId) {
  const reqLogger = signale.scope('request', requestId);
  
  reqLogger.info('Processing request');
  reqLogger.success('Request completed');
  // Output: [request] [req-123] › ℹ  info  Processing request
  //         [request] [req-123] › ✔  success  Request completed
}

handleRequest('req-123');

Scope Display Configuration

Control scope display through global configuration options.

Usage Examples:

const { Signale } = require('signale');

// Disable scope display
const logger = new Signale({
  config: {
    displayScope: false
  }
});

const scoped = logger.scope('hidden');
scoped.info('Scope is hidden');
// Output: ℹ  info  Scope is hidden (no [hidden] prefix)

// Enable scope display (default)
const visible = new Signale({
  config: {
    displayScope: true
  }
});

const scopedVisible = visible.scope('visible');
scopedVisible.info('Scope is shown');
// Output: [visible] › ℹ  info  Scope is shown

Error Handling in Scopes

Scope creation error handling and validation.

Usage Examples:

const signale = require('signale');

// Error: No scope name provided
try {
  const invalid = signale.scope();
} catch (error) {
  console.error(error.message); // "No scope name was defined."
}

// Valid: Empty string handling
const emptyScoped = signale.scope('', 'valid');
emptyScoped.info('Empty strings filtered out');
// Output: [valid] › ℹ  info  Empty strings filtered out

// Array scope names are flattened
const complexScope = signale.scope('level1', 'level2');
console.log(complexScope.scopeName); // ["level1", "level2"]

Install with Tessl CLI

npx tessl i tessl/npm-signale

docs

advanced-features.md

configuration.md

core-logging.md

custom-loggers.md

index.md

scoped-loggers.md

timers.md

tile.json