Initial Commit
This commit is contained in:
186
packages/observability/monitor/logger/README.md
Normal file
186
packages/observability/monitor/logger/README.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# @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.
|
||||
Reference in New Issue
Block a user