# 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.