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

187 lines
20 KiB
Markdown

# @suaveplan/logger - Foundation logging package — structured JSON output, level filtering, redaction, sampling, OTel correlation, and pluggable sinks.
## Summary
Enterprise-grade structured logger for Suaveplan. Provides a full pipeline: level filtering → OTel trace enrichment → sampling → redaction → sinks. Supports multiple output strategies (console, JSON/NDJSON, event bus, storage) with buffering and backpressure.
<!-- begin:auto-docs -->
## Documentation tree
- [abstract](./src/abstract/abstract-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [abstract-logger](./src/abstract/abstract-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [console](./src/console/console-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [console-logger](./src/console/console-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [error-bridge](./src/error-bridge/error-bridge.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [error-bridge](./src/error-bridge/error-bridge.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [errors](./src/errors/logger-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [logger-error](./src/errors/logger-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [event](./src/event/event-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [event-logger](./src/event/event-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [init](./src/init/init.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [init](./src/init/init.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [otel](./src/otel/otel-context.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [otel-context](./src/otel/otel-context.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [record](./src/record/log-record.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [log-record](./src/record/log-record.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [redaction](./src/redaction/redaction.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [redaction](./src/redaction/redaction.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [sampling](./src/sampling/sampling.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [sampling](./src/sampling/sampling.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [sink](./src/sink/sink.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [buffered-sink](./src/sink/buffered-sink.md) — `BufferedSink` is an in-memory queuing wrapper around any `Sink` implementation. It decouples the hot path of log recor…
- [console-sink](./src/sink/console-sink.md) — `ConsoleSink` is the human-readable terminal output sink for `@suaveplan/logger`. It formats each `LogRecord` into a si…
- [json-sink](./src/sink/json-sink.md) — `JsonSink` is the machine-readable structured output sink for `@suaveplan/logger`. It serialises each `LogRecord` to a…
- [sink](./src/sink/sink.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [storage](./src/storage/storage-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [storage-logger](./src/storage/storage-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
<!-- end:auto-docs --> - [abstract-logger](./src/abstract/abstract-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [console](./src/console/console-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [console-logger](./src/console/console-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-bridge](./src/error-bridge/error-bridge.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-bridge](./src/error-bridge/error-bridge.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/logger-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [logger-error](./src/errors/logger-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [event](./src/event/event-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [event-logger](./src/event/event-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [init](./src/init/init.md) — <!-- begin:auto-docs --> _(no submodules)_- [init](./src/init/init.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel-context.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel-context](./src/otel/otel-context.md) — <!-- begin:auto-docs --> _(no submodules)_- [record](./src/record/log-record.md) — <!-- begin:auto-docs --> _(no submodules)_- [log-record](./src/record/log-record.md) — <!-- begin:auto-docs --> _(no submodules)_- [redaction](./src/redaction/redaction.md) — <!-- begin:auto-docs --> _(no submodules)_- [redaction](./src/redaction/redaction.md) — <!-- begin:auto-docs --> _(no submodules)_- [sampling](./src/sampling/sampling.md) — <!-- begin:auto-docs --> _(no submodules)_- [sampling](./src/sampling/sampling.md) — <!-- begin:auto-docs --> _(no submodules)_- [sink](./src/sink/sink.md) — <!-- begin:auto-docs --> _(no submodules)_- [buffered-sink](./src/sink/buffered-sink.md) — `BufferedSink` is an in-memory queuing wrapper around any `Sink` implementation. It decouples the hot path of log recor…
- [console-sink](./src/sink/console-sink.md) — `ConsoleSink` is the human-readable terminal output sink for `@suaveplan/logger`. It formats each `LogRecord` into a si…
- [json-sink](./src/sink/json-sink.md) — `JsonSink` is the machine-readable structured output sink for `@suaveplan/logger`. It serialises each `LogRecord` to a…
- [sink](./src/sink/sink.md) — <!-- begin:auto-docs --> _(no submodules)_- [storage](./src/storage/storage-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [storage-logger](./src/storage/storage-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [abstract-logger](./src/abstract/abstract-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [console](./src/console/console-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [console-logger](./src/console/console-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-bridge](./src/error-bridge/error-bridge.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-bridge](./src/error-bridge/error-bridge.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/logger-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [logger-error](./src/errors/logger-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [event](./src/event/event-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [event-logger](./src/event/event-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [init](./src/init/init.md) — <!-- begin:auto-docs --> _(no submodules)_- [init](./src/init/init.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel-context.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel-context](./src/otel/otel-context.md) — <!-- begin:auto-docs --> _(no submodules)_- [record](./src/record/log-record.md) — <!-- begin:auto-docs --> _(no submodules)_- [log-record](./src/record/log-record.md) — <!-- begin:auto-docs --> _(no submodules)_- [redaction](./src/redaction/redaction.md) — <!-- begin:auto-docs --> _(no submodules)_- [redaction](./src/redaction/redaction.md) — <!-- begin:auto-docs --> _(no submodules)_- [sampling](./src/sampling/sampling.md) — <!-- begin:auto-docs --> _(no submodules)_- [sampling](./src/sampling/sampling.md) — <!-- begin:auto-docs --> _(no submodules)_- [sink](./src/sink/sink.md) — <!-- begin:auto-docs --> _(no submodules)_- [buffered-sink](./src/sink/buffered-sink.md) — `BufferedSink` is an in-memory queuing wrapper around any `Sink` implementation. It decouples the hot path of log recor…
- [console-sink](./src/sink/console-sink.md) — `ConsoleSink` is the human-readable terminal output sink for `@suaveplan/logger`. It formats each `LogRecord` into a si…
- [json-sink](./src/sink/json-sink.md) — `JsonSink` is the machine-readable structured output sink for `@suaveplan/logger`. It serialises each `LogRecord` to a…
- [sink](./src/sink/sink.md) — <!-- begin:auto-docs --> _(no submodules)_- [storage](./src/storage/storage-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [storage-logger](./src/storage/storage-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [abstract-logger](./src/abstract/abstract-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [console](./src/console/console-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [console-logger](./src/console/console-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-bridge](./src/error-bridge/error-bridge.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-bridge](./src/error-bridge/error-bridge.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/logger-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [logger-error](./src/errors/logger-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [event](./src/event/event-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [event-logger](./src/event/event-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [init](./src/init/init.md) — <!-- begin:auto-docs --> _(no submodules)_- [init](./src/init/init.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel-context.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel-context](./src/otel/otel-context.md) — <!-- begin:auto-docs --> _(no submodules)_- [record](./src/record/log-record.md) — <!-- begin:auto-docs --> _(no submodules)_- [log-record](./src/record/log-record.md) — <!-- begin:auto-docs --> _(no submodules)_- [redaction](./src/redaction/redaction.md) — <!-- begin:auto-docs --> _(no submodules)_- [redaction](./src/redaction/redaction.md) — <!-- begin:auto-docs --> _(no submodules)_- [sampling](./src/sampling/sampling.md) — <!-- begin:auto-docs --> _(no submodules)_- [sampling](./src/sampling/sampling.md) — <!-- begin:auto-docs --> _(no submodules)_- [sink](./src/sink/sink.md) — <!-- begin:auto-docs --> _(no submodules)_- [buffered-sink](./src/sink/buffered-sink.md) — `BufferedSink` is an in-memory queuing wrapper around any `Sink` implementation. It decouples the hot path of log recor…
- [console-sink](./src/sink/console-sink.md) — `ConsoleSink` is the human-readable terminal output sink for `@suaveplan/logger`. It formats each `LogRecord` into a si…
- [json-sink](./src/sink/json-sink.md) — `JsonSink` is the machine-readable structured output sink for `@suaveplan/logger`. It serialises each `LogRecord` to a…
- [sink](./src/sink/sink.md) — <!-- begin:auto-docs --> _(no submodules)_- [storage](./src/storage/storage-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [storage-logger](./src/storage/storage-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [abstract-logger](./src/abstract/abstract-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [console](./src/console/console-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ - [console-logger](./src/console/console-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-bridge](./src/error-bridge/error-bridge.md) — <!-- begin:auto-docs --> _(no submodules)_ - [error-bridge](./src/error-bridge/error-bridge.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/logger-error.md) — <!-- begin:auto-docs --> _(no submodules)_ - [logger-error](./src/errors/logger-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [event](./src/event/event-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ - [event-logger](./src/event/event-logger.md) — <!-- begin:auto-docs --> _(no submodules)_- [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_ - [factory](./src/factory/factory.md) — <!-- begin:auto-docs --> _(no submodules)_- [init](./src/init/init.md) — <!-- begin:auto-docs --> _(no submodules)_ - [init](./src/init/init.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel-context.md) — <!-- begin:auto-docs --> _(no submodules)_ - [otel-context](./src/otel/otel-context.md) — <!-- begin:auto-docs --> _(no submodules)_- [record](./src/record/log-record.md) — <!-- begin:auto-docs --> _(no submodules)_ - [log-record](./src/record/log-record.md) — <!-- begin:auto-docs --> _(no submodules)_- [redaction](./src/redaction/redaction.md) — <!-- begin:auto-docs --> _(no submodules)_ - [redaction](./src/redaction/redaction.md) — <!-- begin:auto-docs --> _(no submodules)_- [sampling](./src/sampling/sampling.md) — <!-- begin:auto-docs --> _(no submodules)_ - [sampling](./src/sampling/sampling.md) — <!-- begin:auto-docs --> _(no submodules)_- [sink](./src/sink/sink.md) — <!-- begin:auto-docs --> _(no submodules)_ - [buffered-sink](./src/sink/buffered-sink.md) — `BufferedSink` is an in-memory queuing wrapper around any `Sink` implementation. It decouples the hot path of log recor…
- [console-sink](./src/sink/console-sink.md) — `ConsoleSink` is the human-readable terminal output sink for `@suaveplan/logger`. It formats each `LogRecord` into a si…
- [json-sink](./src/sink/json-sink.md) — `JsonSink` is the machine-readable structured output sink for `@suaveplan/logger`. It serialises each `LogRecord` to a…
- [sink](./src/sink/sink.md) — <!-- begin:auto-docs --> _(no submodules)_- [storage](./src/storage/storage-logger.md) — <!-- begin:auto-docs --> _(no submodules)_ - [storage-logger](./src/storage/storage-logger.md) — <!-- begin:auto-docs --> _(no submodules)_
## Features
- **Structured logging** — `LogRecord` with level, message, ISO timestamp, context bag, trace IDs
- **Level filtering** — `debug | info | warn | error` with hierarchical cutoff
- **OTel enrichment** — auto-injects `trace_id` / `span_id` from the active OpenTelemetry span
- **Sampling** — `HeadSampler` (deterministic FNV1a), `TailSampler` (buffered), `RuleSampler`, `SampleAll/None`
- **Redaction** — path-based and regex-pattern rules; respects `@suaveplan/error` `isSensitive()` markers
- **Pluggable sinks** — `ConsoleSink`, `JsonSink` (NDJSON), `BufferedSink` (async queue, backpressure), `MultiSink`
- **Concrete loggers** — `ConsoleLogger`, `EventLogger` (event-bus integration), `StorageLogger` (KV persistence)
- **Error bridge** — installs a global `SuaveplanError` interceptor so unhandled errors are logged automatically
- **Factory API** — `createLogger(config)` for declarative setup; `initLogger(config)` for one-call bootstrap
## Installation
```bash
bun add @suaveplan/logger
```
## Quick Start
```ts
import { initLogger } from "@suaveplan/logger/init/init";
import { ConsoleLogger } from "@suaveplan/logger/console/console-logger";
// Option 1 — factory bootstrap
const logger = initLogger({ type: "console", level: "info" });
logger.info("server started", { port: 3000 });
// Option 2 — direct construction
const log = new ConsoleLogger({ level: "debug", colors: true, timestamp: true });
log.debug("connecting", { host: "db.local" });
log.warn("slow query", { ms: 412 });
```
## Modules
| Module | Description |
|--------|-------------|
| [`src/abstract/abstract-logger`](src/abstract/abstract-logger.md) | Base pipeline class — all concrete loggers extend this |
| [`src/record/log-record`](src/record/log-record.md) | `LogRecord` type and Zod validation schemas |
| [`src/errors/logger-error`](src/errors/logger-error.md) | `LoggerError` + `LOGGER_CODES` error registry |
| [`src/otel/otel-context`](src/otel/otel-context.md) | OTel trace/span context extractor |
| [`src/sampling/sampling`](src/sampling/sampling.md) | All sampler implementations and `createSampler` factory |
| [`src/redaction/redaction`](src/redaction/redaction.md) | `RedactionEngine` and `applyRedaction` utility |
| [`src/sink/sink`](src/sink/sink.md) | Sink interface, `MultiSink`, `flushSink`, `closeSink` |
| [`src/sink/console-sink`](src/sink/console-sink.md) | ANSI-colored human-readable console output |
| [`src/sink/json-sink`](src/sink/json-sink.md) | NDJSON structured output to any writer |
| [`src/sink/buffered-sink`](src/sink/buffered-sink.md) | Async queue with configurable overflow policies |
| [`src/console/console-logger`](src/console/console-logger.md) | Ready-to-use console logger |
| [`src/event/event-logger`](src/event/event-logger.md) | Event-bus logger with per-level subscriptions |
| [`src/storage/storage-logger`](src/storage/storage-logger.md) | KV-backed persistent logger with batch flush |
| [`src/error-bridge/error-bridge`](src/error-bridge/error-bridge.md) | Global `SuaveplanError` interceptor |
| [`src/factory/factory`](src/factory/factory.md) | Declarative `createLogger` factory |
| [`src/init/init`](src/init/init.md) | One-call `initLogger` bootstrap with global accessor |
## Usage: Redaction
```ts
import { ConsoleLogger } from "@suaveplan/logger/console/console-logger";
const log = new ConsoleLogger({
level: "info",
redaction: {
rules: [
{ kind: "path", path: "user.password" },
{ kind: "pattern", pattern: /token/i },
],
},
});
log.info("login", { user: { password: "s3cr3t", email: "a@b.com" }, token: "xyz" });
// → password and token fields are replaced with "[REDACTED]"
```
## Usage: Sampling
```ts
import { createLogger } from "@suaveplan/logger/factory/factory";
const logger = createLogger({
type: "console",
level: "debug",
sampling: { kind: "head", options: { rate: 0.1 } }, // keep 10%
});
```
## Usage: Buffered JSON sink
```ts
import { BufferedSink } from "@suaveplan/logger/sink/buffered-sink";
import { JsonSink } from "@suaveplan/logger/sink/json-sink";
const inner = new JsonSink({ writer: (line) => fs.appendFileSync("app.log", line + "\n") });
const sink = new BufferedSink({ sink: inner, maxQueueSize: 1000, overflowPolicy: "drop" });
// ... on shutdown:
await sink.flush();
await sink.close();
```
## Usage: StorageLogger
```ts
import { StorageLogger } from "@suaveplan/logger/storage/storage-logger";
const logger = new StorageLogger(kvStorage, {
level: "info",
autoFlush: true,
flushInterval: 10_000,
maxBatchSize: 100,
});
logger.error("payment failed", { orderId: "ord_123" });
const recent = await logger.getLogs({ limit: 50 });
await logger.clearLogs(new Date(Date.now() - 7 * 86400_000)); // purge >7 days old
```
## Usage: Error bridge
```ts
import { installSuaveplanErrorInterceptor } from "@suaveplan/logger/error-bridge/error-bridge";
import { ConsoleLogger } from "@suaveplan/logger/console/console-logger";
const log = new ConsoleLogger({ level: "warn" });
installSuaveplanErrorInterceptor(log); // all future SuaveplanErrors are logged automatically
```
## API Reference
See each module's co-located `.md` file (linked in the table above) for full parameter and return-type documentation.
## License
Private — Suaveplan internal use only.