79 lines
2.1 KiB
TypeScript
79 lines
2.1 KiB
TypeScript
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<string, string | number>;
|
|
}
|
|
|
|
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;
|
|
}
|