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

timers.mddocs/

Timers

Integrated timer functionality for measuring operation duration with automatic labeling and formatted output. Timers provide a convenient way to measure and log execution time for operations with clear visual indicators.

Capabilities

Timer Management

Start and stop timers with automatic or custom labeling.

/**
 * Start a timer with optional custom label
 * @param label - Optional timer label (auto-generated if not provided)
 * @returns The timer label used for this timer
 */
function time(label?: string): string;

/**
 * Stop a timer and display the elapsed time
 * @param label - Optional timer label (uses most recent unlabeled timer if not provided)
 * @returns Object containing the timer label and elapsed time in milliseconds, or undefined if timer not found
 */
function timeEnd(label?: string): {label: string, span: number} | undefined;

Basic Timer Usage

Simple timer operations with automatic labeling.

Usage Examples:

const signale = require('signale');

// Start timer with auto-generated label
const label1 = signale.time();
// Output: ▶  timer_0  Initialized timer...

const label2 = signale.time();  
// Output: ▶  timer_1  Initialized timer...

// Simulate some work
setTimeout(() => {
  // End most recent timer (timer_1)
  const result1 = signale.timeEnd();
  // Output: ◼  timer_1  Timer run for: 1.02s
  console.log(result1); // {label: 'timer_1', span: 1020}
  
  // End specific timer (timer_0)  
  const result2 = signale.timeEnd('timer_0');
  // Output: ◼  timer_0  Timer run for: 1.15s
  console.log(result2); // {label: 'timer_0', span: 1150}
}, 1000);

Custom Timer Labels

Use meaningful labels for better organization and readability.

Usage Examples:

const signale = require('signale');

// Start named timers
signale.time('database-query');
// Output: ▶  database-query  Initialized timer...

signale.time('file-processing');
// Output: ▶  file-processing  Initialized timer...

signale.time('api-request');
// Output: ▶  api-request  Initialized timer...

// End specific timers by label
setTimeout(() => {
  signale.timeEnd('database-query');
  // Output: ◼  database-query  Timer run for: 245ms
  
  signale.timeEnd('file-processing'); 
  // Output: ◼  file-processing  Timer run for: 1.35s
  
  signale.timeEnd('api-request');
  // Output: ◼  api-request  Timer run for: 892ms
}, 1000);

Timer Return Values

Capture and use timer results programmatically.

Usage Examples:

const signale = require('signale');

async function processData() {
  const timerLabel = signale.time('data-processing');
  
  // Simulate data processing
  await new Promise(resolve => setTimeout(resolve, 1500));
  
  const result = signale.timeEnd(timerLabel);
  
  if (result) {
    const { label, span } = result;
    
    if (span > 1000) {
      signale.warn(`Operation ${label} took ${span}ms - consider optimization`);
    } else {
      signale.success(`Operation ${label} completed efficiently in ${span}ms`);
    }
  }
}

processData();
// Output: ▶  data-processing  Initialized timer...
//         ◼  data-processing  Timer run for: 1.50s  
//         ⚠  warning  Operation data-processing took 1500ms - consider optimization

Multiple Timer Management

Handle multiple concurrent timers with different strategies.

Usage Examples:

const signale = require('signale');

// Start multiple timers
const dbTimer = signale.time('database');
const cacheTimer = signale.time('cache');
const autoTimer1 = signale.time(); // timer_0
const autoTimer2 = signale.time(); // timer_1

setTimeout(() => {
  // End timers in different order
  signale.timeEnd('cache');        // End by name
  signale.timeEnd();              // End most recent auto-timer (timer_1)
  signale.timeEnd('database');    // End by name
  signale.timeEnd();             // End remaining auto-timer (timer_0)
}, 800);

// Output:
// ▶  database  Initialized timer...
// ▶  cache     Initialized timer...  
// ▶  timer_0   Initialized timer...
// ▶  timer_1   Initialized timer...
// ◼  cache     Timer run for: 800ms
// ◼  timer_1   Timer run for: 800ms
// ◼  database  Timer run for: 800ms  
// ◼  timer_0   Timer run for: 800ms

Timer Formatting

Timers automatically format display based on duration.

Usage Examples:

const signale = require('signale');

// Short duration (milliseconds)
signale.time('short');
setTimeout(() => {
  signale.timeEnd('short');
  // Output: ◼  short  Timer run for: 150ms
}, 150);

// Medium duration (seconds with decimals)
signale.time('medium');
setTimeout(() => {
  signale.timeEnd('medium'); 
  // Output: ◼  medium  Timer run for: 2.35s
}, 2350);

// Long duration (seconds with decimals) 
signale.time('long');
setTimeout(() => {
  signale.timeEnd('long');
  // Output: ◼  long  Timer run for: 15.67s  
}, 15670);

Timer Error Handling

Handle cases where timers don't exist or have issues.

Usage Examples:

const signale = require('signale');

// Try to end non-existent timer
const result = signale.timeEnd('non-existent');
console.log(result); // undefined (no output, no error)

// Try to end timer when no auto-timers exist
const result2 = signale.timeEnd();
console.log(result2); // undefined (no output, no error)

// Start and end the same timer twice
signale.time('duplicate-test');
const first = signale.timeEnd('duplicate-test');
console.log(first); // {label: 'duplicate-test', span: ...}

const second = signale.timeEnd('duplicate-test'); 
console.log(second); // undefined (timer already ended)

Scoped Timer Inheritance

Timers work with scoped loggers and inherit timer state.

Usage Examples:

const signale = require('signale');

// Start timer on main instance
signale.time('main-timer');

// Create scoped logger - inherits timer state
const scoped = signale.scope('module');

// Timer state is shared
scoped.timeEnd('main-timer');
// Output: [module] › ◼  main-timer  Timer run for: 1.23s

// Start timer on scoped logger
scoped.time('scoped-timer');

// End from main instance - timers are shared
signale.timeEnd('scoped-timer');
// Output: ◼  scoped-timer  Timer run for: 456ms

Practical Timer Patterns

Common patterns for using timers in applications.

Usage Examples:

const signale = require('signale');

// Function timing wrapper
function timeFunction(name, fn) {
  return async (...args) => {
    const timer = signale.time(name);
    try {
      const result = await fn(...args);
      signale.timeEnd(timer);
      return result;
    } catch (error) {
      signale.timeEnd(timer);
      signale.error(`Function ${name} failed after timing`);
      throw error;
    }
  };
}

// Usage
const timedOperation = timeFunction('data-fetch', async () => {
  // Simulate async operation
  await new Promise(resolve => setTimeout(resolve, 1000));
  return 'data';
});

timedOperation();
// Output: ▶  data-fetch  Initialized timer...
//         ◼  data-fetch  Timer run for: 1.00s

// Nested timing
async function complexOperation() {
  signale.time('total');
  
  signale.time('phase1');
  await new Promise(resolve => setTimeout(resolve, 500));
  signale.timeEnd('phase1');
  
  signale.time('phase2'); 
  await new Promise(resolve => setTimeout(resolve, 300));
  signale.timeEnd('phase2');
  
  signale.timeEnd('total');
}

complexOperation();
// Output: ▶  total   Initialized timer...
//         ▶  phase1  Initialized timer...
//         ◼  phase1  Timer run for: 500ms
//         ▶  phase2  Initialized timer...
//         ◼  phase2  Timer run for: 300ms
//         ◼  total   Timer run for: 800ms

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