Initial Commit
This commit is contained in:
@@ -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`.
|
||||
Reference in New Issue
Block a user