fleet-manager: chrony tracking metrics relative to the NTP source

The agent only reported chrony as synced|unsynced — nothing about how well the
clock tracks. Parse `chronyc tracking` for the source-relative metrics.

- proto: HealthSnapshot.chrony_offset_seconds (16, signed system-time offset,
  fast=+), chrony_source (17, reference name/IP), chrony_stratum (18); regenerated.
- agent: replace chronyState() with chronyTracking()/parseChrony() — one exec,
  parses Leap status + Reference ID + Stratum + System time offset (+ test).
- manager: Health.{ChronyOffset,ChronySource,ChronyStratum}; snapshotToHealth maps
  them; influx writes chrony_offset_seconds/_stratum/_source and whitelists the
  offset + stratum as graphable fields.
- UI: chronySummary() + offsetMs() — the chrony row now shows
  "synced · 192.168.50.10 · s3 · +0.01ms" instead of just "synced".
This commit is contained in:
Audiobuzz
2026-07-10 06:47:27 +00:00
parent df7dad81b7
commit 1c68c37824
11 changed files with 222 additions and 45 deletions
+12 -9
View File
@@ -26,7 +26,7 @@ const influxMeasurement = "fleet_health"
var metricFields = map[string]bool{
"load_avg": true, "cpu_pct": true, "temp_c": true, "mem_used_pct": true,
"tmpfs_used_pct": true, "chromium_crashes": true, "kiosk_active": true,
"uptime_seconds": true,
"uptime_seconds": true, "chrony_offset_seconds": true, "chrony_stratum": true,
}
var serialRe = regexp.MustCompile(`^[0-9a-fA-F]+$`) // cert serials are hex
@@ -74,14 +74,17 @@ func snapshotPoint(serial, hostnqn, starship string, snap *fleetpb.HealthSnapsho
tags["starship"] = starship
}
fields := map[string]any{
"load_avg": snap.GetLoadAvg(),
"cpu_pct": snap.GetCpuPct(),
"temp_c": snap.GetTempC(),
"mem_used_pct": snap.GetMemUsedPct(),
"tmpfs_used_pct": snap.GetTmpfsUsedPct(),
"chromium_crashes": int64(snap.GetChromiumCrashes()),
"kiosk_active": boolToInt(snap.GetKioskActive()),
"uptime_seconds": snap.GetUptimeSeconds(),
"load_avg": snap.GetLoadAvg(),
"cpu_pct": snap.GetCpuPct(),
"temp_c": snap.GetTempC(),
"mem_used_pct": snap.GetMemUsedPct(),
"tmpfs_used_pct": snap.GetTmpfsUsedPct(),
"chromium_crashes": int64(snap.GetChromiumCrashes()),
"kiosk_active": boolToInt(snap.GetKioskActive()),
"uptime_seconds": snap.GetUptimeSeconds(),
"chrony_offset_seconds": snap.GetChronyOffsetSeconds(),
"chrony_stratum": int64(snap.GetChronyStratum()),
"chrony_source": snap.GetChronySource(),
// string status fields kept as fields too (handy for annotating charts)
"nvme_root": snap.GetNvmeRoot(),
"auth": snap.GetAuth(),