Files
suaveplan/packages/localization/i18n/i18n-backend-http/src/observability/observability.md
2026-05-27 23:47:53 +01:00

2.8 KiB

@suaveplan/i18n-backend-http/observability

(no submodules)

Purpose

Lazy OpenTelemetry instrument factory and matched in-memory state ring for @suaveplan/i18n-backend-http. Production paths in backend.ts call recordRead(...) once per HttpBackend.read call; the instruments are no-ops until a MeterProvider is registered against @opentelemetry/api, so consumers pay zero overhead unless they wire up the SDK. The matched state ring exists so spec-conformance tests can assert exact attribute payloads without standing up a full SDK + InMemoryMetricExporter pipeline.

Features

  • i18n.backend.http.read_duration_ms — Histogram, milliseconds. Attributes: locale, namespace, outcome ∈ hit | miss | error.
  • i18n.backend.http.read_total — Counter. Attribute: outcome.
  • i18n.backend.http.read_errors_total — Counter. Attributes: code (the I18N.* error code), optional status (HTTP status code as string when the error originated from a known HTTP response).
  • Zero-cost when no MeterProvider is wired — every instrument is a cached singleton.
  • Test-only state ring + reset helpers (getHttpBackendMetricsState, resetHttpBackendMetricsState, resetHttpBackendMetricsCache).

Usage: Basic Example

import { recordRead } from "@suaveplan/i18n-backend-http/observability";

recordRead("en", "auth", "hit", 0.42);

Usage: Advanced Example

import {
    getHttpBackendMetricsState,
    recordRead,
    resetHttpBackendMetricsState,
} from "@suaveplan/i18n-backend-http/observability";

resetHttpBackendMetricsState();
recordRead("xx", "auth", "miss", 1.2, "I18N.BACKEND_LOCALE_NOT_AVAILABLE", 404);
const state = getHttpBackendMetricsState();
console.log(state.readErrorsTotal);
// → [{ attributes: { code: "I18N.BACKEND_LOCALE_NOT_AVAILABLE", status: "404" } }]

API Reference

  • getHttpBackendMetrics(): { readDurationMs, readTotal, readErrorsTotal } — idempotent factory.
  • recordRead(locale, namespace, outcome, durationMs, errorCode?, status?) — emit + ring-record.
  • getHttpBackendMetricsState(): HttpBackendMetricsState — frozen snapshot.
  • resetHttpBackendMetricsState() / resetHttpBackendMetricsCache() — test helpers.

Implementation Notes

status is encoded as a string attribute so OTel SDK aggregators can union it with the code label without numeric coercion ambiguity. The counter cardinality is bounded by the small I18N.* error-code set times a typical handful of HTTP statuses (404 / 500 / 502 / 503), which stays well below downstream backend high-cardinality limits. The cached instruments survive across recordRead calls inside one process — the resetHttpBackendMetricsCache helper exists purely so tests can verify the cache-hit path is exercised.