3.3 KiB
telemetry
(no submodules)
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 everynoteOn.recordProcessDuration(durationUs)— histogram sample perprocess()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
import {
recordVoicesTriggered,
recordProcessDuration,
setActiveVoices,
} from "@suaveplan/audio-fx-plugin-spessasynth/telemetry";
recordVoicesTriggered(1);
recordProcessDuration(412); // microseconds
setActiveVoices(processor.voiceCount);
Usage: Advanced
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.