# DisplayName observability _(no submodules)_ ## Purpose The DisplayName 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 instruments match the canonical Wave-3 formatter contract — every sibling formatter (number, relative-time, list, date, currency, collator, segmenter) emits the same two metric names so dashboards and alerts compose cleanly across the family. ## Features - Histogram `i18n.format.display_name.duration_ms` (unit `ms`) — per-format wall-clock time - Counter `i18n.format.cache_hit{formatter="display_name"}` — increments on cache reuse only - In-memory state ring (`getDisplayNameMetricsState()`) for spec-conformance assertions - `resetDisplayNameMetricsState()` test-only helper to clear the ring between cases ## Usage: Basic Example ```ts import { metrics } from "@opentelemetry/api"; import { MeterProvider } from "@opentelemetry/sdk-metrics"; // import your MetricReader / OTLP exporter ... const provider = new MeterProvider({ readers: [/* reader */] }); metrics.setGlobalMeterProvider(provider); // Subsequent formatDisplayName calls now emit through your reader. import { formatDisplayName } from "@suaveplan/i18n-formatter-display-name"; formatDisplayName("fr", "en-GB", { type: "language" }); ``` ## Usage: Advanced Example ```ts import { describe, expect, it } from "@suaveplan/testing/runner"; import { clearDisplayNameCache, formatDisplayName, } from "@suaveplan/i18n-formatter-display-name"; import { getDisplayNameMetricsState, resetDisplayNameMetricsState, } from "@suaveplan/i18n-formatter-display-name"; it("emits histogram + cache-hit counter", () => { clearDisplayNameCache(); resetDisplayNameMetricsState(); formatDisplayName("fr", "en-GB", { type: "language" }); formatDisplayName("fr", "en-GB", { type: "language" }); const state = getDisplayNameMetricsState(); expect(state.durationSamples).toHaveLength(2); expect(state.cacheHitSamples).toHaveLength(1); }); ``` ## API Reference ### `recordDisplayNameFormat(locale, type, style, durationMs): void` Records the duration histogram sample. Tags: `locale`, `type`, `style`. Called internally by `formatDisplayName`; consumers do not need to invoke it directly. ### `recordDisplayNameCacheHit(): void` Increments the cache-hit counter with the constant tag `{ formatter: "display_name" }`. Called internally on a cache hit. ### `getDisplayNameMetricsState(): DisplayNameMetricsState` Returns the in-memory ring of `durationSamples` and `cacheHitSamples`. Used by spec-conformance tests to assert exact attribute payloads. ### `resetDisplayNameMetricsState(): void` Clears both ring buffers. Test-only helper; call before the under-test code to assert exactly the samples your scenario generates. ## Implementation Notes - The OTel meter is named `suaveplan.i18n.formatter.display_name`. Every formatter in the family has its own meter so OTel resource attributes can be tied per-package if a consumer chooses. - Sample dashboard query (PromQL/Grafana over OTLP): `histogram_quantile(0.99, sum(rate(i18n_format_display_name_duration_ms_bucket[5m])) by (le, locale))` - The in-memory ring is intentionally unbounded — tests are short and call `resetDisplayNameMetricsState()` between cases. A long-running test loop should call reset to avoid memory growth. - `style` defaults to `"long"` in the histogram tag when the caller omits it; `type` is always required so it is never defaulted.