3.0 KiB
otel/metrics
(no submodules)
Purpose
otel/metrics is the OpenTelemetry instrumentation layer for
@suaveplan/sms. It owns four meter instruments — three
counters and a histogram — that SmsService populates on every
send, retry, and failure. Wiring observability at the package
level keeps consumers free from re-defining instrument names and
units, and gives downstream dashboards a stable contract to plot
against.
The module reads the global MeterProvider from
@opentelemetry/api. Tests that wire an in-memory exporter call
refreshSmsMeters() after installing the exporter so subsequent
record* calls land on the test provider rather than the
load-time meter.
Features
sms.sent_total{channel, from_me}counter — successful sends.sms.failed_total{code}counter — failed sends, tagged by error code.sms.retry_total{attempt}counter — retry attempts, tagged by zero-based attempt index.sms.send_duration_ms{outcome}histogram — pipeline duration in milliseconds, outcome ∈ {ok,error,aborted}.refreshSmsMeters()re-resolves every instrument against the currentMeterProviderfor test wiring.
Usage: Basic
import {
recordSmsSent,
recordSmsFailed,
recordSmsRetry,
recordSmsSendDuration,
} from "@suaveplan/sms/otel";
const start = Date.now();
try {
// ... send ...
recordSmsSent("marketing", false);
recordSmsSendDuration(Date.now() - start, "ok");
} catch (err) {
recordSmsFailed("SMS.SEND_FAILED");
recordSmsSendDuration(Date.now() - start, "error");
}
Usage: Advanced
import {
MeterProvider,
PeriodicExportingMetricReader,
ConsoleMetricExporter,
} from "@opentelemetry/sdk-metrics";
import { metrics } from "@opentelemetry/api";
import { refreshSmsMeters } from "@suaveplan/sms/otel";
const provider = new MeterProvider({
readers: [
new PeriodicExportingMetricReader({
exporter: new ConsoleMetricExporter(),
}),
],
});
metrics.setGlobalMeterProvider(provider);
refreshSmsMeters(); // rebind every instrument against the new provider
API Reference
function recordSmsSent(channel: string, fromMe: boolean): voidfunction recordSmsFailed(code: string): voidfunction recordSmsRetry(attempt: number): voidfunction recordSmsSendDuration(durationMs: number, outcome: "ok" | "error" | "aborted"): voidfunction refreshSmsMeters(): void
Implementation Notes
Instruments are stored at module scope so the hot send path
performs zero allocation per record call. The default no-op
meter provided by @opentelemetry/api accepts every call
silently, so packages that never install a MeterProvider pay
nothing. Calling refreshSmsMeters() re-creates each instrument
against the current global — necessary because instrument
identity is bound to the meter instance, not the API surface.
The attribute keys (channel, from_me, code, attempt,
outcome) are part of the public observability contract; renames
require a major version bump.