JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 35
  • Score
    100M100P100Q70808F
  • License MIT

Structured logging with multiple outputs and performance timing for TypeScript applications

Package Exports

  • @200systems/mf-logger

Readme

@200systems/mf-logger

A structured logging and error handling library for the microframework ecosystem.

Features

  • Structured Logging: JSON and pretty-print formats
  • Multiple Outputs: Console, file, and custom handlers
  • Log Levels: Debug, info, warn, error with filtering
  • Child Loggers: Contextual logging with inheritance
  • Persistent Metadata: Attach data to all logs from a logger instance
  • Performance Timing: Built-in timer functionality
  • Error Handling: Comprehensive error logging with stack traces
  • File Rotation: Automatic log file rotation with size limits
  • TypeScript: Full type safety and IntelliSense support

Installation

npm install @200systems/mf-logger

Quick Start

import { createLogger } from '@200systems/mf-logger';

const logger = createLogger();

logger.info('Application started');
logger.warn('This is a warning', { userId: '123' });
logger.error('Something went wrong', new Error('Database connection failed'));

Configuration

Basic Configuration

import { createLogger } from '@200systems/mf-logger';

const logger = createLogger({
  level: 'debug',
  format: 'json',
  context: 'my-service',
  outputs: [
    { type: 'console' },
    { 
      type: 'file', 
      options: { 
        filePath: './logs/app.log',
        maxSize: 10 * 1024 * 1024, // 10MB
        maxFiles: 5
      }
    }
  ]
});

Environment Variables

You can configure the logger using environment variables:

LOG_LEVEL=debug
LOG_FORMAT=json
NODE_ENV=production

Usage Examples

Basic Logging

logger.debug('Debug information', { query: 'SELECT * FROM users' });
logger.info('User logged in', { userId: '123', ip: '192.168.1.1' });
logger.warn('Rate limit approaching', { requests: 95, limit: 100 });
logger.error('Database error', error, { operation: 'user-fetch' });

Child Loggers

const dbLogger = logger.child('database');
const userLogger = dbLogger.child('users');

userLogger.info('Fetching user'); // Context: "database:users"

Persistent Metadata

logger.addMetadata('version', '1.0.0');
logger.addMetadata('environment', 'production');

// All subsequent logs will include this metadata
logger.info('This log includes version and environment');

Performance Timing

const endTimer = logger.startTimer('database-query');

// Perform some operation
await db.query('SELECT * FROM users');

endTimer(); // Logs: "Timer database-query completed" with duration

Custom Output Handler

const logger = createLogger({
  outputs: [
    {
      type: 'custom',
      options: {
        customHandler: async (entry) => {
          // Send to external service
          await sendToLogService(entry);
        }
      }
    }
  ]
});

File Logging with Rotation

const logger = createLogger({
  outputs: [
    {
      type: 'file',
      options: {
        filePath: './logs/app.log',
        maxSize: 5 * 1024 * 1024,  // 5MB per file
        maxFiles: 10               // Keep 10 files max
      }
    }
  ]
});

Log Entry Structure

Each log entry follows this structure:

interface LogEntry {
  timestamp: string;
  level: 'debug' | 'info' | 'warn' | 'error';
  message: string;
  context?: string;
  metadata?: Record<string, any>;
  error?: {
    name: string;
    message: string;
    stack?: string;
    code?: string | number;
  };
  request?: {
    id?: string;
    method?: string;
    url?: string;
    userAgent?: string;
    ip?: string;
  };
  performance?: {
    duration?: number;
    memory?: NodeJS.MemoryUsage;
  };
}

Output Formats

Pretty Format (Development)

2024-01-15T10:30:00.000Z INFO  [my-service] User logged in
{
  "userId": "123",
  "ip": "192.168.1.1"
}

JSON Format (Production)

{
  "timestamp": "2024-01-15T10:30:00.000Z",
  "level": "info",
  "message": "User logged in",
  "context": "my-service",
  "metadata": {
    "userId": "123",
    "ip": "192.168.1.1"
  },
  "performance": {
    "memory": { ... }
  }
}

Integration with Other Packages

This logger is designed to integrate seamlessly with other microframework packages:

// In repository layer
import { createLogger } from '@200systems/mf-logger';

export class BaseRepository {
  protected logger = createLogger().child('repository');
}

// In service layer
export class BaseService {
  protected logger = createLogger().child('service');
}

API Reference

Logger Interface

interface Logger {
  debug(message: string, metadata?: Record<string, any>): void;
  info(message: string, metadata?: Record<string, any>): void;
  warn(message: string, metadata?: Record<string, any>): void;
  error(message: string, error?: Error, metadata?: Record<string, any>): void;
  child(context: string): Logger;
  setLevel(level: LogLevel): void;
  addMetadata(key: string, value: any): void;
  startTimer(label: string): () => void;
}

Configuration Options

interface LoggerConfig {
  level: 'debug' | 'info' | 'warn' | 'error';
  format: 'json' | 'pretty';
  includeTimestamp: boolean;
  includeStack: boolean;
  context?: string;
  outputs: LogOutput[];
}

License

MIT