import { type Counter, type Histogram, metrics } from "@opentelemetry/api"; const METER_NAME = "@suaveplan/cron"; let _parseHistogram: Histogram | undefined; let _nextRunHistogram: Histogram | undefined; let _parseCounter: Counter | undefined; let _nextRunCounter: Counter | undefined; let _dstTransitionCounter: Counter | undefined; function getParseHistogram(): Histogram { if (!_parseHistogram) { _parseHistogram = metrics .getMeter(METER_NAME) .createHistogram("cron.parse.duration_ms", { description: "Cron expression parse duration in milliseconds", unit: "ms", }); } return _parseHistogram; } function getNextRunHistogram(): Histogram { if (!_nextRunHistogram) { _nextRunHistogram = metrics .getMeter(METER_NAME) .createHistogram("cron.next_run.duration_ms", { description: "Cron next-run search duration in milliseconds", unit: "ms", }); } return _nextRunHistogram; } function getParseCounter(): Counter { if (!_parseCounter) { _parseCounter = metrics .getMeter(METER_NAME) .createCounter("cron.parse_total", { description: "Cron parse invocations by outcome", }); } return _parseCounter; } function getNextRunCounter(): Counter { if (!_nextRunCounter) { _nextRunCounter = metrics .getMeter(METER_NAME) .createCounter("cron.next_run_total", { description: "Cron next-run invocations by outcome and tz", }); } return _nextRunCounter; } function getDstTransitionCounter(): Counter { if (!_dstTransitionCounter) { _dstTransitionCounter = metrics .getMeter(METER_NAME) .createCounter("cron.dst_transition_total", { description: "DST transitions crossed during next-run search", }); } return _dstTransitionCounter; } /** Outcome attribute is a closed enum so cardinality is bounded. */ export type Outcome = "success" | "error"; /** Record a parse-duration sample and increment the parse counter. */ export function recordParse(durationMs: number, outcome: Outcome): void { getParseHistogram().record(durationMs, { outcome }); getParseCounter().add(1, { outcome }); } /** Record a next-run-duration sample and increment the next-run counter. */ export function recordNextRun( durationMs: number, outcome: Outcome, tz: string ): void { getNextRunHistogram().record(durationMs, { outcome, tz }); getNextRunCounter().add(1, { outcome, tz }); } /** Increment the DST-transition counter. `kind` is a closed enum. */ export function recordDstTransition( kind: "spring-forward" | "fall-back", tz: string ): void { getDstTransitionCounter().add(1, { kind, tz }); }