Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# observability/instrumented
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
`instrumented` is the gated OpenTelemetry wrapper for `@suaveplan/testing-e2e` helpers and fixtures. When `TESTING_E2E_OTEL_ENABLED` is set, wrapped calls emit counters for invocations, histograms for durations, and span events for failures — giving a Playwright test run the same structured telemetry as a production service. When the flag is off, `instrumented` returns the original function reference unchanged so test-run cost is identical to the unwrapped case.
|
||||
|
||||
## Features
|
||||
|
||||
- Gated at module import via `TESTING_E2E_OTEL_ENABLED` — no per-call env reads
|
||||
- Uses `@opentelemetry/api` only (no SDK) — consumers wire exporters at bootstrap
|
||||
- Preserves signature and return type of the wrapped function
|
||||
- Handles sync and async fn forms, including rejection
|
||||
- Zero overhead when disabled (identity pass-through)
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { instrumented } from "@suaveplan/testing-e2e/observability";
|
||||
|
||||
const navigate = instrumented("testing_e2e.navigate", async (page: Page, url: string) => {
|
||||
await page.goto(url);
|
||||
});
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { instrumented } from "@suaveplan/testing-e2e/observability";
|
||||
|
||||
class DashboardPage {
|
||||
public gotoInstrumented = instrumented(
|
||||
"testing_e2e.page.dashboard.goto",
|
||||
async (page: Page) => {
|
||||
await page.goto("/dashboard");
|
||||
await page.waitForLoadState("domcontentloaded");
|
||||
}
|
||||
);
|
||||
|
||||
public filterInstrumented = instrumented(
|
||||
"testing_e2e.page.dashboard.filter",
|
||||
async (page: Page, query: string) => {
|
||||
await page.fill('input[name="q"]', query);
|
||||
await page.press('input[name="q"]', "Enter");
|
||||
}
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `instrumented<TFn>(name, fn): TFn`
|
||||
|
||||
- `name` — metric name suffix; the full name becomes `testing_e2e.<name>.count` / `duration_ms` / `errors`
|
||||
- `fn` — any function to wrap
|
||||
- Returns `TFn` with the same signature; instrumented only when the env flag is set
|
||||
|
||||
### Environment gating
|
||||
|
||||
`TESTING_E2E_OTEL_ENABLED` must equal `"1"` or `"true"` at module-import time.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The env check runs once at module import — flipping the variable mid-run has no effect, which avoids per-call reads in the hot path. With instrumentation enabled but no OTel SDK registered, `@opentelemetry/api` returns no-op tracers and meters, so the overhead is a single no-op counter increment. The disabled branch returns the original function reference, so V8 inlines it as if the wrapper was never there.
|
||||
Reference in New Issue
Block a user