Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# `instruments.ts` — webhook plugin OpenTelemetry instruments
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines the four OpenTelemetry instruments emitted by the webhook plugin: two counters and two histograms covering every observable outcome of `WebhookService.send`. The bundle is lazily built against the process-wide `MeterProvider` and cached so repeat calls return the same `Counter` / `Histogram` references — this means tests can install a fresh provider, call `resetWebhookInstruments()`, and trust that the next `getWebhookInstruments()` rebinds against it. Without this seam, tests that install a `MeterProvider` after the first import see metrics flow to a stale meter and silently drop observations.
|
||||
|
||||
## Features
|
||||
|
||||
- Four instruments — `deliveries_total`, `dead_letters_total`, `delivery_attempts`, `send_duration_ms`.
|
||||
- Lazy + cached binding so the meter is resolved on first read, not at import time.
|
||||
- `resetWebhookInstruments()` for test isolation.
|
||||
- Stable namespace `webhook_plugin.*` to keep the plugin's metrics separate from `@suaveplan/webhook-client`'s `webhook_client.*` metrics.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { getWebhookInstruments } from "@suaveplan/api-plugin-webhook/otel/instruments";
|
||||
|
||||
const inst = getWebhookInstruments();
|
||||
inst.deliveriesTotal.add(1, { event: "order.created", status: "delivered" });
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
// Tests typically install a fresh MeterProvider, then call resetWebhookInstruments
|
||||
// so the next getWebhookInstruments() rebinds against the freshly-installed provider.
|
||||
|
||||
import { metrics } from "@opentelemetry/api";
|
||||
import {
|
||||
AggregationTemporality,
|
||||
InMemoryMetricExporter,
|
||||
MeterProvider,
|
||||
PeriodicExportingMetricReader,
|
||||
} from "@opentelemetry/sdk-metrics";
|
||||
import {
|
||||
getWebhookInstruments,
|
||||
resetWebhookInstruments,
|
||||
} from "@suaveplan/api-plugin-webhook/otel/instruments";
|
||||
|
||||
const exporter = new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE);
|
||||
const reader = new PeriodicExportingMetricReader({ exporter, exportIntervalMillis: 60_000 });
|
||||
const provider = new MeterProvider({ readers: [reader] });
|
||||
metrics.setGlobalMeterProvider(provider);
|
||||
resetWebhookInstruments();
|
||||
|
||||
const inst = getWebhookInstruments();
|
||||
inst.deliveriesTotal.add(1, { event: "evt", status: "delivered" });
|
||||
await provider.forceFlush();
|
||||
console.log(exporter.getMetrics());
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `getWebhookInstruments()` — returns the cached `WebhookInstruments` bundle, lazily binding on first call.
|
||||
- `resetWebhookInstruments()` — drops the cache so the next `getWebhookInstruments()` rebinds.
|
||||
- `WebhookInstruments` — `{ deliveriesTotal, deadLettersTotal, deliveryAttempts, sendDurationMs }`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The namespace `webhook_plugin.*` was chosen explicitly so dashboards and alerts can distinguish plugin-level emissions from the `webhook_client.*` emissions the underlying delivery library emits. The label set `{event, status, endpoint_id}` on `deliveries_total` deliberately includes `endpoint_id` even though it has unbounded cardinality — operators with many endpoints SHOULD aggregate at scrape time using a recording rule that drops the label. Including it at emission time means operators can debug a single endpoint without recompiling. The histograms inherit OTel's default bucket layout (no custom `boundaries` supplied) — operators tune via SDK views, not by editing this file.
|
||||
Reference in New Issue
Block a user