first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
# event-logger
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`EventLogger` routes each log entry through an `EventBusLike<LoggerEvents>` emitter after the standard `AbstractLogger` pipeline (level filtering, redaction, sampling, OTel). It exists for environments where other parts of an application need to react to log events — for example, a UI component that surfaces recent errors, a test harness that asserts on emitted entries, or an aggregator that combines logs from multiple services. The emitter is injected so any conformant `EventBusLike` works (including `@suaveplan/events`' `EventBus`).
## Features
- Emits `"log"` for every accepted record
- Emits `"log:debug"`, `"log:info"`, `"log:warn"`, `"log:error"` per level
- Emits `"metrics:updated"` after every log with the current `LoggerMetrics` snapshot
- `on*/off*` helper methods for typed subscription/unsubscription
- Proper unsubscription via the `() => void` handle returned by `EventBusLike.on`
- Compatible with any `EventBusLike<LoggerEvents<TMetadata>>` — no hard dep on `@suaveplan/events`
## Usage: Basic Example
```ts
import { EventBus } from "@suaveplan/events";
import { EventLogger } from "@suaveplan/logger/event";
const bus = new EventBus();
const logger = new EventLogger(bus, { level: "info" });
logger.onError((entry) => {
alerting.report(entry.message, entry.metadata);
});
logger.error("Payment gateway unreachable");
```
## Usage: Advanced Example
```ts
import { EventBus } from "@suaveplan/events";
import { EventLogger } from "@suaveplan/logger/event";
const bus = new EventBus();
const logger = new EventLogger(bus, { level: "debug" });
// Subscribe
const handleInfo = (entry) => console.log("[INFO]", entry.message);
logger.onInfo(handleInfo);
// Log
logger.info("Started");
// Unsubscribe
logger.offInfo(handleInfo);
```
## API Reference
### `class EventLogger<TMetadata> extends AbstractLogger<TMetadata>`
**Constructor**: `new EventLogger(emitter, config?)`
| Parameter | Type | Description |
|-----------|------|-------------|
| `emitter` | `LoggerEventBus<TMetadata>` | Any `EventBusLike` conformant bus |
| `config` | `EventLoggerConfig<TMetadata>?` | Inherits all `AbstractLoggerConfig` options |
#### Subscription helpers (all return `this`)
`onLog` / `offLog`, `onDebug` / `offDebug`, `onInfo` / `offInfo`, `onWarn` / `offWarn`, `onError` / `offError`, `onMetricsUpdate` / `offMetricsUpdate`
#### `getEmitter(): LoggerEventBus<TMetadata>`
Returns the injected bus.
### `interface LoggerEvents<TMetadata>`
```ts
{
"log": LogEntry<TMetadata>;
"log:debug": LogEntry<TMetadata>;
"log:info": LogEntry<TMetadata>;
"log:warn": LogEntry<TMetadata>;
"log:error": LogEntry<TMetadata>;
"metrics:updated": LoggerMetrics;
}
```
## Implementation Notes
Unsubscription is implemented by storing the `() => void` cleanup function returned by `emitter.on()` in a `WeakMap<listener, cleanup>`. Calling `off*` looks up and invokes the cleanup. The `WeakMap` avoids memory leaks when the listener function is garbage collected without explicit unsubscription.