first commit
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# instruments
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`getDeliveryTrackingInstruments` lazily constructs and caches the OTel `Counter` set used by every production code path in `@suaveplan/delivery-tracking`. Centralising the instrument names here keeps metric semantics consistent and makes the package observable via any `MeterProvider` configured by the host application.
|
||||
|
||||
The instruments are bound to a `Meter` named `@suaveplan/delivery-tracking`. Tests install a real `InMemoryMetricExporter` + `MeterProvider` in `tests/setup/polyfills.ts` and assert counter totals using the exporter's snapshot — no mocking is involved, satisfying CLAUDE.md rule 2 ("no mocks").
|
||||
|
||||
## Features
|
||||
|
||||
- Lazy singleton; instruments are created on first call and reused.
|
||||
- `resetDeliveryTrackingInstruments()` clears the cache for test isolation.
|
||||
- Five counters with stable names: `delivery_tracking.tracked.total`, `delivery_tracking.deduped.total`, `delivery_tracking.webhook_parsed.total`, `delivery_tracking.token_issued.total`, `delivery_tracking.token_rejected.total`.
|
||||
- All counters carry attribute hints (event_type, channel, provider, kind) that callers should pass when incrementing.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { getDeliveryTrackingInstruments } from "@suaveplan/delivery-tracking/otel";
|
||||
|
||||
const i = getDeliveryTrackingInstruments();
|
||||
i.trackedCounter.add(1, { event_type: "sent" });
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { metrics } from "@opentelemetry/api";
|
||||
import {
|
||||
MeterProvider,
|
||||
PeriodicExportingMetricReader,
|
||||
InMemoryMetricExporter,
|
||||
AggregationTemporality,
|
||||
} from "@opentelemetry/sdk-metrics";
|
||||
import {
|
||||
getDeliveryTrackingInstruments,
|
||||
resetDeliveryTrackingInstruments,
|
||||
} from "@suaveplan/delivery-tracking/otel";
|
||||
|
||||
const exporter = new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE);
|
||||
metrics.setGlobalMeterProvider(
|
||||
new MeterProvider({
|
||||
readers: [
|
||||
new PeriodicExportingMetricReader({
|
||||
exporter,
|
||||
exportIntervalMillis: 60_000,
|
||||
}),
|
||||
],
|
||||
})
|
||||
);
|
||||
resetDeliveryTrackingInstruments();
|
||||
const i = getDeliveryTrackingInstruments();
|
||||
i.webhookParsedCounter.add(3, { provider: "sendgrid" });
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `getDeliveryTrackingInstruments(): DeliveryTrackingInstruments` — returns the cached set; constructs on first call.
|
||||
- `resetDeliveryTrackingInstruments(): void` — clears the cache; intended for test setup.
|
||||
- `interface DeliveryTrackingInstruments` — `meter`, `trackedCounter`, `dedupedCounter`, `webhookParsedCounter`, `tokenIssuedCounter`, `tokenRejectedCounter`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The lazy-init pattern is necessary because the global `MeterProvider` is usually set after module import. Constructing the counters at module top-level would bind them to the no-op default provider; constructing inside the accessor lets the test harness install its provider in `setupFiles` before any source module imports.
|
||||
Reference in New Issue
Block a user