Files
suaveplan/packages/api-stack/api/api-plugin-notifications/src/otel/instruments.md
2026-05-27 23:29:53 +01:00

3.0 KiB

otel/instruments

(no submodules)

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

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:

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.