npm.io
0.8.1 • Published 4d ago

@hamak/logging

Licence
MIT
Version
0.8.1
Deps
2
Size
85 kB
Vulns
0
Weekly
0

Pluggable Logging System

A comprehensive, pluggable logging system for the app-framework monorepo.

Packages

  • @hamak/logging-api - Public interfaces and types
  • @hamak/logging-spi - Service Provider Interfaces for extensions
  • @hamak/logging-impl - Core implementation

Quick Start

import { createLoggingPlugin } from '@hamak/logging-impl';
import { LogLevel } from '@hamak/logging-api';

// Create logging plugin with default configuration
const loggingPlugin = createLoggingPlugin();

// Or with custom configuration
const loggingPlugin = createLoggingPlugin({
  globalLevel: LogLevel.DEBUG,
  interceptConsole: true, // Default: true
  devFormatter: true,      // Default: true in development
  pluginLevels: {
    'my-plugin': LogLevel.TRACE
  }
});

// Use in microkernel
const host = createHost({
  plugins: [loggingPlugin, myPlugin]
});

Features

Context-Aware Logging
export const myPlugin: PluginModule = {
  initialize(ctx) {
    const logManager = ctx.resolve(LOG_MANAGER_TOKEN);
    const logger = logManager.createLogger({ plugin: 'my-plugin' });

    logger.info('Plugin initializing');
    // Output: ℹ️  INFO [my-plugin] Plugin initializing

    const childLogger = logger.child({ module: 'auth' });
    childLogger.warn('Authentication failed');
    // Output: ⚠️  WARN [my-plugin] {auth} Authentication failed
  }
};
Console Interception (Default: Enabled)

All console.log/warn/error calls automatically route through the logging system!

// With interception enabled (default)
console.log('Hello world');
// → Routes through logger.info('Hello world')

console.warn('Warning message');
// → Routes through logger.warn('Warning message')

console.error('Error occurred', new Error('details'));
// → Routes through logger.error('Error occurred', error)

Disable if needed:

const loggingPlugin = createLoggingPlugin({
  interceptConsole: false // Disable console interception
});
Performance Timing
logger.time('database-query');
await db.query('SELECT * FROM users');
logger.timeEnd('database-query');
// Output: 🐛 DEBUG {module} database-query ⏱  45ms #performance
Structured Metadata
logger.info('User logged in', {
  userId: '123',
  timestamp: Date.now(),
  tags: ['auth', 'user-event']
});
Multiple Log Levels
logger.trace('Very detailed debug info');
logger.debug('Debug information');
logger.info('General information');
logger.warn('Warning message');
logger.error('Error occurred', error);
logger.fatal('Fatal error', error);
Rich Development Output

In development mode, logs include:

  • Colors - Different colors per log level
  • Emojis - Visual indicators for each level
  • Context - Plugin/module/component hierarchy
  • Performance - Duration tracking
  • Tags - Categorization and filtering
JSON Output for Production

In production mode, logs are structured JSON:

{
  "timestamp": 1699564800000,
  "level": "INFO",
  "message": "User logged in",
  "context": {
    "plugin": "auth",
    "module": "login"
  },
  "metadata": {
    "userId": "123",
    "tags": ["auth", "user-event"]
  }
}

Configuration Options

interface LoggingPluginConfig {
  /** Global minimum log level */
  globalLevel?: LogLevel;

  /** Plugin-specific log levels */
  pluginLevels?: Record<string, LogLevel>;

  /** Module-specific log levels */
  moduleLevels?: Record<string, LogLevel>;

  /** Buffer size before forcing flush */
  bufferSize?: number; // Default: 1000

  /** Automatic flush interval in milliseconds */
  flushInterval?: number; // Default: 5000

  /** Use rich development formatter */
  devFormatter?: boolean; // Default: true in development

  /** Intercept console.log/warn/error (ENABLED BY DEFAULT) */
  interceptConsole?: boolean; // Default: true
}

Advanced Usage

Custom Transports
import { ILogTransport, LogEntry } from '@hamak/logging-api';

class MyCustomTransport implements ILogTransport {
  readonly id = 'my-transport';
  readonly name = 'My Custom Transport';

  log(entry: LogEntry): void {
    // Send to custom destination
    fetch('/api/logs', {
      method: 'POST',
      body: JSON.stringify(entry)
    });
  }
}

// Register in plugin initialization
logManager.registerTransport(new MyCustomTransport(), {
  id: 'my-transport',
  enabled: true,
  minLevel: LogLevel.WARN
});
Filtering Logs
// Only log errors from 'payment' plugin
logManager.registerTransport(transport, {
  id: 'payment-errors',
  minLevel: LogLevel.ERROR,
  plugins: ['payment']
});

// Only log entries with specific tags
logManager.registerTransport(transport, {
  id: 'analytics',
  filter: (entry) => entry.metadata?.tags?.includes('analytics')
});
Accessing Log Manager
export const myPlugin: PluginModule = {
  initialize(ctx) {
    const logManager = ctx.resolve(LOG_MANAGER_TOKEN);

    // Create logger
    const logger = logManager.createLogger({ plugin: 'my-plugin' });

    // Change log levels at runtime
    logManager.setPluginLevel('my-plugin', LogLevel.TRACE);
    logManager.setGlobalLevel(LogLevel.WARN);

    // Flush logs manually
    await logManager.flush();
  }
};

Architecture

  • SPI/API/IMPL Pattern - Clean separation of concerns
  • Dependency Injection - Loggers injected via microkernel DI
  • Pluggable Transports - Multiple output destinations
  • Event-Based - Integrates with microkernel event system
  • Performance Optimized - Buffering, batching, lazy formatting
  • Type-Safe - Full TypeScript support

Examples

See apps/demo/src/ for complete integration examples.

Documentation

License

MIT

Keywords