import { type Counter, type Histogram, metrics } from "@opentelemetry/api"; /** * OTel instruments for the Date formatter. * * Histogram records per-format wall-clock duration; the counter * increments on every cache reuse so consumers can observe cache * effectiveness. * * The module retains a small in-memory state ring so spec-conformance * tests can assert exact attribute payloads without standing up a * full SDK exporter. */ export interface DateMetricSample { readonly attributes: Record; } export interface DateMetricsState { readonly durationSamples: DateMetricSample[]; readonly cacheHitSamples: DateMetricSample[]; } let cached: | { readonly durationMs: Histogram; readonly cacheHit: Counter; } | undefined; const state: DateMetricsState = { durationSamples: [], cacheHitSamples: [], }; function ensureInstruments() { if (cached) return cached; const meter = metrics.getMeter("suaveplan.i18n.formatter.date"); cached = { durationMs: meter.createHistogram("i18n.format.date.duration_ms", { description: "Duration in ms of DateFormatter.format / formatDateRange; labels: locale, preset.", unit: "ms", }), cacheHit: meter.createCounter("i18n.format.cache_hit", { description: "Format-time cache reuse counter; labels: formatter (date).", }), }; return cached; } export function recordDateFormat( locale: string, preset: string, durationMs: number ): void { const ins = ensureInstruments(); const attributes = { locale, preset }; ins.durationMs.record(durationMs, attributes); state.durationSamples.push({ attributes }); } export function recordDateCacheHit(): void { const ins = ensureInstruments(); const attributes = { formatter: "date" }; ins.cacheHit.add(1, attributes); state.cacheHitSamples.push({ attributes }); } export function getDateMetricsState(): DateMetricsState { return state; } export function resetDateMetricsState(): void { state.durationSamples.length = 0; state.cacheHitSamples.length = 0; }