JSPM

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

Production-ready observability toolkit combining OpenTelemetry instrumentation with structured Pino logging for Node.js applications

Package Exports

  • @recoverysky/wonder-logger

Readme

⭐Wonder Logger⭐

Production-ready observability toolkit combining OpenTelemetry instrumentation with structured Pino logging for Node.js applications

Build Status codecov Node.js npm version TypeScript PRs Welcome License: MIT

Overview

⭐Wonder Logger⭐ is a comprehensive observability solution that unifies structured logging and distributed tracing for Node.js applications. Built on industry-standard tools (Pino and OpenTelemetry), it provides a clean, modular API for instrumenting your applications with production-grade observability.

Key Features

  • Structured Logging - Fast, JSON-based logging with Pino
  • Distributed Tracing - Full OpenTelemetry SDK integration with automatic instrumentation
  • Metrics Collection - Prometheus and OTLP metrics exporters
  • Multiple Transports - Console, file, OpenTelemetry, and in-memory transports
  • Trace Context Correlation - Automatic injection of trace IDs into logs
  • Modular Architecture - Composable transports and exporters
  • Zero Globals - Factory pattern with no singleton state
  • Full TypeScript - Complete type definitions included
  • Production Ready - Battle-tested with 319 tests (unit + integration + E2E)

Supported Backends

  • Grafana Loki - Log aggregation
  • Grafana Tempo - Distributed tracing
  • Jaeger - Distributed tracing
  • Prometheus - Metrics collection
  • Any OTLP-compatible backend (Honeycomb, Datadog, etc.)

Installation

npm install wonder-logger
yarn add wonder-logger
pnpm add wonder-logger

Quick Start

Basic Logging

import { createLogger } from 'wonder-logger'

const logger = createLogger({
  name: 'my-service',
  level: 'info'
})

logger.info('Application started')
logger.info({ userId: 123 }, 'User logged in')
logger.error({ err: new Error('Failed') }, 'Operation failed')

OpenTelemetry Instrumentation

import { createTelemetry } from 'wonder-logger'

// Initialize telemetry BEFORE other imports
const sdk = createTelemetry({
  serviceName: 'my-api',
  serviceVersion: '1.0.0',
  environment: 'production',

  tracing: {
    exporter: 'otlp'  // or 'console', 'jaeger'
  },

  metrics: {
    exporters: ['prometheus', 'otlp'],
    port: 9090
  }
})

// Auto-instrumentation is now active!
// HTTP, Express, databases, and more are automatically traced

Combined Logging + Tracing

import { createLogger, createTelemetry, withTraceContext, withSpan } from 'wonder-logger'

// Initialize telemetry
createTelemetry({ serviceName: 'my-api' })

// Create trace-aware logger
const baseLogger = createLogger({ name: 'my-api' })
const logger = withTraceContext(baseLogger)

// Logs will include trace_id and span_id
await withSpan('process-order', async () => {
  logger.info('Processing order')
  // { level: 30, trace_id: "abc123", span_id: "def456", msg: "Processing order" }
})

Architecture

wonder-logger/
├── Logger (Pino-based)
│   ├── Transports
│   │   ├── Console (with pretty printing)
│   │   ├── File (async I/O)
│   │   ├── OpenTelemetry (OTLP)
│   │   └── Memory (queryable in-memory store)
│   └── Plugins
│       ├── Trace Context (OTEL correlation)
│       └── Morgan Stream (HTTP request logging)
│
└── OpenTelemetry
    ├── Trace Exporters
    │   ├── Console
    │   ├── OTLP (Tempo, Jaeger, Honeycomb)
    │   └── Jaeger
    ├── Metrics Exporters
    │   ├── Prometheus (pull-based)
    │   └── OTLP (push-based)
    └── Auto-Instrumentation
        └── HTTP, Express, GraphQL, databases, etc.

Documentation

Core Modules

Examples

Multiple Transports

import {
  createLogger,
  createConsoleTransport,
  createFileTransport,
  createOtelTransport
} from 'wonder-logger'

const logger = createLogger({
  name: 'my-api',
  transports: [
    createConsoleTransport({ pretty: true, level: 'debug' }),
    createFileTransport({ dir: './logs', fileName: 'app.log' }),
    createOtelTransport({
      serviceName: 'my-api',
      endpoint: 'http://localhost:4318/v1/logs'
    })
  ]
})

Express Integration

import express from 'express'
import morgan from 'morgan'
import {
  createLogger,
  createTelemetry,
  withTraceContext,
  createMorganStream,
  withSpan
} from 'wonder-logger'

// Initialize telemetry first
createTelemetry({ serviceName: 'my-api' })

// Create trace-aware logger
const logger = withTraceContext(createLogger({ name: 'my-api' }))

const app = express()

// HTTP request logging
app.use(morgan('combined', { stream: createMorganStream(logger) }))

// Request-scoped logging
app.use((req, res, next) => {
  req.logger = logger.child({ requestId: req.headers['x-request-id'] })
  next()
})

app.get('/users/:id', async (req, res) => {
  const user = await withSpan('fetch-user', async () => {
    req.logger.info({ userId: req.params.id }, 'Fetching user')
    return await db.users.findById(req.params.id)
  })

  res.json(user)
})

app.listen(3000, () => {
  logger.info({ port: 3000 }, 'Server started')
})

Memory Transport for Testing

import {
  createLogger,
  createMemoryTransport,
  getMemoryLogs
} from 'wonder-logger'

const logger = createLogger({
  name: 'test',
  transports: [createMemoryTransport({ name: 'test-logs' })]
})

logger.info({ userId: 123 }, 'User action')

// Query logs
const logs = getMemoryLogs('test-logs', {
  level: 'info',
  format: 'parsed'
})

console.log(logs[0].userId) // 123

Manual Span Instrumentation

import { withSpan } from 'wonder-logger'
import { metrics } from '@opentelemetry/api'

async function processPayment(orderId: string) {
  return withSpan('process-payment', async () => {
    // Your business logic
    const charge = await stripe.charges.create(...)

    // Record custom metrics
    const meter = metrics.getMeter('payments')
    const counter = meter.createCounter('payments_processed')
    counter.add(1, { status: 'success' })

    return charge
  })
}

API Reference

Logger

// Create logger
createLogger(options: LoggerOptions): pino.Logger

// Transports
createConsoleTransport(options?: ConsoleTransportOptions): pino.StreamEntry
createFileTransport(options?: FileTransportOptions): pino.StreamEntry
createOtelTransport(options: OtelTransportOptions): pino.StreamEntry
createMemoryTransport(options?: MemoryTransportOptions): pino.StreamEntry

// Memory transport utilities
getMemoryLogs(name: string, options?: MemoryQueryOptions): RawLogEntry[] | ParsedLogEntry[]
clearMemoryLogs(name: string): void
getMemoryLogSize(name: string): number
getAllMemoryStoreNames(): string[]

// Plugins
withTraceContext(logger: pino.Logger): pino.Logger
createMorganStream(logger: pino.Logger): NodeJS.WritableStream

OpenTelemetry

// Create telemetry SDK
createTelemetry(options: TelemetryOptions): TelemetrySDK

// Manual instrumentation
withSpan(spanName: string, fn: () => Promise<T>, tracerName?: string): Promise<T>

// SDK methods
sdk.start(): void
sdk.shutdown(): Promise<void>
sdk.forceFlush(): Promise<void>

Environment Variables

Logging

LOG_LEVEL=info  # Minimum log level (trace, debug, info, warn, error, fatal)

OpenTelemetry

# OTLP Exporter
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
OTEL_EXPORTER_OTLP_HEADERS='{"x-api-key":"secret"}'

# Jaeger Exporter
JAEGER_ENDPOINT=http://localhost:14268/api/traces

# Metrics
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:4318/v1/metrics

# General
NODE_ENV=production

Testing

⭐Wonder Logger⭐ includes comprehensive test coverage:

  • 237 unit tests - Fast, isolated component testing
  • 63 integration tests - Real behavior validation
  • 19 E2E tests - Production stack validation
# Run all tests
pnpm test

# Run by category
pnpm test:unit
pnpm test:integration
pnpm test:e2e

# Coverage reports
pnpm test:coverage
pnpm test:unit:coverage

# Watch mode
pnpm test:watch

Performance

Logging (Pino)

  • 30,000+ logs/second (JSON mode)
  • 20,000+ logs/second (pretty mode)
  • < 1ms per log entry
  • Async by default with background worker threads

OpenTelemetry

  • Negligible overhead with batching
  • Configurable sampling rates
  • Background export workers

Production Best Practices

  1. Use JSON in production

    createConsoleTransport({ pretty: false })
  2. Set appropriate log levels

    level: process.env.NODE_ENV === 'production' ? 'info' : 'debug'
  3. Use OTLP for centralized collection

    createOtelTransport({ serviceName: 'my-api' })
  4. Include trace context for correlation

    const logger = withTraceContext(baseLogger)
  5. Use structured data, not string interpolation

    logger.info({ userId, orderId }, 'Order placed')  // Good
    logger.info(`Order ${orderId} by ${userId}`)       // Bad
  6. Child loggers for scoped context

    const requestLogger = logger.child({ requestId })
  7. Configure sampling for high-volume services

    createTelemetry({
      tracing: { sampleRate: 0.1 }  // 10% sampling
    })

TypeScript

⭐Wonder Logger⭐ is written in TypeScript and provides complete type definitions:

import type {
  LoggerOptions,
  ConsoleTransportOptions,
  FileTransportOptions,
  OtelTransportOptions,
  MemoryTransportOptions,
  TelemetryOptions,
  TracingOptions,
  MetricsOptions,
  TelemetrySDK
} from 'wonder-logger'

Module Configuration

Your tsconfig.json should include:

{
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "bundler",
    "esModuleInterop": true,
    "target": "ES2022"
  }
}

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Write tests for your changes
  4. Ensure all tests pass: pnpm test
  5. Commit with descriptive messages
  6. Submit a pull request

Development Setup

# Clone repository
git clone https://github.com/jenova-marie/wonder-logger.git
cd wonder-logger

# Install dependencies
pnpm install

# Run tests
pnpm test

# Build
pnpm build

License

MIT © jenova-marie

Acknowledgments

⭐Wonder Logger⭐ is built on these excellent open-source projects:

  • Pino - Fast and low overhead logging
  • OpenTelemetry - Vendor-neutral observability framework
  • Grafana - Visualization and observability platform

Support


Made with ✨ by jenova-marie