Files
skills/docs/communication/messaging/sms-providers/src/otel/otel.md
2026-05-29 08:20:56 +01:00

3.6 KiB

OTel — @suaveplan/sms-providers

(no submodules)

Purpose

Owns the package's OpenTelemetry instrument set. Five instruments cover the public-surface operations every provider class performs: outbound send (count + duration), inbound webhook events (count + verification duration), and signature-failure counter. The module exposes typed recordSend/recordWebhook/recordSignatureFailure/recordSendDuration/recordWebhookVerifyDuration helpers so providers stay free of inline OTel boilerplate, and a refreshSmsProvidersMeters() helper that re-resolves every instrument against the current global MeterProvider — tests install a fresh in-memory reader, call refresh, and then drive the helpers to assert on the captured metric points.

Features

  • Exactly five instruments — three counters (send_total, webhook_total, signature_failures_total) and two histograms (send_duration_ms, webhook_verify_duration_ms).
  • Every counter carries a provider label so multi-provider deployments split cleanly in Grafana / Honeycomb.
  • outcome ("ok" / "error") on send_total and webhook_total lets dashboards compute success rate as 1 - error / total.
  • webhook_total adds an event label (message_received | delivery_receipt | opt_in | opt_out | help).
  • Histograms record in ms.
  • refreshSmsProvidersMeters() is the test seam — module-load resolves the global meter once, this resets it.

Usage: Basic

import {
    recordSend,
    recordSendDuration,
} from "@suaveplan/sms-providers";

const t0 = Date.now();
try {
    /* call provider */
    recordSend("twilio", "ok");
} catch {
    recordSend("twilio", "error");
    throw;
} finally {
    recordSendDuration("twilio", Date.now() - t0);
}

Usage: Advanced

import {
    recordSignatureFailure,
    recordWebhook,
    recordWebhookVerifyDuration,
    refreshSmsProvidersMeters,
} from "@suaveplan/sms-providers";
import { metrics } from "@opentelemetry/api";
import { MeterProvider } from "@opentelemetry/sdk-metrics";

// Test-only: swap the global meter for a recording one.
const provider = new MeterProvider();
metrics.setGlobalMeterProvider(provider);
refreshSmsProvidersMeters();

const t0 = performance.now();
try {
    // verifyWebhookSignature(...)
} catch (err) {
    recordSignatureFailure("plivo");
    throw err;
} finally {
    recordWebhookVerifyDuration("plivo", performance.now() - t0);
}

recordWebhook("vonage", "delivery_receipt", "ok");

API Reference

Symbol Kind Notes
recordSend(provider, outcome) function Counter sms_providers.send_total.
recordWebhook(provider, event, outcome) function Counter sms_providers.webhook_total.
recordSignatureFailure(provider) function Counter sms_providers.signature_failures_total.
recordSendDuration(provider, ms) function Histogram sms_providers.send_duration_ms.
recordWebhookVerifyDuration(provider, ms) function Histogram sms_providers.webhook_verify_duration_ms.
refreshSmsProvidersMeters() function Re-resolves every instrument against the current global meter.
SendOutcome / WebhookOutcome type "ok" | "error".

Implementation Notes

Instruments are held as let-bound module-locals so refreshSmsProvidersMeters() can reassign them after metrics.setGlobalMeterProvider(...) — re-resolving is necessary because OTel's Meter proxy snapshots the active provider at meter-creation time. The instrument names follow the OTel naming convention (<domain>.<metric> with _total suffix on monotonic counters).