first commit
This commit is contained in:
84
docs/communication/messaging/sms-providers/src/otel/otel.md
Normal file
84
docs/communication/messaging/sms-providers/src/otel/otel.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# OTel — `@suaveplan/sms-providers`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```ts
|
||||
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).
|
||||
Reference in New Issue
Block a user