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

2.5 KiB

otel/instruments

(no submodules)

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

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(...):

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.