first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View 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).