Files
skills/docs/localization/i18n/i18n-formatter-date/src/observability/observability.md
2026-05-29 08:20:56 +01:00

3.2 KiB

Date observability

(no submodules)

Purpose

The Date formatter exports two OpenTelemetry instruments and a small in-memory state ring so spec-conformance tests can assert exact attribute payloads without standing up a full SDK exporter. The instrument names match the canonical Wave-3 formatter contract — every sibling formatter (number, relative-time, list, display-name, currency, collator, segmenter) emits the same two metric names so dashboards and alerts compose cleanly across the family.

Features

  • Histogram i18n.format.date.duration_ms (unit ms) — per-format wall-clock time
  • Counter i18n.format.cache_hit{formatter="date"} — increments on cache reuse only
  • In-memory state ring (getDateMetricsState()) for spec-conformance
  • resetDateMetricsState() test-only helper to clear the ring

Usage: Basic Example

import { metrics } from "@opentelemetry/api";
import { MeterProvider } from "@opentelemetry/sdk-metrics";

const provider = new MeterProvider({ readers: [/* reader */] });
metrics.setGlobalMeterProvider(provider);

import { formatDate } from "@suaveplan/i18n-formatter-date";
formatDate(new Date(2026, 0, 1), "en-GB", { preset: "short" });
// emits via your reader

Usage: Advanced Example

import { describe, expect, it } from "@suaveplan/testing/runner";
import {
    clearDateFormatterCache,
    formatDate,
} from "@suaveplan/i18n-formatter-date";
import {
    getDateMetricsState,
    resetDateMetricsState,
} from "@suaveplan/i18n-formatter-date";

it("emits histogram + cache-hit counter", () => {
    clearDateFormatterCache();
    resetDateMetricsState();
    formatDate(new Date(2026, 0, 1), "en-GB", { preset: "short" });
    formatDate(new Date(2026, 0, 1), "en-GB", { preset: "short" });
    const state = getDateMetricsState();
    expect(state.durationSamples).toHaveLength(2);
    expect(state.cacheHitSamples).toHaveLength(1);
    expect(state.durationSamples[0]?.attributes).toMatchObject({
        locale: "en-GB",
        preset: "short",
    });
});

API Reference

recordDateFormat(locale, preset, durationMs): void

Records the duration histogram sample. Tags: locale, preset. Called internally by formatDate / formatDateRange.

recordDateCacheHit(): void

Increments the cache-hit counter with the constant tag { formatter: "date" }.

getDateMetricsState(): DateMetricsState

Returns the in-memory ring of durationSamples and cacheHitSamples. Used by spec-conformance tests.

resetDateMetricsState(): void

Clears both ring buffers. Test-only helper.

Implementation Notes

  • The OTel meter is named suaveplan.i18n.formatter.date. Every formatter in the family has its own meter so OTel resource attributes can be tied per-package if a consumer chooses.
  • When the caller omits preset, the histogram tag is "custom" so every sample carries a non-null preset attribute.
  • Sample dashboard query (PromQL/Grafana over OTLP): histogram_quantile(0.99, sum(rate(i18n_format_date_duration_ms_bucket[5m])) by (le, locale, preset))
  • The in-memory ring is intentionally unbounded — tests are short and call resetDateMetricsState() between cases. A long-running test loop should call reset to avoid memory growth.