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,63 @@
# `otel/instruments.ts`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Owns the lazy-built OpenTelemetry instrument bundle (`SiteInstruments`) that every observable code path in `@suaveplan/api-plugin-site` emits to. Instruments are constructed against the global `MeterProvider` on first call and cached so each call to `getSiteInstruments()` reuses the same `Counter`/`Histogram` handles. `resetSiteInstruments()` drops the cache so tests can install a fresh `MeterProvider` and re-bind against it — the canonical suaveplan pattern used by every other plugin's OTel module.
## Features
- `sitesCreatedTotal{outcome}` counter — `success` | `error`.
- `sitesUpdatedTotal{kind}` counter — `settings` | `fields` | `state` | `domain`.
- `domainResolutionsTotal{outcome}` counter — `hit` | `miss` | `error`.
- `domainResolutionDurationMs` histogram — wall-clock ms.
- `bootstrapFailedTotal` counter — incremented when `createDefaultSite` fails during an `organization:created` event.
- Cache reset for test rebinding via `resetSiteInstruments()`.
## Usage: Basic
```ts
import { getSiteInstruments } from "@suaveplan/api-plugin-site/otel/instruments";
const inst = getSiteInstruments();
inst.sitesCreatedTotal.add(1, { outcome: "success" });
```
## Usage: Advanced
```ts
import { MeterProvider } from "@opentelemetry/sdk-metrics";
import { metrics } from "@opentelemetry/api";
import {
getSiteInstruments,
resetSiteInstruments,
} from "@suaveplan/api-plugin-site/otel/instruments";
beforeAll(() => {
const mp = new MeterProvider();
metrics.setGlobalMeterProvider(mp);
resetSiteInstruments();
});
it("counts a resolution miss", () => {
const inst = getSiteInstruments();
inst.domainResolutionsTotal.add(1, { outcome: "miss" });
});
```
## API Reference
- `interface SiteInstruments` — five readonly handles.
- `getSiteInstruments(): SiteInstruments` — lazy + cached.
- `resetSiteInstruments(): void` — drop cache so the next call rebinds.
## Implementation Notes
- The cache lives at module scope. Reset is required between tests that swap the global provider — without it, an old handle pinned to a destroyed provider would record forever into the void.
- Metric names follow `<package>.<noun>_total` / `_duration_ms` convention so dashboards can grep across plugins consistently.
- The histogram unit is `ms` so collectors can render p50/p95/p99 latency without additional conversion.
- The counter / histogram handles returned by `getSiteInstruments()` are safe to retain across requests — they are thin proxies over the underlying `MeterProvider`'s metric registry, and recreating them on every call would defeat the purpose of OTel's batched export pipeline. Tests that swap providers therefore MUST call `resetSiteInstruments()` before the next read so the next handle points at the new provider.
- This module avoids any side effects at import time so consumers can tree-shake it cleanly when they disable observability via a build flag — the `getMeter` call is gated behind the first invocation of `getSiteInstruments`.