fix(obs): count scanned versions independent of ILM (#4516)

versions_scanned for both the scanner and ILM collectors was read from
the Lifecycle work source's `checked` counter, which is never recorded on
the production scan path — so rustfs_scanner_versions_scanned_total and
rustfs_ilm_versions_scanned_total sat at zero even while objects_scanned
climbed. The two metrics also have distinct intended meanings that were
conflated: "versions scanned" (all versions, any bucket) vs "versions
checked for ILM actions" (lifecycle-configured buckets only).

Add a lifetime `versions_scanned` counter recorded for every version the
scanner walks (independent of ILM), and record the Lifecycle source's
`checked` counter from the ILM evaluator so the ILM metric reflects the
real checked subset. The scanner collector now reports total scanned
versions; the ILM collector keeps the ILM-checked subset.

Closes backlog#995 (OBS-09).

Co-authored-by: heihutu <heihutu@gmail.com>
This commit is contained in:
houseme
2026-07-09 00:50:51 +08:00
committed by GitHub
parent e829430d89
commit 6ab8636734
4 changed files with 85 additions and 1 deletions
+6 -1
View File
@@ -990,7 +990,12 @@ pub async fn collect_scanner_metric_stats() -> Option<ScannerStats> {
let completed_cycles = metrics.life_time_ops.get("scan_cycle").copied().unwrap_or_default();
let directories_scanned = metrics.life_time_ops.get("scan_folder").copied().unwrap_or_default();
let objects_scanned = metrics.life_time_ops.get("scan_object").copied().unwrap_or_default();
let versions_scanned = scanner_lifecycle_checked_versions(&metrics);
// Real scan coverage: every version the scanner walked, independent of ILM
// rules. The ILM-checked subset (`scanner_lifecycle_checked_versions`) still
// feeds the ILM collector's versions_scanned, but the scanner collector must
// report the total scanned versions — otherwise clusters without lifecycle
// rules report zero here while objects_scanned keeps climbing.
let versions_scanned = metrics.versions_scanned;
let reference_time = metrics.cycles_completed_at.last().copied().unwrap_or(metrics.current_started);
let last_activity_seconds = now.signed_duration_since(reference_time).num_seconds().max(0) as u64;
let active_paths = metrics.active_scan_paths as u64;