3.7 KiB
otel/instruments
(no submodules)
Purpose
The instruments module owns the OpenTelemetry counters and histogram
emitted by every code path inside @suaveplan/api-plugin-auth. The
bundle is lazily constructed against the global MeterProvider so
operators can wire an SDK before the plugin loads without import-time
side effects, and tests can call resetAuthInstruments() between
suites to rebind against a fresh in-memory provider.
Features
- Five named instruments —
sessionsResolvedTotal,sessionResolveDurationMs,roleCheckTotal,signupsTotal,signinsTotal— bundled in oneAuthInstrumentsvalue. - Lazy global-provider binding via
metrics.getMeter(...)so the instruments resolve at first call, never at import time. resetAuthInstruments()for deterministic test setup.- Stable instrument names (
auth.*) mirrored by the spec delta so operators can scrape known metric IDs without code inspection.
Usage: Basic
import { getAuthInstruments } from "@suaveplan/api-plugin-auth/otel/instruments";
const ins = getAuthInstruments();
ins.sessionsResolvedTotal.add(1, { outcome: "authenticated" });
ins.sessionResolveDurationMs.record(durationMs, { outcome: "authenticated" });
Usage: Advanced
For testing, install an in-memory MeterProvider, then reset the
cached instruments so the next access binds against it. The plugin's
own test polyfill (tests/setup/polyfills.ts) does exactly this for
every test file in the package.
import { metrics } from "@opentelemetry/api";
import {
InMemoryMetricExporter,
MeterProvider,
PeriodicExportingMetricReader,
AggregationTemporality,
} from "@opentelemetry/sdk-metrics";
import {
getAuthInstruments,
resetAuthInstruments,
} from "@suaveplan/api-plugin-auth/otel/instruments";
const exporter = new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE);
const reader = new PeriodicExportingMetricReader({ exporter, exportIntervalMillis: 60_000 });
const provider = new MeterProvider({ readers: [reader] });
metrics.setGlobalMeterProvider(provider);
resetAuthInstruments();
const ins = getAuthInstruments();
ins.signinsTotal.add(1, { outcome: "failure" });
await provider.forceFlush();
const collected = exporter.getMetrics();
API Reference
interface AuthInstruments
sessionsResolvedTotal: Counter—auth.sessions_resolved_total.sessionResolveDurationMs: Histogram—auth.session_resolve_duration_ms(unitms).roleCheckTotal: Counter—auth.role_check_total.signupsTotal: Counter—auth.signups_total.signinsTotal: Counter—auth.signins_total.
getAuthInstruments(): AuthInstruments
Returns the cached bundle, building it on first call. Safe to call concurrently — the cache is single-writer because the function is synchronous.
resetAuthInstruments(): void
Drops the cache so the next getAuthInstruments() builds afresh
against whatever MeterProvider is currently registered.
Implementation Notes
- The module deliberately reads
metrics.getMeterlazily — calling it at import time would resolve the no-op meter before tests install their provider, which is exactly the failure mode that theresetAuthInstruments()helper exists to prevent. - Counter / histogram attribute keys (
outcome) are documented per call site rather than enforced at the meter — OpenTelemetry's attribute API is intentionally untyped, but the call-site values are string literals ("authenticated","anonymous","error","allowed","denied","success","failure") so dashboards can rely on the cardinality being bounded. - Histogram unit is
msso dashboards do not need to renormalise.