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 forinfo, yellow forwarn, red forerror - Optional ISO timestamp prefix, dimmed for contrast in colour mode
- Optional
#tagrendering when the log record carriesctx.__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
consolemethod for each log level, preserving browser DevTools severity grouping - No external dependencies beyond the
Sinkinterface andLogRecordtypes
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.