Files
suaveplan/packages/communication/emails/email-templates/src/telemetry/telemetry.md
2026-05-27 23:29:53 +01:00

3.0 KiB

telemetry

(no submodules)

Purpose

Exposes the OpenTelemetry instrument set published by @suaveplan/email-templates. Every public render or registry mutation emits a counter (and where useful, a duration histogram) so operators can build dashboards without instrumenting consumers themselves.

The instrument set is constructed lazily on first access — importing this module does NOT create a meter or instruments, satisfying the "side-effects: false" contract in package.json. Once constructed, the set is cached and the same object reference is returned forever (the metric exporter receives stable instrument identity, which is required for cumulative-temporality counters).

Features

  • Four instruments: render_total (Counter), render_duration_ms (Histogram, unit ms), registry_register_total (Counter), validation_failure_total (Counter).
  • Stable meter name: @suaveplan/email-templates.
  • resetEmailTemplatesInstrumentsCacheForTest() helper to drop the cache between test runs that swap the global MeterProvider.

Usage: Basic

import { getEmailTemplatesInstruments } from "@suaveplan/email-templates/otel";

const instruments = getEmailTemplatesInstruments();
instruments.renderCounter.add(1, { template: "welcome", outcome: "ok" });

Usage: Advanced

Wire a real metric exporter in test setup and assert the recorded series on every render call (the package uses this pattern internally):

import {
  AggregationTemporality,
  InMemoryMetricExporter,
  MeterProvider,
  PeriodicExportingMetricReader,
} from "@opentelemetry/sdk-metrics";
import { metrics } from "@opentelemetry/api";

const exporter = new InMemoryMetricExporter(AggregationTemporality.DELTA);
const reader = new PeriodicExportingMetricReader({ exporter });
const provider = new MeterProvider({ readers: [reader] });
metrics.setGlobalMeterProvider(provider);

// ... drive the renderer ...

await reader.forceFlush();
const series = exporter.getMetrics();
// assert series contains email_templates.render_total ...

API Reference

Symbol Kind Description
getEmailTemplatesInstruments() function Returns the cached EmailTemplatesInstruments.
resetEmailTemplatesInstrumentsCacheForTest() function Drops the module-local cache — test-only.
EmailTemplatesInstruments type The shape of the instrument set.

Implementation Notes

The accessor must remain idempotent. Repeated calls return the same object reference; the test corpus asserts that fact because cumulative counters lose their backing storage if a meter is re-created mid-flight.

The module never reads process.env, globalThis.window, or any DOM-resident global — it is universal (engines.bun, engines.node, browser) without conditional code paths.