# instrumented _(no submodules)_ ## Purpose `instrumented` wraps a named function with optional OpenTelemetry instrumentation — counters for invocations, histograms for durations, span events for failures. Instrumentation is **gated** behind the `TESTING_DOM_OTEL_ENABLED` environment variable, so production test runs pay zero overhead while CI or local profiling sessions can flip the flag on to surface hot-path data. ## Features - Gated at import time via an environment variable check; no-op when disabled - Uses only `@opentelemetry/api` (no SDK dependency) — consumers wire the actual exporters at bootstrap - Preserves the wrapped function's signature and return type - Handles both sync and async functions, including rejection paths - Zero allocation overhead when gated off (returns the original function) ## Usage: Basic Example ```ts import { instrumented } from "@suaveplan/testing-dom/observability"; const render = instrumented("testing_dom.render", (tree: unknown) => { return reactRender(tree); }); render(); // counter incremented, histogram timed — if enabled ``` ## Usage: Advanced Example ```ts import { instrumented } from "@suaveplan/testing-dom/observability"; class TestingHarness { public setup = instrumented("testing_dom.harness.setup", async () => { await this.loadFixtures(); await this.mountApp(); }); public teardown = instrumented("testing_dom.harness.teardown", async () => { await this.unmountApp(); }); } // Flag-off: `const harness = new TestingHarness(); await harness.setup();` // runs at the same cost as the unwrapped method. // Flag-on: every call emits a counter and a histogram observation. ``` ## API Reference ### `instrumented(name, fn): TFn` - `name` — metric name suffix; the full metric becomes `testing_dom..count` / `duration_ms` / `errors` - `fn` — any function (sync or async) - Returns `TFn` — a function with the same signature, instrumented when enabled ### Environment gating `TESTING_DOM_OTEL_ENABLED` must equal `"1"` / `"true"` at module-import time for instrumentation to activate. ## Implementation Notes The gate is evaluated once, at module import — flipping the env var mid-process has no effect. This avoids per-call environment reads in the hot path. When the gate is off, `instrumented` returns the original function reference unchanged, so V8 inlines as if the wrapper was never there. The `@opentelemetry/api` import is a marker package — it provides no-op tracers/meters when no SDK is registered, so even with the gate on, unconfigured environments pay only the cost of a no-op counter increment.