Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
# `instruments`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Builds the OTel instrument bundle the header tenant resolver emits on every
`resolve()` invocation. Centralising instrument creation keeps the resolver
factory free of meter plumbing — the resolver simply records against the
frozen counter returned here. The counter name (`api.tenant.resolves_total`)
follows the API plugin system design doc §6 step 4 so a missing entry
is a spec deviation a CI gate could detect.
The instrument is wired against the OTel global meter provider by default,
which falls back to a no-op implementation when no SDK is installed. Tests
need not configure a provider; production hosts register their SDK once at
boot and the resolver picks it up automatically.
## Features
- One counter: `api.tenant.resolves_total` labelled
`{ resolver: "header", outcome }`.
- `outcome` attribute drawn from a closed five-value union
(`resolved`, `absent`, `invalid`, `not_found_in_registry`,
`untrusted_source`) so dashboards can break down resolver behaviour.
- Optional `meterProvider` injection for tests that want a captive
provider; defaults to the OTel global.
## Usage: Basic
```ts
import { createHeaderResolverInstruments } from "@suaveplan/api-tenant-resolver-header/instruments";
const instruments = createHeaderResolverInstruments();
instruments.resolvesTotal.add(1, { resolver: "header", outcome: "resolved" });
```
## Usage: Advanced
```ts
import { MeterProvider } from "@opentelemetry/sdk-metrics";
import { createHeaderResolverInstruments } from "@suaveplan/api-tenant-resolver-header/instruments";
const provider = new MeterProvider();
const instruments = createHeaderResolverInstruments({
meterProvider: provider,
});
// hook instruments.meter into a Prometheus exporter to scrape
// `api_tenant_resolves_total{resolver="header",outcome="invalid"}` etc.
```
## API Reference
- `interface HeaderResolverInstruments` — `{ meter, resolvesTotal }`.
- `type HeaderResolveOutcome` — five-value union of outcome attribute
values.
- `function createHeaderResolverInstruments(config?: { meterProvider? })`
— returns a frozen instrument bundle.
## Implementation Notes
The bundle is frozen with `Object.freeze` so consumers cannot accidentally
swap the counter instance at runtime. The counter is created lazily-per-
resolver-instance rather than module-level so a host that wants different
meter providers per host instance (multi-tenant test harness) can wire each
resolver separately.
A counter — not a histogram — is the right primitive here because the
quantity being observed is the count of resolver invocations broken down by
outcome, not a duration. Resolver latency is dominated by the registry
probe; hosts that need probe latency wire a histogram around their
`TenantRegistryProbe` rather than expecting this package to time it.