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,70 @@
# instruments
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Provides the canonical OpenTelemetry instrument bundle emitted by the SSE plugin. Counters and a histogram cover the four observability questions operators ask: "how many connections are live?", "how busy is each channel?", "are heartbeats firing?", and "are we shedding load under backpressure?". Instruments are lazily resolved against the global `MeterProvider` and cached so every production call site shares the same identity (a cold-start operator can install a fresh provider in tests via `resetSseInstruments()`).
## Features
- `sse.active_connections` — UpDownCounter; +1 on subscribe, −1 on close. Carries `channel` attribute so dashboards can show per-channel concurrency.
- `sse.broadcasts_total` — counter incremented on every `service.broadcast` call, partitioned by `channel`.
- `sse.heartbeats_total` — counter incremented every time the handler writes a `: heartbeat\n\n` comment frame.
- `sse.message_bytes_total` — total bytes written across every framed event (helps capacity planning).
- `sse.queue_overflow_total` — counter incremented when the handler drops events under backpressure; tags `policy` and the originating `code: SSE.QUEUE_OVERFLOW`.
- `sse.connection_duration_ms` — histogram of per-connection lifetime in milliseconds, recorded on close.
## Usage: Basic
```ts
import { getSseInstruments } from "@suaveplan/api-plugin-sse/otel/instruments";
const instruments = getSseInstruments();
instruments.broadcastsTotal.add(1, { channel: "notifications" });
```
## Usage: Advanced
```ts
import { metrics } from "@opentelemetry/api";
import {
InMemoryMetricExporter,
AggregationTemporality,
MeterProvider,
PeriodicExportingMetricReader,
} from "@opentelemetry/sdk-metrics";
import {
getSseInstruments,
resetSseInstruments,
} from "@suaveplan/api-plugin-sse/otel/instruments";
// Install a fresh provider in a test, then rebind the cache.
const exporter = new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE);
const reader = new PeriodicExportingMetricReader({
exporter,
exportIntervalMillis: 60_000,
});
const provider = new MeterProvider({ readers: [reader] });
metrics.setGlobalMeterProvider(provider);
resetSseInstruments();
const i = getSseInstruments();
i.activeConnections.add(1, { channel: "c" });
await provider.forceFlush();
console.log(exporter.getMetrics());
```
## API Reference
- `interface SseInstruments` — the bundle: `activeConnections: UpDownCounter`, `broadcastsTotal: Counter`, `heartbeatsTotal: Counter`, `messageBytesTotal: Counter`, `queueOverflowTotal: Counter`, `connectionDurationMs: Histogram`.
- `getSseInstruments(): SseInstruments` — lazily resolve the bundle against the current global `MeterProvider`; cached so subsequent calls are O(1).
- `resetSseInstruments(): void` — drop the cache so the next `getSseInstruments` rebinds. Tests call this after installing a fresh provider.
## Implementation Notes
- Instrument names use the canonical OpenTelemetry semantic conventions style (`sse.snake_case_name`). They are public — renaming is a breaking change.
- The bundle is module-level cached. A second `MeterProvider.setGlobalMeterProvider` call after `getSseInstruments` has been invoked will NOT take effect until `resetSseInstruments` runs.
- `connection_duration_ms` is recorded with the `channel` attribute so per-channel SLO dashboards work without a separate aggregator.