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 @@
# telemetry
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
OpenTelemetry instrument bridge for the SpessaSynth plugin. Exposes three instruments under the meter `@suaveplan/audio-fx-plugin-spessasynth`: a monotonic counter `spessasynth_voices_triggered_total`, a histogram `spessasynth_process_duration_us`, and an observable gauge `spessasynth_voices_active`. The instruments are lazily created on first use and cached so the underlying OTel SDK sees a stable identity across the process lifetime.
The plugin core, voice manager, and MIDI router call into this module — none of those modules import `@opentelemetry/api` directly — so telemetry can be swapped or stubbed by mutating this single file.
## Features
- Lazy instrument creation: instruments are not registered with the SDK until first call.
- `recordVoicesTriggered(n?)` — counter bump on every `noteOn`.
- `recordProcessDuration(durationUs)` — histogram sample per `process()` block.
- `setActiveVoices(n)` — latched value the observable gauge reads on each collection.
- `getActiveVoicesValue()` — read-back for diagnostics and unit tests.
- `resetForTesting()` — clears the singletons so a test suite that swaps the meter provider can re-register from scratch.
- All instrument labels are cardinality-stable: no per-channel dimensions, no per-voice tags — chosen so a long-running synth session does not blow up the metric backend.
## Usage: Basic
```ts
import {
recordVoicesTriggered,
recordProcessDuration,
setActiveVoices,
} from "@suaveplan/audio-fx-plugin-spessasynth/telemetry";
recordVoicesTriggered(1);
recordProcessDuration(412); // microseconds
setActiveVoices(processor.voiceCount);
```
## Usage: Advanced
```ts
import { metrics } from "@opentelemetry/api";
import { MeterProvider } from "@opentelemetry/sdk-metrics";
import { InMemoryMetricExporter } from "@opentelemetry/sdk-metrics";
import {
resetForTesting,
setActiveVoices,
} from "@suaveplan/audio-fx-plugin-spessasynth/telemetry";
const exporter = new InMemoryMetricExporter(0);
const provider = new MeterProvider({ readers: [/* periodic reader */] });
metrics.setGlobalMeterProvider(provider);
resetForTesting();
setActiveVoices(3);
const collected = await exporter.collect();
// `spessasynth_voices_active` gauge in collected.scopeMetrics → 3
```
## API Reference
- `recordVoicesTriggered(n?: number): void` — counter add, default 1.
- `recordProcessDuration(durationUs: number): void` — histogram record.
- `setActiveVoices(count: number): void` — latch the gauge value.
- `getActiveVoicesValue(): number` — read the latched value.
- `resetForTesting(): void` — clears singletons (test-only).
## Implementation Notes
The observable gauge is a one-shot construction with a callback that reads the latched `_activeVoicesValue` module-level variable. The latched approach (rather than passing the processor in to read `voiceCount`) decouples the telemetry module from the upstream library and lets `setActiveVoices` be called from a high-frequency path (every `process()` block) without per-call overhead. `resetForTesting` deliberately drops references to the cached instruments — the OTel API gracefully re-creates them on the next call, but the gauge callback registration is lost; tests that need to re-arm the gauge should call `setActiveVoices` at least once after resetting.