Files
2026-05-27 23:47:53 +01:00

3.9 KiB

console-sink

Purpose

ConsoleSink is the human-readable terminal output sink for @suaveplan/logger. It formats each LogRecord into a single coloured, prefixed line and dispatches it to the appropriate console method (console.debug, console.info, console.warn, or console.error) so that log output appears at the correct severity level in browser DevTools and Node.js terminals alike.

The sink is intentionally synchronous — write returns void, not Promise<void> — because console.* is itself synchronous and any async wrapper would introduce misleading latency for a purely I/O-synchronous operation.

Features

  • ANSI colour codes per log level: cyan for debug, green for info, yellow for warn, red for error
  • Optional ISO timestamp prefix, dimmed for contrast in colour mode
  • Optional #tag rendering when the log record carries ctx.__tags
  • Optional compact JSON metadata block printed below the message line
  • All formatting options can be toggled at construction time or by mutating public fields after construction
  • Delegates to the correct console method for each log level, preserving browser DevTools severity grouping
  • No external dependencies beyond the Sink interface and LogRecord types

Usage: Basic Example

import { ConsoleSink } from "@suaveplan/logger/sink";

const sink = new ConsoleSink(); // colors + timestamp enabled by default

sink.write({
  ts: new Date().toISOString(),
  level: "info",
  msg: "Server started",
  ctx: {},
});
// Output: [2024-01-01T00:00:00.000Z] [INFO] Server started

Usage: Advanced Example

import { ConsoleSink } from "@suaveplan/logger/sink";
import { ConsoleLogger } from "@suaveplan/logger/console";

// Plain text for CI environments (no ANSI codes in log files)
const sink = new ConsoleSink({
  colors: false,
  timestamp: true,
  includeMetadata: true,
  includeTags: true,
});

const logger = new ConsoleLogger({ sink });
logger.info("Request completed", {
  __tags: ["http", "perf"],
  duration: 42,
  status: 200,
});
// Output:
// [2024-01-01T00:00:00.000Z] [INFO] [#http #perf] Request completed
// {
//   "__tags": ["http", "perf"],
//   "duration": 42,
//   "status": 200
// }

API Reference

class ConsoleSink implements Sink

Constructor: new ConsoleSink(options?: ConsoleSinkOptions)

All options are also exposed as mutable public fields so they can be toggled after construction (e.g., to disable colours when a terminal is detected as non-interactive).

Option / Field Type Default Description
colors boolean true Wrap level and timestamp tokens in ANSI colour escapes
timestamp boolean true Prefix each line with the record's ts value
includeMetadata boolean false Append ctx as a formatted JSON block below the message
includeTags boolean true Inline ctx.__tags values as #tag tokens

Methods

  • write(record: LogRecord): void — Format and print the record synchronously. Never throws; console.* errors (which are vanishingly rare) surface as uncaught exceptions in the host environment.

Implementation Notes

ANSI escape codes are defined as a small static map keyed by LogLevel plus "reset" and "dim" sentinels. The formatter builds a parts: string[] array and joins once at the end to minimise string concatenation allocations per record.

The sink checks console[method] at call time rather than caching the reference at construction, which means it respects any console mocking that test frameworks install. This is deliberate — ConsoleSink is commonly used in test environments where console.error is wrapped to assert that no unexpected errors are logged.

Colour mode does not auto-detect process.stdout.isTTY; that decision is left to the caller (typically the factory or the logger bootstrap) so the sink itself remains environment-agnostic and testable without process environment manipulation.