Initial Commit
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# otel/instruments
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
The instruments module owns the three OpenTelemetry counters the user
|
||||
plugin emits — `user.profile_reads_total`,
|
||||
`user.profile_updates_total{outcome}`, and `user.self_deletes_total`.
|
||||
The counters are lazily bound to the global `MeterProvider` on first
|
||||
call and cached for the lifetime of the process, with a
|
||||
`resetUserInstruments()` helper so test setup can install a fresh
|
||||
provider and force the next call to rebind.
|
||||
|
||||
## Features
|
||||
|
||||
- Three counters with stable names — they appear verbatim in every
|
||||
exporter (Prometheus, OTLP, in-memory test reader).
|
||||
- Lazy binding — the meter is resolved on first call, so test setup
|
||||
that installs a `MeterProvider` BEFORE importing the user plugin
|
||||
is guaranteed to see its counters bound against that provider.
|
||||
- `outcome` attribute on `profile_updates_total` so a Grafana panel
|
||||
can split success vs. error without an additional counter.
|
||||
- `resetUserInstruments()` clears the cache for tests that swap the
|
||||
global `MeterProvider` mid-suite.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { getUserInstruments } from "@suaveplan/api-plugin-user/otel/instruments";
|
||||
|
||||
const instruments = getUserInstruments();
|
||||
instruments.profileReadsTotal.add(1);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Tests install a real in-memory MeterProvider in `polyfills.ts` BEFORE
|
||||
any plugin source imports run, then `resetUserInstruments()` after
|
||||
`metrics.setGlobalMeterProvider(...)`:
|
||||
|
||||
```ts
|
||||
import { metrics } from "@opentelemetry/api";
|
||||
import { InMemoryMetricExporter, MeterProvider } from "@opentelemetry/sdk-metrics";
|
||||
import { resetUserInstruments } from "@suaveplan/api-plugin-user/otel/instruments";
|
||||
|
||||
const provider = new MeterProvider({ readers: [/* … */] });
|
||||
metrics.setGlobalMeterProvider(provider);
|
||||
resetUserInstruments();
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `getUserInstruments(): UserInstruments`
|
||||
|
||||
Returns the cached bundle, building it on first call.
|
||||
|
||||
### `resetUserInstruments(): void`
|
||||
|
||||
Clears the module cache. Idempotent.
|
||||
|
||||
### `UserInstruments`
|
||||
|
||||
`{ profileReadsTotal, profileUpdatesTotal, selfDeletesTotal }` — each
|
||||
value is an OpenTelemetry `Counter`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The meter name is the package name — every exporter that records the
|
||||
meter scope will surface it as `@suaveplan/api-plugin-user`.
|
||||
- The counters are intentionally narrow — histograms / observables
|
||||
belong in a follow-up if and when observability needs them.
|
||||
- The cache invalidation pattern is mirrored from the sibling auth
|
||||
plugin so test setup is uniform across `api-plugin-*` packages.
|
||||
Reference in New Issue
Block a user