first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
# Segmenter observability
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
The Segmenter 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 emits the same two metric names so dashboards
and alerts compose cleanly across the family.
## Features
- Histogram `i18n.format.segmenter.duration_ms` (unit `ms`) — per-segment wall-clock time
- Counter `i18n.format.cache_hit{formatter="segmenter"}` — increments on cache reuse only
- In-memory state ring (`getSegmenterMetricsState()`) for spec-conformance
- `resetSegmenterMetricsState()` test-only helper
## Usage: Basic Example
```ts
import { metrics } from "@opentelemetry/api";
import { MeterProvider } from "@opentelemetry/sdk-metrics";
const provider = new MeterProvider({ readers: [/* reader */] });
metrics.setGlobalMeterProvider(provider);
import { segmentText } from "@suaveplan/i18n-formatter-segmenter";
segmentText("hello", "en-GB", { granularity: "word" });
// emits via your reader
```
## Usage: Advanced Example
```ts
import { describe, expect, it } from "@suaveplan/testing/runner";
import {
clearSegmenterCache,
segmentText,
} from "@suaveplan/i18n-formatter-segmenter";
import {
getSegmenterMetricsState,
resetSegmenterMetricsState,
} from "@suaveplan/i18n-formatter-segmenter";
it("emits histogram + cache-hit counter", () => {
clearSegmenterCache();
resetSegmenterMetricsState();
segmentText("hello", "en-GB", { granularity: "word" });
segmentText("hello", "en-GB", { granularity: "word" });
const state = getSegmenterMetricsState();
expect(state.durationSamples).toHaveLength(2);
expect(state.cacheHitSamples).toHaveLength(1);
expect(state.durationSamples[0]?.attributes).toMatchObject({
locale: "en-GB",
granularity: "word",
});
});
```
## API Reference
### `recordSegmenterFormat(locale, granularity, durationMs): void`
Records the duration histogram sample. Tags: `locale`, `granularity`.
Called internally by `segmentText` / `formatSegments`.
### `recordSegmenterCacheHit(): void`
Increments the cache-hit counter with the constant tag
`{ formatter: "segmenter" }`.
### `getSegmenterMetricsState(): SegmenterMetricsState`
Returns the in-memory ring of `durationSamples` and
`cacheHitSamples`. Used by spec-conformance tests.
### `resetSegmenterMetricsState(): void`
Clears both ring buffers. Test-only helper.
## Implementation Notes
- The OTel meter is named `suaveplan.i18n.formatter.segmenter`. Every
formatter in the family has its own meter so OTel resource
attributes can be tied per-package if a consumer chooses.
- `granularity` defaults to `"grapheme"` in the histogram tag when
the caller omits it; `locale` is always required so it's never
defaulted.
- Sample dashboard query (PromQL/Grafana over OTLP):
`histogram_quantile(0.99, sum(rate(i18n_format_segmenter_duration_ms_bucket[5m])) by (le, locale, granularity))`
- The in-memory ring is intentionally unbounded — tests are short
and call `resetSegmenterMetricsState()` between cases. A
long-running test loop should call reset to avoid memory growth.