Files
skills/docs/media/audio-fx/audio-fx-plugin-spessasynth/src/telemetry/telemetry.md
2026-05-29 08:20:56 +01:00

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

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.