3.0 KiB
job-scheduler-otel
(no submodules)
Purpose
Wires @opentelemetry/api metrics for the scheduler. The module exposes a small set of recording helpers — recordJobRun, recordJobDuration, incrementJobFailure, incrementCronExhausted, recordQueueDepth — that the scheduler and execution modules call at fixed points. Lazy meter / instrument initialisation keeps cold-start cost near zero for callers that never produce metrics.
Features
- One meter (
@suaveplan/job-scheduler) shared across all instruments. - Lazy-initialised
Histograms andCounters — no instrument is created until first use. - Closed-enum
outcomeandkindlabel values (success | error | timeout,cron | queued) so cardinality is bounded. - Pure side-effect-free getters — the module can be imported in tree-shake audits without producing instruments.
Usage: Basic Example
import { recordJobRun } from "@suaveplan/job-scheduler";
const start = Date.now();
try {
await runHandler();
recordJobRun(Date.now() - start, "success", "queued");
} catch (err) {
recordJobRun(Date.now() - start, "error", "queued");
throw err;
}
Usage: Advanced Example
import {
incrementCronExhausted,
incrementJobFailure,
recordJobDuration,
recordJobRun,
recordQueueDepth,
} from "@suaveplan/job-scheduler";
function tick(queueDepth: number): void {
recordQueueDepth(queueDepth);
}
function onCronExhausted(): void {
incrementCronExhausted();
}
function onJobFinished(
durationMs: number,
outcome: "success" | "error" | "timeout",
kind: "cron" | "queued"
): void {
recordJobRun(durationMs, outcome, kind);
if (outcome !== "success") incrementJobFailure(kind);
if (outcome === "timeout") {
recordJobDuration(durationMs, "timeout", kind);
}
}
API Reference
type JobOutcome = "success" | "error" | "timeout"type JobKind = "cron" | "queued"recordJobRun(durationMs, outcome, kind): void— records duration histogram sample and increments runs counter.recordJobDuration(durationMs, outcome, kind): void— duration-only sample, no counter bump.incrementJobFailure(kind): void— bump failures counter bykind.incrementCronExhausted(): void— bump exhausted-cron counter.recordQueueDepth(depth): void— sample current heap depth.
Implementation Notes
All instruments are created exactly once per process via lazy module-scope caches. The OpenTelemetry metrics API guarantees stable instrument identity across getMeter(name).createX calls only when name + kind + description + unit match — caching here avoids that contract entirely. Label-value enums are closed by TypeScript at the boundary; passing a free-form string would compile-fail. The histograms accept number durations; callers compute deltas with the injected scheduler Clock (test runs use FakeClock so values are deterministic and stable across CI runs).