first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
# `otel`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
This module wires `@suaveplan/audio-decode-wav` into OpenTelemetry: it builds (and caches) the tracer, meter, counters and histogram the package emits, supports swapping the meter provider for tests, and exposes the two convenience recorders (`recordSuccess`, `recordError`) used by the decoder and the stream wrapper. Every public call in the package routes its telemetry through one of those two functions so the spec's `audio_decode_wav.*` instrument names are emitted from exactly one place.
## Features
- `setAudioDecodeWavMeterProvider(provider)` overrides the meter provider; pass `undefined` to revert to the global. Resets the instrument cache so the next access binds to the new provider — essential for tests that snapshot per-test metrics.
- Lazy-built, cached instruments via `getInstruments(force?)` — first call builds, subsequent calls return the cache unless `force === true`.
- Three counters (`bytes_in_total`, `frames_out_total`, `errors_total`) and one histogram (`op_duration_ms`) on the `@suaveplan/audio-decode-wav` meter.
- Tracer spans on the `@suaveplan/audio-decode-wav` tracer, named `audio_decode_wav.<op>` where `op ∈ {"decodeWav", "stream.feed", "stream.flush"}`.
- `recordSuccess(input)` and `recordError(input)` are the canonical emit points — both increment the duration histogram, the relevant counter, and start/end a span.
## Usage: Basic
```ts
import { getInstruments, recordSuccess } from "@suaveplan/audio-decode-wav";
recordSuccess({
op: "decodeWav",
bytesIn: 1024,
framesOut: 256,
durationMs: 1.2,
});
const inst = getInstruments();
inst.tracer.startSpan("custom.span").end();
```
## Usage: Advanced
```ts
import {
resetInstruments,
setAudioDecodeWavMeterProvider,
} from "@suaveplan/audio-decode-wav";
const counters: Array<{ name: string; value: number }> = [];
setAudioDecodeWavMeterProvider({
getMeter: () => ({
createCounter: (name) => ({ add: (v) => counters.push({ name, value: v }) }),
createHistogram: () => ({ record: () => {} }),
}),
} as never);
resetInstruments();
// run decode(), then assert against `counters`
setAudioDecodeWavMeterProvider(undefined);
resetInstruments();
```
## API Reference
- `setAudioDecodeWavMeterProvider(provider: MeterProvider | undefined): void` — override the meter provider; clears the instrument cache.
- `getInstruments(force?: boolean): AudioDecodeWavInstruments` — return the cached instruments (or rebuild if `force`).
- `resetInstruments(): void` — drop the cache; next `getInstruments` rebuilds.
- `recordSuccess(input: SuccessOpInput): void` — emit duration + bytes_in + frames_out + span for a successful op.
- `recordError(input: ErrorOpInput): void` — emit duration + errors_total + span for a failed op.
- `type AudioDecodeWavOp = "decodeWav" | "stream.feed" | "stream.flush"`.
- `type AudioDecodeWavOutcome = "success" | "error"`.
## Implementation Notes
The cache is module-scoped — there is exactly one set of instruments per process. Tests swap the provider via `setAudioDecodeWavMeterProvider` and call `resetInstruments()` to force a rebuild; the override pointer is read inside `getInstruments` so the swap takes effect on the next access. Span attributes include `audio_decode_wav.outcome` and either `audio_decode_wav.bytes_in`/`audio_decode_wav.frames_out` (success) or `audio_decode_wav.code` (error); these mirror the metric attribute keys so an OTel collector can join spans and metrics on the same dimension.