Add Zoekt node, task-state, and stale-storage gauges
Summary
Add three new gauges to lib/gitlab_exporter/database/zoekt.rb to cover Zoekt observability gaps that currently have no equivalent here. These were originally proposed as Rails-side gauges in gitlab-org/gitlab!241045 (merged) but moved here during review because they are pure SQL aggregations and fit the exporter's pattern (DB-derived state metrics).
Background
gitlab-org/gitlab!241045 adds in-process per-request Zoekt metrics to the Rails app (http_zoekt_requests_*, sidekiq_zoekt_requests_*). Those four metrics must live in Rails because they observe data in SafeRequestStore that the exporter cannot see.
The three gauges in this issue are different: they're DB aggregations with no in-process dependency, so they belong here alongside the existing 10 search_zoekt_* metrics in database/zoekt.rb.
Proposed metrics
1. search_zoekt_node_enabled_namespaces
-
Type: gauge
-
Labels:
node_id,node_name -
Description: Number of enabled namespaces per Zoekt node.
-
Query sketch:
SELECT zn.id AS node_id, zn.metadata ->> 'name' AS node_name, COUNT(DISTINCT zi.zoekt_enabled_namespace_id) AS count FROM zoekt_nodes zn LEFT JOIN zoekt_indices zi ON zi.zoekt_node_id = zn.id GROUP BY zn.id, zn.metadata ->> 'name';
2. search_zoekt_node_tasks
-
Type: gauge
-
Labels:
node_id,node_name,state(one ofpending,processing,done,skipped,failed,orphaned) -
Description: Number of Zoekt indexing tasks on a node, broken down by state.
-
Query sketch:
SELECT zn.id AS node_id, zn.metadata ->> 'name' AS node_name, zt.state, COUNT(*) AS count FROM zoekt_nodes zn LEFT JOIN zoekt_tasks zt ON zt.zoekt_node_id = zn.id GROUP BY zn.id, zn.metadata ->> 'name', zt.state;The state enum maps (from
Search::Zoekt::Taskable):Numeric Label 0 pending1 processing10 done250 skipped255 failed256 orphanedNote that the value of
search_zoekt_task_processing_queue_sizeis approximatelysum(search_zoekt_node_tasks{state=~"pending|processing"})(the existing metric also filters byperform_at <= NOW(), which the new gauge does not). We could either:- (a) Add the new gauge alongside the existing one and mark
search_zoekt_task_processing_queue_sizeas deprecated in a follow-up, or - (b) Replace the existing one entirely in a single change.
Option (a) is safer because anyone querying the old metric (alerts, dashboards) keeps working. Recommend going with (a) and removing the old metric in a later release once consumers have migrated.
- (a) Add the new gauge alongside the existing one and mark
3. search_zoekt_indices_with_stale_used_storage_bytes
-
Type: gauge
-
Labels: none
-
Description: Number of Zoekt indices whose
used_storage_bytesvalue has not been updated since the last index run. -
Query sketch:
SELECT COUNT(*) FROM zoekt_indices WHERE last_indexed_at >= used_storage_bytes_updated_at;This mirrors the Rails
Search::Zoekt::Index.with_stale_used_storage_bytes_updated_atscope (defined inee/app/models/search/zoekt/index.rb).
Implementation notes
Each metric should follow the pattern already used by the other 10 Zoekt metrics in database/zoekt.rb:
- SQL constant at the top of
ZoektCollector. - Execution in
ZoektCollector#run, added to the result hash. PrometheusMetrics.describe(...)line at the top ofZoektProber.process_*_resultsmethod called fromprocess_results.add_*_to_metricmethod that calls@metrics.add(...).- Spec coverage in
spec/database/zoekt_spec.rb.
Release / rollout
After this lands, the gem needs to be released and bumped in:
gitlab-org/omnibus-gitlab(for Linux package installs)gitlab-org/charts/gitlab(for Helm chart installs)
Until those bumps merge, self-managed installs won't see the new metrics. GitLab.com picks them up on its own cadence.
References
- Originating MR: gitlab-org/gitlab!241045 (merged)
- Originating issue: gitlab-org/gitlab#591830 (closed)
- Parent epic: gitlab-org#17919 (closed)
- Existing Zoekt collector: https://gitlab.com/gitlab-org/ruby/gems/gitlab-exporter/-/blob/master/lib/gitlab_exporter/database/zoekt.rb