first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
# `otel/instruments`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
OpenTelemetry instrument bundle for `@suaveplan/api-plugin-notifications`.
The module exposes a lazy, memoised factory that resolves a meter
against the current global `MeterProvider` on first call and caches the
resulting `Counter` instances for the lifetime of the process. A
companion `resetNotificationsInstruments()` clears the cache so tests
can install a fresh in-memory `MeterProvider` and re-resolve the meter
against it deterministically.
## Features
- Six counters covering the entire production surface: notification
create / read / delete, push send / fail, and device-token registry.
- Single meter per process — the meter is created with the package
name, so traces grouped by `service.namespace` keep notifications
metrics separable from sibling plugins.
- Reset helper for tests — the test suite installs a fresh
`InMemoryMetricExporter` per file, resets the cache, and reads back
cumulative metrics through `flushTestMetrics()` from
`tests/setup/polyfills.ts`.
- Counter attributes are caller-supplied. The route layer passes
`{ platform: "ios" }` to `pushSentTotal.add(1, attrs)` and
`{ reason: "BadDeviceToken" }` to `pushFailedTotal.add(1, attrs)`.
## Usage: Basic
```ts
import { getNotificationsInstruments } from "@suaveplan/api-plugin-notifications";
const inst = getNotificationsInstruments();
inst.notificationsCreatedTotal.add(1);
inst.pushSentTotal.add(1, { platform: "ios" });
```
## Usage: Advanced
For test code that installs a fresh provider, reset the cache so the
next call rebinds:
```ts
import { metrics } from "@opentelemetry/api";
import {
AggregationTemporality,
InMemoryMetricExporter,
MeterProvider,
} from "@opentelemetry/sdk-metrics";
import {
getNotificationsInstruments,
resetNotificationsInstruments,
} from "@suaveplan/api-plugin-notifications";
const exporter = new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE);
const provider = new MeterProvider();
metrics.setGlobalMeterProvider(provider);
resetNotificationsInstruments();
const inst = getNotificationsInstruments();
inst.pushFailedTotal.add(1, { reason: "BadDeviceToken" });
```
## API Reference
- `NotificationsInstruments` — readonly interface with six `Counter`
fields.
- `getNotificationsInstruments(): NotificationsInstruments` — lazy
memoised factory. Idempotent within a session.
- `resetNotificationsInstruments(): void` — drop the cache so the next
factory call rebinds against the current global provider.
## Implementation Notes
The lazy-bind pattern is required because the meter resolution copies
the `MeterProvider` reference at meter-create time. If the bundle were
created at module load, every test in the suite would share one meter
bound to whatever provider happened to be installed first, defeating
isolation. The cache resets between tests via the
`afterEach(resetNotificationsInstruments)` hook in
`instruments.test.ts`.