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,76 @@
# job-scheduler-otel
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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 `Histogram`s and `Counter`s — no instrument is created until first use.
- Closed-enum `outcome` and `kind` label 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
```ts
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
```ts
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 by `kind`.
- `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).