improve logging and concurrent vcenter inventory
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-01-21 10:25:04 +11:00
parent 00805513c9
commit 2483091861
5 changed files with 115 additions and 55 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"fmt"
"log/slog"
"strconv"
"strings"
"time"
@@ -44,7 +45,7 @@ func boolStringFromInterface(value interface{}) string {
// latestHourlySnapshotBefore finds the most recent hourly snapshot table prior to the given time, skipping empty tables.
func latestHourlySnapshotBefore(ctx context.Context, dbConn *sqlx.DB, cutoff time.Time) (string, error) {
tables, err := listLatestHourlyWithRows(ctx, dbConn, "", cutoff.Unix(), 1)
tables, err := listLatestHourlyWithRows(ctx, dbConn, "", cutoff.Unix(), 1, nil)
if err != nil {
return "", err
}
@@ -68,7 +69,7 @@ func parseSnapshotTime(table string) (int64, bool) {
}
// listLatestHourlyWithRows returns recent hourly snapshot tables (ordered desc by time) that have rows, optionally filtered by vcenter.
func listLatestHourlyWithRows(ctx context.Context, dbConn *sqlx.DB, vcenter string, beforeUnix int64, limit int) ([]snapshotTable, error) {
func listLatestHourlyWithRows(ctx context.Context, dbConn *sqlx.DB, vcenter string, beforeUnix int64, limit int, logger *slog.Logger) ([]snapshotTable, error) {
if limit <= 0 {
limit = 50
}
@@ -88,31 +89,54 @@ LIMIT ?
for rows.Next() {
var name string
var ts int64
var count int64
var count sql.NullInt64
if scanErr := rows.Scan(&name, &ts, &count); scanErr != nil {
continue
}
if err := db.ValidateTableName(name); err != nil {
continue
}
// Use snapshot_count first; fall back to row check (and vcenter filter) only when needed.
if count == 0 {
if has, _ := db.TableHasRows(ctx, dbConn, name); !has {
continue
if count.Valid && count.Int64 == 0 {
if logger != nil {
logger.Debug("skipping snapshot table with zero count", "table", name, "snapshot_time", ts)
}
continue
}
probed := false
hasRows := true
start := time.Now()
if !count.Valid {
probed = true
if ok, err := db.TableHasRows(ctx, dbConn, name); err == nil {
hasRows = ok
} else {
hasRows = false
if logger != nil {
logger.Debug("snapshot table probe failed", "table", name, "error", err)
}
}
}
if vcenter != "" {
if vcenter != "" && hasRows {
probed = true
vrows, qerr := querySnapshotRows(ctx, dbConn, name, []string{"VmId"}, `"Vcenter" = ? LIMIT 1`, vcenter)
if qerr != nil {
continue
}
hasVcenter := vrows.Next()
vrows.Close()
if !hasVcenter {
continue
if qerr == nil {
hasRows = vrows.Next()
vrows.Close()
} else {
hasRows = false
if logger != nil {
logger.Debug("snapshot vcenter filter probe failed", "table", name, "vcenter", vcenter, "error", qerr)
}
}
}
out = append(out, snapshotTable{Table: name, Time: ts})
elapsed := time.Since(start)
if logger != nil {
logger.Debug("evaluated snapshot table", "table", name, "snapshot_time", ts, "snapshot_count", count, "probed", probed, "has_rows", hasRows, "elapsed", elapsed)
}
if !hasRows {
continue
}
out = append(out, snapshotTable{Table: name, Time: ts, Count: count})
}
return out, nil
}