2.7 KiB
sampler
(no submodules)
Purpose
Sampler collects periodic snapshots of runtime metrics (memory usage by default, plus caller-supplied custom metrics). The timer source is injected through a TimersLike so tests can advance virtual time deterministically and so non-setInterval runtimes (Workers, Deno, embedded JS) can plug in their own scheduler. Sample storage is capped via FIFO eviction so long-running collectors don't leak memory.
Features
- Zod-validated options (
intervalMs > 0, optional positivemaxSamples, optionalcaptureMemory). - Injectable
Clock,TimersLike, andMemoryProbe— the defaults readDate.now,setTimeout/clearTimeout, andprocess.memoryUsage/performance.memoryrespectively. start()/stop()are idempotent — double-startand double-stopare no-ops.takeSample(customMetrics?)records a single sample on demand; same code path used by the scheduled tick.getSamples()/getSamplesInRange(start, end)/clear()for retrieval and reset.events: EventBus<SamplerEventMap>emitssampler:start,sampler:stop,sampler:sample.- Telemetry:
profiler_samples_totalcounter incremented on every sample.
Usage: Basic
import { Sampler } from "@suaveplan/profiler";
const sampler = new Sampler({ intervalMs: 1000 });
sampler.start();
// ...
sampler.stop();
console.log(sampler.getSamples());
Usage: Advanced
import { Sampler } from "@suaveplan/profiler";
import type { TimersLike } from "@suaveplan/types";
const queue: Array<{ cb: () => void; handle: number }> = [];
let next = 1;
const fakeTimers: TimersLike = {
setTimer(cb) {
const handle = next++;
queue.push({ cb, handle });
return handle;
},
clearTimer() {},
};
let clockT = 0;
const sampler = new Sampler({
intervalMs: 10,
timers: fakeTimers,
clock: () => clockT,
memoryProbe: () => 4096,
});
sampler.start();
clockT = 10;
queue.shift()?.cb();
API Reference
class Sampler—new Sampler(options: SamplerOptions).interface SamplerOptions extends SamplerConfig { clock?, timers?, memoryProbe? }.- Methods:
start,stop,takeSample,getSamples,getSamplesInRange,isRunning,clear. - Errors: throws
ProfilerErrorwithPROFILER.INVALID_OPTIONSwhen options fail Zod validation.
Implementation Notes
The scheduler uses a self-rescheduling setTimer rather than setInterval because TimersLike only models one-shot timers. Each tick checks this.running before taking a sample, which lets a stop() that runs between callback dispatch and execution avoid emitting a stale sample. FIFO eviction uses splice(0, n) so the oldest samples drop out when maxSamples is exceeded.