# instruments _(no submodules)_ ## Purpose Owns the rate-limit OTel instrument registry. Today the package emits exactly one counter — `api.rate_limit.exceeded_total{plugin, route, key_kind}` — which the design doc §12.4 lists as the canonical rate-limit denial signal. The factory wraps the OTel global meter-provider lookup so production gets real export when an SDK is installed and tests get a no-op when one is not. ## Features - `RATE_LIMIT_COUNTER_NAMES` frozen tuple — drives both factory construction AND the conformance test that asserts each name is present on the returned bundle. - `createRateLimitInstruments({ meterProvider? })` — explicit override precedence beats the global, so the middleware tests can assert exact `.add` call counts against an injected fake provider. - Returned object is `Object.freeze`-d so accidental mutation surfaces immediately rather than silently breaking downstream label invariants. ## Usage: Basic ```ts import { createRateLimitInstruments } from "@suaveplan/api-rate-limit/instruments"; const instruments = createRateLimitInstruments(); instruments.counters["api.rate_limit.exceeded_total"].add(1, { plugin: "billing", route: "POST /invoices", key_kind: "principal", }); ``` ## Usage: Advanced Wire a captured meter-provider to assert exactly-once denial increments under a deterministic clock: ```ts import type { MeterProvider } from "@opentelemetry/api"; import { createRateLimitInstruments } from "@suaveplan/api-rate-limit/instruments"; declare const fakeProvider: MeterProvider; // captures every .add() call const instruments = createRateLimitInstruments({ meterProvider: fakeProvider }); // drive the middleware against the fake clock, then assert // fakeProvider's recorded .add() invocations match the denial transitions ``` ## API Reference - `const RATE_LIMIT_COUNTER_NAMES: readonly ["api.rate_limit.exceeded_total"]` - `type RateLimitCounterName = (typeof RATE_LIMIT_COUNTER_NAMES)[number]` - `interface RateLimitInstruments { counters: Readonly> }` - `interface RateLimitInstrumentsConfig { meterProvider?: MeterProvider }` - `function createRateLimitInstruments(config?: RateLimitInstrumentsConfig): RateLimitInstruments` ## Implementation Notes The package deliberately does NOT install an SDK — that's an operator concern. When no SDK is registered, the OTel no-op meter-provider returns no-op counters whose `.add()` is a function-call no-op, so this module is hot-path safe even with default config. The host's own `HostInstruments` already declares the same counter name; both emit, both reach the same exporter — OTel aggregates correctly because the meter name is the only difference and the SDK merges series by name + label-set.