npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dolasoftfree/logger

v3.1.1

Published

A comprehensive logging system with execution tracking, trace logging, and general logging capabilities

Readme

@dolasoftfree/logger

npm version npm downloads Bundle Size License: MIT

A comprehensive logging system that combines execution tracking, trace logging, and general logging capabilities into a single, unified interface with automatic production safety.

Features

  • 🚀 Multiple logging modes: Console, HTTP route, both, or none
  • 📊 Session management: Track complex operations with session-based logging
  • ⏱️ Execution tracking: Monitor step-by-step execution with timing information
  • 🔍 Trace logging: Detailed trace logs with emoji indicators
  • 🔐 Data sanitization: Automatic removal of sensitive information
  • 🌐 Environment configuration: Flexible configuration via environment variables
  • 📝 TypeScript support: Full type definitions included
  • 🔒 Production safety: Automatic console silencing in production environments
  • 🎯 Singleton pattern: Ensures consistent logging across your application

Installation

npm install @dolasoftfree/logger

Quick Start

import { getLogger } from '@dolasoftfree/logger';

// Get the logger instance
const logger = getLogger();

logger.info('Application started');
logger.debug('Debug information', { userId: 123 });
logger.warn('Warning message');
logger.error('Error occurred', new Error('Something went wrong'));

// Session-based logging
logger.startSession('user-123', 'trace');
logger.addTraceStep('start', '🚀 Starting operation');
// ... perform operations
logger.addTraceStep('complete', '✅ Operation completed');
const session = logger.endSession();

Configuration

Using the Singleton Instance

The package exports a default singleton instance for immediate use:

import { getLogger } from '@dolasoftfree/logger';

// Get logger instance
const logger = getLogger();
logger.info('Using the singleton logger');

Custom Configuration with getInstance

For custom configuration, use the getInstance method:

import { UnifiedLogger, LOG_MODES } from '@dolasoftfree/logger';

// Get configured singleton instance
const logger = UnifiedLogger.getInstance({
  logMode: LOG_MODES.BOTH,
  routeUrl: 'http://localhost:3000/api/logs',
  maxLogs: 1000,
  maxSessions: 100,
  sensitiveFields: ['password', 'token', 'secret']
});

Environment Variables

Configure the logger behavior using environment variables:

  • LOG_MODE: Set the logging mode (console, route, both, or none)
  • LOG_ROUTE_URL: Set the HTTP endpoint for remote logging
  • LOG_MAX_LOGS: Positive integer to cap in-memory logs (default 1000)
  • LOG_MAX_SESSIONS: Positive integer to cap stored sessions (default 100)
  • LOG_SENSITIVE_FIELDS: Comma-separated list of keys to redact (default: password,token,secret,key,apiKey,auth,authorization)
  • NODE_ENV: When set to production, automatically disables console output
export LOG_MODE=both
export LOG_ROUTE_URL=http://localhost:3000/api/logs
export LOG_MAX_LOGS=2000
export LOG_MAX_SESSIONS=250
export LOG_SENSITIVE_FIELDS=password,token,creditCard,ssn
export NODE_ENV=production

Precedence and Validation

  • LOG_MODE precedence: LOG_MODE (if valid) → config.logMode → default console.
  • Valid values: console, route, both, none. Invalid/empty values are ignored.
  • LOG_ROUTE_URL precedence: LOG_ROUTE_URL (if non-empty) → config.routeUrl → default http://localhost:3000/api/logs.
  • Limits precedence: LOG_MAX_LOGS/LOG_MAX_SESSIONS (valid positive int) → config.maxLogs/config.maxSessions → defaults.
  • Sanitization precedence: LOG_SENSITIVE_FIELDS (comma-separated list) → config.sensitiveFields → defaults.
  • Production behavior: see Production Safety below — console output is automatically disabled in production when applicable.

Example (invalid LOG_MODE is ignored and falls back to config):

export LOG_MODE=undefined   # ignored
import { UnifiedLogger, LOG_MODES } from '@dolasoftfree/logger';

const logger = UnifiedLogger.getInstance({ logMode: LOG_MODES.BOTH });
// Resulting mode will be 'both' because env was invalid

Log Modes

Use the exported LOG_MODES constant for type-safe configuration:

import { UnifiedLogger, LOG_MODES } from '@dolasoftfree/logger';

const logger = UnifiedLogger.getInstance({
  logMode: LOG_MODES.CONSOLE,  // 'console'
  // logMode: LOG_MODES.ROUTE,  // 'route'
  // logMode: LOG_MODES.BOTH,   // 'both'
  // logMode: LOG_MODES.NONE,   // 'none'
});

Production Safety

The logger automatically handles production environments:

  1. Automatic Production Detection: Detects when running in production via NODE_ENV
  2. Console Silencing: In production:
    • console mode → automatically switches to none
    • both mode → automatically switches to route only
    • route mode → remains unchanged
    • none mode → remains unchanged
  3. No Initialization Logs: Logger initialization messages are suppressed in production
// In production (NODE_ENV=production):
const logger = UnifiedLogger.getInstance({ 
  logMode: LOG_MODES.CONSOLE  // Automatically becomes 'none'
});

logger.info('This will not appear in console'); // Silent in production
logger.error('Even errors are silent');         // Silent in production

// But route mode still works in production:
const routeLogger = UnifiedLogger.getInstance({ 
  logMode: LOG_MODES.ROUTE,
  routeUrl: 'https://api.example.com/logs'
});

routeLogger.info('This will be sent to the API'); // Works in production

API Reference

Singleton Management

// Get the singleton instance (creates one if it doesn't exist)
UnifiedLogger.getInstance(config?: UnifiedLoggerConfig): UnifiedLogger

// Reset the singleton instance (useful for testing)
UnifiedLogger.resetInstance(): void

General Logging

logger.debug(message: string, context?: unknown, metadata?: unknown): void
logger.info(message: string, context?: unknown, metadata?: unknown): void
logger.warn(message: string, context?: unknown, metadata?: unknown): void
logger.error(message: string, error?: Error | unknown, context?: unknown, metadata?: unknown): void

Session Management

// Start a new session
logger.startSession(id: string, type?: 'trace' | 'execution' | 'general', metadata?: Record<string, unknown>): void

// End the current session
logger.endSession(): Session | null

// Get session information
logger.getCurrentSession(): Session | null
logger.getSession(id: string): Session | null
logger.getAllSessions(): Session[]

Trace Logging

// Add a trace step
logger.addTraceStep(level: 'start' | 'complete' | 'error' | 'info', message: string, metadata?: Record<string, unknown>): void

// Start a timed trace step
logger.startTraceStep(stepName: string, message: string, metadata?: Record<string, unknown>): void

// Complete a timed trace step
logger.completeTraceStep(stepName: string, message?: string, metadata?: Record<string, unknown>): void

Execution Tracking

// Start an execution step
logger.startStep(stepId: string, stepName: string, metadata?: Record<string, unknown>): void

// Complete an execution step
logger.completeStep(stepId: string, metadata?: Record<string, unknown>): void

// Mark a step as failed
logger.failStep(stepId: string, error: string): void

Specialized Methods

// Custom logging with emoji
logger.logCustom(emoji: string, message: string, metadata?: Record<string, unknown>): void

// Update session metadata dynamically
logger.updateSessionMetadata(metadata: Record<string, unknown>): void

Data Retrieval

// Get all logs
logger.getAllLogs(): LogEntry[]

// Clear old sessions (older than 1 hour)
logger.clearOldSessions(): void

Examples

For comprehensive examples and use cases, please see the Examples Documentation.

Basic Logging

import { getLogger } from '@dolasoftfree/logger';

const logger = getLogger();

// Simple logging
logger.info('Server started on port 3000');
logger.debug('Database connection established', { db: 'postgres' });

// Error logging with stack trace
try {
  // some operation
} catch (error) {
  logger.error('Operation failed', error, { operation: 'dataSync' });
}

Execution Tracking

import { getLogger } from '@dolasoftfree/logger';

const logger = getLogger();

// Start a session
logger.startSession('import-123', 'execution');

// Track individual steps
logger.startStep('step1', 'Loading data');
// ... perform loading
logger.completeStep('step1', { recordsLoaded: 1000 });

logger.startStep('step2', 'Processing data');
try {
  // ... process data
  logger.completeStep('step2', { recordsProcessed: 950 });
} catch (error) {
  logger.failStep('step2', error.message);
}

// End session
const session = logger.endSession();
console.log(`Total duration: ${session.totalDuration}ms`);

Trace Logging with Timing

import { getLogger } from '@dolasoftfree/logger';

const logger = getLogger();

logger.startSession('analysis-456', 'trace');

logger.startTraceStep('data-fetch', 'Fetching data from API');
// ... fetch data
logger.completeTraceStep('data-fetch', 'Data fetched successfully', { 
  records: 500 
});

logger.startTraceStep('data-transform', 'Transforming data');
// ... transform data
logger.completeTraceStep('data-transform');

logger.endSession();

Remote Logging

import { UnifiedLogger, LOG_MODES } from '@dolasoftfree/logger';

// Configure for remote logging
const logger = UnifiedLogger.getInstance({
  logMode: LOG_MODES.ROUTE,
  routeUrl: 'https://api.example.com/logs'
});

// All logs will be sent to the remote endpoint
logger.info('Remote log entry', { source: 'worker-1' });

Data Sanitization

import { UnifiedLogger } from '@dolasoftfree/logger';

const logger = UnifiedLogger.getInstance({
  sensitiveFields: ['password', 'creditCard', 'ssn']
});

// Sensitive fields will be automatically removed
logger.info('User login', {
  username: 'john.doe',
  password: 'secret123', // This will be removed
  timestamp: new Date()
});

Custom Domain Logging

import { getLogger } from '@dolasoftfree/logger';

const logger = getLogger();

// Start a session for your specific use case
logger.startSession('payment-processing', 'trace');

// Use custom logging for domain-specific events
logger.logCustom('💳', 'Processing payment', { amount: 99.99, currency: 'USD' });
logger.logCustom('🏦', 'Connecting to payment gateway', { provider: 'stripe' });

// Update session metadata as needed
logger.updateSessionMetadata({ 
  transactionId: 'tx_12345',
  customerType: 'premium' 
});

// Continue with your domain logic
logger.logCustom('✅', 'Payment processed successfully');
logger.endSession();

Log Modes

  1. console: Logs only to the console (automatically disabled in production)
  2. route: Logs only to the HTTP endpoint
  3. both: Logs to both console and HTTP endpoint (console disabled in production)
  4. none: Disables all logging output

Types

The package includes full TypeScript definitions:

import { 
  LogEntry, 
  Session, 
  TraceStep, 
  ExecutionStep,
  LogMode,
  UnifiedLoggerConfig,
  LOG_MODES
} from '@dolasoftfree/logger';

Testing

When writing tests, use the resetInstance method to ensure a clean state:

import { UnifiedLogger } from '@dolasoftfree/logger';

beforeEach(() => {
  UnifiedLogger.resetInstance();
});

it('should test logging', () => {
  const logger = UnifiedLogger.getInstance({ logMode: 'none' });
  // ... your tests
});

License

MIT