Files
skills/docs/communication/emails/delivery-tracking/src/otel/instruments.md
2026-05-29 08:20:56 +01:00

2.9 KiB

instruments

(no submodules)

Purpose

getDeliveryTrackingInstruments lazily constructs and caches the OTel Counter set used by every production code path in @suaveplan/delivery-tracking. Centralising the instrument names here keeps metric semantics consistent and makes the package observable via any MeterProvider configured by the host application.

The instruments are bound to a Meter named @suaveplan/delivery-tracking. Tests install a real InMemoryMetricExporter + MeterProvider in tests/setup/polyfills.ts and assert counter totals using the exporter's snapshot — no mocking is involved, satisfying CLAUDE.md rule 2 ("no mocks").

Features

  • Lazy singleton; instruments are created on first call and reused.
  • resetDeliveryTrackingInstruments() clears the cache for test isolation.
  • Five counters with stable names: delivery_tracking.tracked.total, delivery_tracking.deduped.total, delivery_tracking.webhook_parsed.total, delivery_tracking.token_issued.total, delivery_tracking.token_rejected.total.
  • All counters carry attribute hints (event_type, channel, provider, kind) that callers should pass when incrementing.

Usage: Basic

import { getDeliveryTrackingInstruments } from "@suaveplan/delivery-tracking/otel";

const i = getDeliveryTrackingInstruments();
i.trackedCounter.add(1, { event_type: "sent" });

Usage: Advanced

import { metrics } from "@opentelemetry/api";
import {
    MeterProvider,
    PeriodicExportingMetricReader,
    InMemoryMetricExporter,
    AggregationTemporality,
} from "@opentelemetry/sdk-metrics";
import {
    getDeliveryTrackingInstruments,
    resetDeliveryTrackingInstruments,
} from "@suaveplan/delivery-tracking/otel";

const exporter = new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE);
metrics.setGlobalMeterProvider(
    new MeterProvider({
        readers: [
            new PeriodicExportingMetricReader({
                exporter,
                exportIntervalMillis: 60_000,
            }),
        ],
    })
);
resetDeliveryTrackingInstruments();
const i = getDeliveryTrackingInstruments();
i.webhookParsedCounter.add(3, { provider: "sendgrid" });

API Reference

  • getDeliveryTrackingInstruments(): DeliveryTrackingInstruments — returns the cached set; constructs on first call.
  • resetDeliveryTrackingInstruments(): void — clears the cache; intended for test setup.
  • interface DeliveryTrackingInstruments — meter, trackedCounter, dedupedCounter, webhookParsedCounter, tokenIssuedCounter, tokenRejectedCounter.

Implementation Notes

The lazy-init pattern is necessary because the global MeterProvider is usually set after module import. Constructing the counters at module top-level would bind them to the no-op default provider; constructing inside the accessor lets the test harness install its provider in setupFiles before any source module imports.