first commit
This commit is contained in:
70
docs/api-stack/api/api-plugin-sse/src/otel/instruments.md
Normal file
70
docs/api-stack/api/api-plugin-sse/src/otel/instruments.md
Normal 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.
|
||||
Reference in New Issue
Block a user