first commit
This commit is contained in:
98
docs/communication/messaging/sms/src/otel/metrics.md
Normal file
98
docs/communication/messaging/sms/src/otel/metrics.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# `otel/metrics`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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
|
||||
current `MeterProvider` for test wiring.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```ts
|
||||
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): void`
|
||||
- `function recordSmsFailed(code: string): void`
|
||||
- `function recordSmsRetry(attempt: number): void`
|
||||
- `function recordSmsSendDuration(durationMs: number, outcome:
|
||||
"ok" | "error" | "aborted"): void`
|
||||
- `function 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.
|
||||
Reference in New Issue
Block a user