From db3566c1a36dfec818df6946bf0435bd6075d11a Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Tue, 18 Aug 2026 10:47:00 +0100 Subject: [PATCH] chore: correct AI Gateway metric provider label and cardinality notes (#28220) The cardinality notes in `aibridge/metrics/metrics.go` assume the `provider` label takes one of three values, and two for the key pool metrics. That was accurate when the notes were written: `provider` is the provider instance name, and the name defaulted to one of the three provider types aibridge supports. Instances can now be given their own names, so the label takes any configured name and the series counts scale with the number of configured providers rather than being capped at a fixed number. The monitoring docs are also updated to make clear that `provider` is the provider instance name. Comments and documentation only, no behaviour change. Follow-up to #28210. --- aibridge/metrics/metrics.go | 29 +++++++++++++------------- docs/ai-coder/ai-gateway/monitoring.md | 3 +++ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/aibridge/metrics/metrics.go b/aibridge/metrics/metrics.go index 99d6c3e0c2..8584261da2 100644 --- a/aibridge/metrics/metrics.go +++ b/aibridge/metrics/metrics.go @@ -5,6 +5,7 @@ import ( "github.com/prometheus/client_golang/prometheus/promauto" ) +// provider is the provider instance name, and model is the requested AI model. var baseLabels = []string{"provider", "model"} const ( @@ -51,20 +52,20 @@ func NewMetrics(reg prometheus.Registerer) *Metrics { return &Metrics{ // Interception-related metrics. - // Pessimistic cardinality: 3 providers, 5 models, 2 statuses, 3 routes, 3 methods, 10 clients = up to 2700 PER INITIATOR. + // Pessimistic cardinality: N provider names, 5 models, 2 statuses, 3 routes, 3 methods, 10 clients = up to 900N PER INITIATOR. InterceptionCount: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Subsystem: "interceptions", Name: "total", Help: "The count of intercepted requests.", }, append(baseLabels, "status", "route", "method", "initiator_id", "client")), - // Pessimistic cardinality: 3 providers, 5 models, 3 routes = up to 45. + // Pessimistic cardinality: N provider names, 5 models, 3 routes = up to 15N. // NOTE: route is not unbounded because this is only for intercepted routes. InterceptionsInflight: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ Subsystem: "interceptions", Name: "inflight", Help: "The number of intercepted requests which are being processed.", }, append(baseLabels, "route")), - // Pessimistic cardinality: 3 providers, 5 models, 7 buckets + 3 extra series (count, sum, +Inf) = up to 150. + // Pessimistic cardinality: N provider names, 5 models, 7 buckets + 3 extra series (count, sum, +Inf) = up to 50N. InterceptionDuration: promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{ Subsystem: "interceptions", Name: "duration_seconds", @@ -76,7 +77,7 @@ func NewMetrics(reg prometheus.Registerer) *Metrics { Buckets: []float64{0.5, 2, 5, 15, 30, 60, 120}, }, baseLabels), - // Pessimistic cardinality: 3 providers, 10 routes, 3 methods = up to 90. + // Pessimistic cardinality: N provider names, 10 routes, 3 methods = up to 30N. // NOTE: route is not unbounded because PassthroughRoutes (see provider.go) is a static list. PassthroughCount: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Subsystem: "passthrough", @@ -86,7 +87,7 @@ func NewMetrics(reg prometheus.Registerer) *Metrics { // Prompt-related metrics. - // Pessimistic cardinality: 3 providers, 5 models, 10 clients = up to 150 PER INITIATOR. + // Pessimistic cardinality: N provider names, 5 models, 10 clients = up to 50N PER INITIATOR. PromptCount: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Subsystem: "prompts", Name: "total", @@ -95,7 +96,7 @@ func NewMetrics(reg prometheus.Registerer) *Metrics { // Token-related metrics. - // Pessimistic cardinality: 3 providers, 5 models, 10 types, 10 clients = up to 1500 PER INITIATOR. + // Pessimistic cardinality: N provider names, 5 models, 10 types, 10 clients = up to 500N PER INITIATOR. TokenUseCount: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Subsystem: "tokens", Name: "total", @@ -104,13 +105,13 @@ func NewMetrics(reg prometheus.Registerer) *Metrics { // Tool-related metrics. - // Pessimistic cardinality: 3 providers, 5 models, 3 servers, 30 tools = up to 1350. + // Pessimistic cardinality: N provider names, 5 models, 3 servers, 30 tools = up to 450N. InjectedToolUseCount: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Subsystem: "injected_tool_invocations", Name: "total", Help: "The number of times an injected MCP tool was invoked by AI Gateway.", }, append(baseLabels, "server", "name")), - // Pessimistic cardinality: 3 providers, 5 models, 30 tools = up to 450. + // Pessimistic cardinality: N provider names, 5 models, 30 tools = up to 150N. NonInjectedToolUseCount: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Subsystem: "non_injected_tool_selections", Name: "total", @@ -119,19 +120,19 @@ func NewMetrics(reg prometheus.Registerer) *Metrics { // Circuit breaker metrics. - // Pessimistic cardinality: 3 providers, 2 endpoints, 5 models = up to 30. + // Pessimistic cardinality: N provider names, 2 endpoints, 5 models = up to 10N. CircuitBreakerState: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ Subsystem: "circuit_breaker", Name: "state", Help: "Current state of the circuit breaker (0=closed, 0.5=half-open, 1=open).", }, []string{"provider", "endpoint", "model"}), - // Pessimistic cardinality: 3 providers, 2 endpoints, 5 models = up to 30. + // Pessimistic cardinality: N provider names, 2 endpoints, 5 models = up to 10N. CircuitBreakerTrips: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Subsystem: "circuit_breaker", Name: "trips_total", Help: "Total number of times the circuit breaker transitioned to open state.", }, []string{"provider", "endpoint", "model"}), - // Pessimistic cardinality: 3 providers, 2 endpoints, 5 models = up to 30. + // Pessimistic cardinality: N provider names, 2 endpoints, 5 models = up to 10N. CircuitBreakerRejects: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Subsystem: "circuit_breaker", Name: "rejects_total", @@ -140,21 +141,21 @@ func NewMetrics(reg prometheus.Registerer) *Metrics { // Key pool failover metrics. - // Pessimistic cardinality: 2 providers, 2 reasons = up to 4. + // Pessimistic cardinality: N provider names with a key pool, 2 reasons = up to 2N. KeyPoolStateTransitions: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Subsystem: "key_pool", Name: "state_transitions_total", Help: "The number of API key state transitions during failover " + "(reason: rate_limited, unauthorized).", }, []string{"provider", "reason"}), - // Pessimistic cardinality: 2 providers, 2 outcomes = up to 4. + // Pessimistic cardinality: N provider names with a key pool, 2 outcomes = up to 2N. KeyPoolExhaustions: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Subsystem: "key_pool", Name: "exhaustions_total", Help: "The number of times the key pool was exhausted with no usable key " + "(outcome: rate_limited, auth_failed).", }, []string{"provider", "outcome"}), - // Pessimistic cardinality: 2 providers, 7 buckets + 3 extra series (count, sum, +Inf) = up to 20. + // Pessimistic cardinality: N provider names with a key pool, 7 buckets + 3 extra series (count, sum, +Inf) = up to 10N. KeyPoolFailoverAttempts: promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{ Subsystem: "key_pool", Name: "failover_attempts", diff --git a/docs/ai-coder/ai-gateway/monitoring.md b/docs/ai-coder/ai-gateway/monitoring.md index 937cf7360d..8cb9670899 100644 --- a/docs/ai-coder/ai-gateway/monitoring.md +++ b/docs/ai-coder/ai-gateway/monitoring.md @@ -25,6 +25,9 @@ Each process exports metrics for the traffic that it handles: Refer to [provider configuration](./providers.md) for the provider reload lifecycle these metrics describe. +The `provider` label is the provider instance name. +Some metrics use the explicit `provider_name` or `provider_type` labels for clarity. + | Metric | Type | Labels | Purpose | |--------------------------------------------------------------------|-----------|----------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------| | `coder_ai_gateway_interceptions_total` | counter | `client`, `initiator_id`, `method`, `model`, `provider`, `route`, `status` | Intercepted requests. |