v0.295.0: a box that was off at its backup time catches up once (R-871, decision 109); the missed-backup banner (decision 110); a late daily timer after a host suspend is skipped
gates / gates (push) Successful in 31s
gates / gates (push) Successful in 31s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -329,3 +329,31 @@ func (s *MetricsStore) Prune(olderThan time.Duration) (int64, error) {
|
||||
|
||||
return total, nil
|
||||
}
|
||||
|
||||
// SampleCount is how many system samples (one a minute) exist in [from, to) — the box's own record of whether it
|
||||
// was on (R-871 banner: "the box was off at 02:30").
|
||||
func (s *MetricsStore) SampleCount(from, to time.Time) (int, error) {
|
||||
var n int
|
||||
err := s.db.QueryRow(`SELECT COUNT(*) FROM system_metrics WHERE ts >= ? AND ts < ?`, from.Unix(), to.Unix()).Scan(&n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// HourSampleCounts returns the number of system samples per UTC hour start (unix seconds) in [from, to) — the
|
||||
// banner's "when is this box usually on" pattern (R-871). At most 24×7 rows for a week.
|
||||
func (s *MetricsStore) HourSampleCounts(from, to time.Time) (map[int64]int, error) {
|
||||
rows, err := s.db.Query(`SELECT (ts / 3600) * 3600 AS h, COUNT(*) FROM system_metrics WHERE ts >= ? AND ts < ? GROUP BY h`, from.Unix(), to.Unix())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
out := map[int64]int{}
|
||||
for rows.Next() {
|
||||
var h int64
|
||||
var n int
|
||||
if err := rows.Scan(&h, &n); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[h] = n
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user