# OpenTelemetry instruments — `@suaveplan/api-plugin-cms` _(no submodules)_ ## Purpose The package emits seven OpenTelemetry counters on every production mutation so operators can dashboard CMS activity and alert on drift without wiring custom hooks. Instruments are resolved lazily through `getCmsInstruments()` so test harnesses installing a custom `MeterProvider` before importing the engine capture every observation. The `resetCmsInstruments()` helper drops the cached bundle for tests that need a clean slate; it is exported for testing only. ## Features - One counter per `CmsEngine` event: `cms.models_created_total`, `cms.content_created_total`, `cms.content_updated_total`, `cms.content_published_total`, `cms.content_archived_total`, `cms.content_deleted_total`. - One derived counter `cms.validation_failures_total` increments whenever `createContent` or `updateContent` raises `CMS.VALIDATION_FAILED`. - Lazy resolution honours the harness pattern: first import of the package does not touch `metrics.getMeter` — the meter binds on the first hot-path call. ## Usage: Basic ```ts import { metrics } from "@opentelemetry/api"; import { MeterProvider } from "@opentelemetry/sdk-metrics"; const provider = new MeterProvider({ readers: [...] }); metrics.setGlobalMeterProvider(provider); // First mutation binds the cached meter to `provider`. import { CmsEngine } from "@suaveplan/api-plugin-cms"; new CmsEngine().createModel({ /* ... */ }); ``` ## Usage: Advanced In tests, install the in-memory exporter from `tests/setup/polyfills.ts`, exercise the engine, then assert against the flushed metrics: ```ts import { flushTestMetrics } from "../../tests/setup/polyfills.js"; import { resetCmsInstruments } from "@suaveplan/api-plugin-cms"; beforeEach(() => resetCmsInstruments()); it("publishing increments the counter", async () => { // ... engine.transitionStatus(..., "published") const metrics = await flushTestMetrics(); // assert "cms.content_published_total" sum == 1 }); ``` ## API Reference | Symbol | Description | |---|---| | `interface CmsInstruments` | Holds the seven counters + meter. | | `getCmsInstruments()` | Resolve (or build + cache) the bundle. | | `resetCmsInstruments()` | Test-only — clear the cached bundle. | ## Implementation Notes The meter is acquired via `metrics.getMeter("@suaveplan/api-plugin-cms")` on first call. Each counter is created with a human-readable `description`. Production paths increment via `instr..add(1)` so the wire emits a single delta per call; downstream pipelines aggregate to a histogram of activity per minute if needed.