3.4 KiB
3.4 KiB
instruments
(no submodules)
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. Carrieschannelattribute so dashboards can show per-channel concurrency.sse.broadcasts_total— counter incremented on everyservice.broadcastcall, partitioned bychannel.sse.heartbeats_total— counter incremented every time the handler writes a: heartbeat\n\ncomment 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; tagspolicyand the originatingcode: SSE.QUEUE_OVERFLOW.sse.connection_duration_ms— histogram of per-connection lifetime in milliseconds, recorded on close.
Usage: Basic
import { getSseInstruments } from "@suaveplan/api-plugin-sse/otel/instruments";
const instruments = getSseInstruments();
instruments.broadcastsTotal.add(1, { channel: "notifications" });
Usage: Advanced
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 globalMeterProvider; cached so subsequent calls are O(1).resetSseInstruments(): void— drop the cache so the nextgetSseInstrumentsrebinds. 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.setGlobalMeterProvidercall aftergetSseInstrumentshas been invoked will NOT take effect untilresetSseInstrumentsruns. connection_duration_msis recorded with thechannelattribute so per-channel SLO dashboards work without a separate aggregator.