# `instruments` _(no submodules)_ ## Purpose Owns the OpenTelemetry instrument bundle emitted by the GraphiQL UI plugin. A single `Counter` (`graphql.ui.requests_total`) is constructed at mount time and incremented on each successful HTML response. The counter is always labelled `{ ui: "graphiql" }` so dashboards can sum across sibling UI plugins (`api-graphql-ui-altair` etc.) without collision. Asset sub-requests (`/assets/...`) do NOT increment this counter — they are covered by the host router's standard request metrics. ## Features - Single `Counter` instrument — `graphql.ui.requests_total`. - Optional `meterProvider` parameter — defaults to the OTel global (which falls back to a no-op when no SDK is installed). - Frozen instrument bundle — meter + counter created once at plugin mount time. - `recordUiRequest(instruments)` helper — applies the `{ ui: "graphiql" }` label automatically so call sites never get it wrong. ## Usage: Basic ```ts import { createGraphiqlInstruments, recordUiRequest, } from "@suaveplan/api-graphql-ui-graphiql"; const instruments = createGraphiqlInstruments(); recordUiRequest(instruments); ``` ## Usage: Advanced ```ts import { MeterProvider } from "@opentelemetry/sdk-metrics"; import { createGraphiqlInstruments } from "@suaveplan/api-graphql-ui-graphiql"; const meterProvider = new MeterProvider({ /* readers, views, ... */ }); const instruments = createGraphiqlInstruments({ meterProvider }); // instruments.meter / instruments.requestsTotal are now wired to the // caller-controlled provider rather than the OTel global. ``` ## API Reference - `interface GraphiqlInstrumentsConfig { meterProvider?: MeterProvider }`. - `interface GraphiqlInstruments { meter: Meter; requestsTotal: Counter }` — frozen at construction. - `createGraphiqlInstruments(config?)` — returns the frozen bundle. - `recordUiRequest(instruments)` — increments the counter with the canonical `{ ui: "graphiql" }` label. - `UI_LABEL_VALUE: "graphiql"` — the literal used in every observation. ## Implementation Notes `UI_LABEL_VALUE` is exported as a named constant so the sibling Altair package can reference it via a `not-equal` predicate in shared tests ("the two UI plugins MUST emit distinct `ui` labels"). The counter name is shared across UI plugins by design — operators get a single rollup of "explorer requests" without per-UI configuration. The Stage-5 testing-kit's in-memory `MeterProvider` is used in tests; production operators register their preferred SDK once at process boot.