Package com.tnsai.quality.observability
Class LabelCardinalityGuard
java.lang.Object
com.tnsai.quality.observability.LabelCardinalityGuard
Bounds the number of distinct values a Prometheus label can take.
Prometheus creates one time series per unique label combination. If any label accepts unbounded strings (user-supplied model names, error messages folded into error_type, trace snippets), series cardinality explodes: the scrape endpoint grows multi-MB, the TSDB exhausts memory, and dashboards time out trying to enumerate options. This is a well-documented operational hazard — do not overuse labels.
Strategy
- Null / empty →
"unknown". Consistent bucket for missing data. - Allowlisted value → pass through unchanged. Stable known values.
- Novel value below the cap → recorded and passed through. Tolerates organic growth (new provider, new error type).
- Novel value at/above the cap → collapsed into
OVERFLOW_BUCKET. The metric still records the event; it just shares a bucket with other rare values. Logged once per bucketed value at WARN.
Common configurations
LabelCardinalityGuard providers = LabelCardinalityGuard.builder("llm.provider")
.maxDistinct(32)
.allow("anthropic", "openai", "google", "azure", "ollama",
"huggingface", "bedrock", "mistral", "groq", "cohere",
"openrouter", "deepseek")
.build();
LabelCardinalityGuard models = LabelCardinalityGuard.builder("llm.model")
.maxDistinct(256) // models legitimately expand; buffer is larger
.build(); // no allowlist — just the cap
LabelCardinalityGuard errors = LabelCardinalityGuard.builder("llm.error_type")
.maxDistinct(16)
.allow("timeout", "rate_limit", "auth", "invalid_request",
"server_error", "parse_error", "network")
.build();
Thread-safe.
- Since:
- 0.3.0
-
Nested Class Summary
Nested Classes -
Field Summary
Fields -
Method Summary
Modifier and TypeMethodDescriptionintCount of distinct admitted (non-allowlisted, non-bucket) values currently tracked.Starts a new builder for a label namedname.Returns a safe label value forraw.voidreset()Resets the admitted-values memory.
-
Field Details
-
UNKNOWN_BUCKET
Label value used when an input is null / empty.- See Also:
-
OVERFLOW_BUCKET
Label value used when the distinct-count cap has been hit.- See Also:
-
-
Method Details
-
builder
Starts a new builder for a label namedname. -
normalise
Returns a safe label value forraw.- Parameters:
raw- caller-supplied value; may be null or unbounded- Returns:
- the original value if allowed or under the cap;
UNKNOWN_BUCKETfor null/empty;OVERFLOW_BUCKETotherwise
-
admittedCount
public int admittedCount()Count of distinct admitted (non-allowlisted, non-bucket) values currently tracked. -
reset
public void reset()Resets the admitted-values memory. Intended for tests.
-