@beecode/msh-logger
v2.0.2
Published
[](https://beecode.semaphoreci.com/projects/msh-logger) [
Readme
@beecode/msh-logger
Micro-service helper: logging abstraction using the Strategy Pattern
A TypeScript logging abstraction that decouples formatting from transport. Built on the Strategy Pattern with pluggable formatting strategies, transporting strategies, and ready-made presets for common setups.
- Install
- Quick Start
- Architecture
- Log Levels
- Presets
- Formatting Strategies
- Transporting Strategies
- Custom LoggerStrategyBase
- Creating Child Loggers (clone)
- API Reference
- Migrating from v1 to v2
- License
Install
npm i @beecode/msh-loggerQuick Start
import { LogLevel } from '@beecode/msh-logger'
import { PresetConsoleSimpleString } from '@beecode/msh-logger/controller/preset/console-simple-string'
const logger = new PresetConsoleSimpleString({ logLevel: LogLevel.INFO })
logger.debug('This is hidden') // filtered out (below INFO)
logger.info('Server started', { port: 3000 })
logger.warn('Deprecation warning')
logger.error('Something went wrong', new Error('boom'))Output:
2026-05-30T12:00:00.000Z - INFO: Server started { port: 3000 }
2026-05-30T12:00:00.000Z - WARN: Deprecation warning
2026-05-30T12:00:00.000Z - ERROR: Something went wrong Error: boomArchitecture
Diagram
Format-Transport Separation
The logger is built on two independent, composable strategy layers:
- FormattingStrategy — transforms log data (
level,meta,category,timestamp) plus messages into structuredFormattedLog[]objects. - TransportingStrategy — receives
FormattedLogobjects and writes them to a destination (console, Pino, stream, etc.).
The LoggerStrategyBase composes one of each. Presets pre-wire common combinations so you don't have to think about the two layers individually.
src/
├── business/
│ ├── model/
│ │ └── log-level.ts # LogLevel enum
│ └── service/
│ ├── logger-strategy.ts # LoggerStrategy interface
│ ├── logger-strategy/
│ │ └── base.ts # LoggerStrategyBase
│ ├── formatting-strategy.ts # FormattingStrategy interface
│ ├── formatting-strategy/
│ │ ├── simple-string.ts # FormattingStrategySimpleString
│ │ └── json.ts # FormattingStrategyJson
│ ├── transporting-strategy.ts # TransportingStrategy interface
│ └── transporting-strategy/
│ ├── console.ts # TransportingStrategyConsole
│ ├── pino.ts # TransportingStrategyPino
│ ├── stream.ts # TransportingStrategyStream
│ └── void.ts # TransportingStrategyVoid
└── controller/preset/ # Pre-wired presets
├── console-simple-string.ts # PresetConsoleSimpleString
├── console-json.ts # PresetConsoleJson
├── pino.ts # PresetPino
└── void.ts # PresetVoidPresets (convenience wrappers):
| Preset | Formatting | Transporting |
|--------|-----------|-------------|
| PresetConsoleSimpleString | FormattingStrategySimpleString | TransportingStrategyConsole |
| PresetConsoleJson | FormattingStrategyJson | TransportingStrategyConsole |
| PresetPino | FormattingStrategyJson | TransportingStrategyPino |
| PresetVoid | — | — (no-op) |
Log Levels
The LogLevel enum controls which messages are emitted. Higher numeric severity means more critical:
| Level | Value | Description |
|-------|-------|-------------|
| LogLevel.FATAL | 60 | Unrecoverable — the process must terminate |
| LogLevel.ERROR | 50 | Unexpected failure — a feature failed but the process can continue |
| LogLevel.WARN | 40 | Degraded behavior — unexpected but recoverable |
| LogLevel.INFO | 30 | Business-significant events — service started, user logged in |
| LogLevel.DEBUG | 20 | Diagnostic detail — request/response payloads, branching decisions |
| LogLevel.TRACE | 10 | Fine-grained flow — function entry/exit, variable dumps |
When a logger is created, it defaults to LogLevel.ERROR (most restrictive). Any log at or above the configured level is emitted; lower levels are silently dropped.
Presets
Presets are the easiest way to get started. Each pre-wires a specific formatting + transporting combination.
PresetConsoleSimpleString
Human-readable console output with timestamps. Good for local development.
import { LogLevel } from '@beecode/msh-logger'
import { PresetConsoleSimpleString } from '@beecode/msh-logger/controller/preset/console-simple-string'
const logger = new PresetConsoleSimpleString({
logLevel: LogLevel.DEBUG,
category: 'my-app',
meta: { service: 'api', version: '1.0.0' },
})Constructor params (inherits LoggerStrategyParams, omits strategies):
| Param | Type | Default | Description |
|-------|------|---------|-------------|
| logLevel | LogLevel | LogLevel.ERROR | Minimum log level to emit |
| category | string | undefined | Category label added to every log entry |
| meta | ObjectType | undefined | Metadata attached to every log entry |
Output format:
2026-05-30T12:00:00.000Z - INFO: [my-app] Hello worldPresetConsoleJson
JSON-formatted console output. Good for structured log ingestion.
import { LogLevel } from '@beecode/msh-logger'
import { PresetConsoleJson } from '@beecode/msh-logger/controller/preset/console-json'
const logger = new PresetConsoleJson({
logLevel: LogLevel.INFO,
category: 'my-app',
meta: { service: 'api' },
})Constructor params: same as PresetConsoleSimpleString.
Output format:
{"level":"INFO","timestamp":1748606400000,"category":"my-app","message":"Hello world"}When meta is provided, it is spread into the JSON payload:
{"service":"api","level":"INFO","timestamp":1748606400000,"category":"my-app","message":"Hello world"}PresetPino
Production-grade logging via Pino. Delegates formatting and transport to the Pino library.
import { LogLevel } from '@beecode/msh-logger'
import { PresetPino } from '@beecode/msh-logger/controller/preset/pino'
const logger = new PresetPino({
logLevel: LogLevel.INFO,
})Constructor params (PresetPinoParams):
| Param | Type | Default | Description |
|-------|------|---------|-------------|
| logLevel | LogLevel | LogLevel.ERROR | Minimum log level to emit |
| category | string | undefined | Category label added to every log entry |
| meta | ObjectType | undefined | Metadata attached to every log entry |
| pinoLogger | pino.Logger | pino() | Custom Pino logger instance |
PresetVoid
The default no-op logger. All log calls are silently ignored — useful for testing or disabling logging entirely.
import { PresetVoid } from '@beecode/msh-logger/controller/preset/void'
const logger = new PresetVoid()
logger.info('This does nothing')
logger.error('Neither does this')Formatting Strategies
Formatting strategies transform raw log data into FormattedLog[] objects. Each FormattedLog contains a level, message, and optional metadata.
FormattingStrategySimpleString
Human-readable format with timestamps. Produces messages like 2026-05-30T12:00:00.000Z - INFO: [category] message.
import { FormattingStrategySimpleString } from '@beecode/msh-logger/business/service/formatting-strategy/simple-string'
const formatter = new FormattingStrategySimpleString()FormattingStrategyJson
Structured JSON format. Extracts message from objects and spreads remaining keys into metadata.
import { FormattingStrategyJson } from '@beecode/msh-logger/business/service/formatting-strategy/json'
const formatter = new FormattingStrategyJson()Transporting Strategies
Transporting strategies receive FormattedLog objects and write them to a destination.
TransportingStrategyConsole
Writes to console.* methods, mapping log levels to the appropriate console function.
import { TransportingStrategyConsole } from '@beecode/msh-logger/business/service/transporting-strategy/console'
const transport = new TransportingStrategyConsole()TransportingStrategyPino
Sends logs to a Pino logger instance. Optionally inject a custom Pino logger; defaults to pino().
import { TransportingStrategyPino } from '@beecode/msh-logger/business/service/transporting-strategy/pino'
const transport = new TransportingStrategyPino() // uses default pino()
// or with a custom instance:
// const transport = new TransportingStrategyPino(customPinoLogger)TransportingStrategyStream
Writes JSON-stringified FormattedLog to any NodeJS.WritableStream. Useful for piping logs to files, HTTP streams, or custom destinations.
import { createWriteStream } from 'node:fs'
import { TransportingStrategyStream } from '@beecode/msh-logger/business/service/transporting-strategy/stream'
const stream = createWriteStream('./app.log')
const transport = new TransportingStrategyStream(stream)TransportingStrategyVoid
No-op transport. Silently drops all logs.
import { TransportingStrategyVoid } from '@beecode/msh-logger/business/service/transporting-strategy/void'
const transport = new TransportingStrategyVoid()Custom LoggerStrategyBase
Combine any formatting strategy with any transporting strategy to build a custom logger:
import { LogLevel } from '@beecode/msh-logger'
import { LoggerStrategyBase } from '@beecode/msh-logger/business/service/logger-strategy/base'
import { FormattingStrategyJson } from '@beecode/msh-logger/business/service/formatting-strategy/json'
import { TransportingStrategyStream } from '@beecode/msh-logger/business/service/transporting-strategy/stream'
import { createWriteStream } from 'node:fs'
const logger = new LoggerStrategyBase({
formattingStrategy: new FormattingStrategyJson(),
transportingStrategy: new TransportingStrategyStream(createWriteStream('./app.log')),
logLevel: LogLevel.DEBUG,
category: 'my-service',
meta: { env: 'production' },
})Constructor params (LoggerStrategyBaseParams):
| Param | Type | Default | Description |
|-------|------|---------|-------------|
| formattingStrategy | FormattingStrategy | — (required) | Strategy for formatting log data |
| transportingStrategy | TransportingStrategy | — (required) | Strategy for transporting formatted logs |
| logLevel | LogLevel | LogLevel.ERROR | Minimum log level to emit |
| category | string | undefined | Category label added to every log entry |
| meta | ObjectType | undefined | Metadata attached to every log entry |
Creating Child Loggers (clone)
Use clone() to create a child logger that inherits settings from a parent, with optional overrides:
import { LogLevel } from '@beecode/msh-logger'
import { PresetConsoleSimpleString } from '@beecode/msh-logger/controller/preset/console-simple-string'
const parent = new PresetConsoleSimpleString({
logLevel: LogLevel.INFO,
category: 'app',
meta: { service: 'api' },
})
// Child inherits everything, overrides category and adds meta
const child = parent.clone({
category: 'app:router',
meta: { route: '/users' },
})
child.info('User listed')
// Meta is shallow-merged: { service: 'api', route: '/users' }API Reference
Full API documentation is generated with TypeDoc and available in resource/doc/api/.
Public exports (from @beecode/msh-logger):
| Export | Kind | Description |
|--------|------|-------------|
| LogLevel | enum | Log level values: FATAL, ERROR, WARN, INFO, DEBUG, TRACE |
| LoggerStrategy | interface | Contract for all logger implementations |
| LoggerStrategyParams | type | Params for configuring loggers and clone() |
| ObjectType | type | Record<string, unknown> — metadata bag |
Formatting types (from @beecode/msh-logger/business/service/formatting-strategy):
| Export | Kind | Description |
|--------|------|-------------|
| FormattedLog | type | Intermediate structure: { level, message, metadata? } |
| FormattingStrategy | interface | Contract for formatting strategies |
Preset imports (via subpath):
| Import path | Export |
|-------------|--------|
| @beecode/msh-logger/controller/preset/console-simple-string | PresetConsoleSimpleString |
| @beecode/msh-logger/controller/preset/console-json | PresetConsoleJson |
| @beecode/msh-logger/controller/preset/pino | PresetPino |
| @beecode/msh-logger/controller/preset/void | PresetVoid |
Formatting strategy imports (via subpath):
| Import path | Export |
|-------------|--------|
| @beecode/msh-logger/business/service/formatting-strategy/json | FormattingStrategyJson |
| @beecode/msh-logger/business/service/formatting-strategy/simple-string | FormattingStrategySimpleString |
Transporting strategy imports (via subpath):
| Import path | Export |
|-------------|--------|
| @beecode/msh-logger/business/service/transporting-strategy/console | TransportingStrategyConsole |
| @beecode/msh-logger/business/service/transporting-strategy/pino | TransportingStrategyPino |
| @beecode/msh-logger/business/service/transporting-strategy/stream | TransportingStrategyStream |
| @beecode/msh-logger/business/service/transporting-strategy/void | TransportingStrategyVoid |
Base class import (via subpath):
| Import path | Export |
|-------------|--------|
| @beecode/msh-logger/business/service/logger-strategy/base | LoggerStrategyBase, LoggerStrategyBaseParams |
Migrating from v1 to v2
See MIGRATION.md for a complete guide covering all breaking changes and code examples.

