better handle skipped inventories
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-01-20 17:18:43 +11:00
parent 7ea02be91a
commit c8bb30c788
4 changed files with 32 additions and 14 deletions

View File

@@ -31,7 +31,7 @@ If you just want to run a single inventory snapshot across all configured vCente
exit (no scheduler/server), use: exit (no scheduler/server), use:
```shell ```shell
vctp -settings /path/to/vctp.yml -run-inventory-once vctp -settings /path/to/vctp.yml -run-inventory
``` ```
### Database Configuration ### Database Configuration

View File

@@ -1086,21 +1086,36 @@ func (c *CronTask) captureHourlySnapshotForVcenter(ctx context.Context, startTim
c.Logger.Warn("failed to locate previous hourly snapshot for deletion comparison", "error", prevTableErr, "url", url) c.Logger.Warn("failed to locate previous hourly snapshot for deletion comparison", "error", prevTableErr, "url", url)
} }
prevSnapshotTime := int64(0)
if prevTableName != "" {
if suffix := strings.TrimPrefix(prevTableName, "inventory_hourly_"); suffix != prevTableName {
if ts, err := strconv.ParseInt(suffix, 10, 64); err == nil {
prevSnapshotTime = ts
}
}
}
if prevTableName != "" { if prevTableName != "" {
moreMissing := c.markMissingFromPrevious(ctx, dbConn, prevTableName, url, startTime, presentSnapshots, presentByUuid, presentByName, inventoryByVmID, inventoryByUuid, inventoryByName) moreMissing := c.markMissingFromPrevious(ctx, dbConn, prevTableName, url, startTime, presentSnapshots, presentByUuid, presentByName, inventoryByVmID, inventoryByUuid, inventoryByName)
missingCount += moreMissing missingCount += moreMissing
newCount = countNewFromPrevious(ctx, dbConn, prevTableName, url, presentSnapshots) // Guard against gaps: if previous snapshot is much older than expected, skip "new" detection to avoid false positives when an hourly run was missed.
if newCount > 0 { snapshotPeriod := durationFromSeconds(c.Settings.Values.Settings.VcenterInventorySnapshotSeconds, time.Hour).Seconds()
newRows := listNewFromPrevious(ctx, dbConn, prevTableName, url, presentSnapshots) if prevSnapshotTime > 0 && startTime.Unix()-prevSnapshotTime > int64(snapshotPeriod*2) {
names := make([]string, 0, len(newRows)) c.Logger.Info("skipping new-VM detection due to gap between snapshots", "prev_table", prevTableName, "prev_snapshot_unix", prevSnapshotTime, "current_snapshot_unix", startTime.Unix())
for _, r := range newRows { } else {
if r.Name != "" { newCount = countNewFromPrevious(ctx, dbConn, prevTableName, url, presentSnapshots)
names = append(names, r.Name) if newCount > 0 {
} else if r.VmId.Valid { newRows := listNewFromPrevious(ctx, dbConn, prevTableName, url, presentSnapshots)
names = append(names, r.VmId.String) names := make([]string, 0, len(newRows))
for _, r := range newRows {
if r.Name != "" {
names = append(names, r.Name)
} else if r.VmId.Valid {
names = append(names, r.VmId.String)
}
} }
c.Logger.Info("new VMs since previous snapshot", "prev_table", prevTableName, "count", newCount, "names", names)
} }
c.Logger.Info("new VMs since previous snapshot", "prev_table", prevTableName, "count", newCount, "names", names)
} }
c.Logger.Debug("compared with previous snapshot", "prev_table", prevTableName, "new_since_prev", newCount, "missing_since_prev", missingCount) c.Logger.Debug("compared with previous snapshot", "prev_table", prevTableName, "new_since_prev", newCount, "missing_since_prev", missingCount)
} else { } else {

View File

@@ -38,7 +38,7 @@ const fallbackEncryptionKey = "5L1l3B5KvwOCzUHMAlCgsgUTRAYMfSpa"
func main() { func main() {
settingsPath := flag.String("settings", "/etc/dtms/vctp.yml", "Path to settings YAML") settingsPath := flag.String("settings", "/etc/dtms/vctp.yml", "Path to settings YAML")
runInventoryOnce := flag.Bool("run-inventory", false, "Run a single inventory snapshot across all configured vCenters and exit") runInventory := flag.Bool("run-inventory", false, "Run a single inventory snapshot across all configured vCenters and exit")
flag.Parse() flag.Parse()
bootstrapLogger := log.New(log.LevelInfo, log.OutputText) bootstrapLogger := log.New(log.LevelInfo, log.OutputText)
@@ -59,6 +59,8 @@ func main() {
) )
s.Logger = logger s.Logger = logger
logger.Info("vCTP starting", "build_time", buildTime, "sha1_version", sha1ver, "go_version", runtime.Version(), "settings_file", *settingsPath)
// Configure database // Configure database
dbDriver := strings.TrimSpace(s.Values.Settings.DatabaseDriver) dbDriver := strings.TrimSpace(s.Values.Settings.DatabaseDriver)
if dbDriver == "" { if dbDriver == "" {
@@ -181,7 +183,7 @@ func main() {
} }
// One-shot mode: run a single inventory snapshot across all configured vCenters and exit. // One-shot mode: run a single inventory snapshot across all configured vCenters and exit.
if *runInventoryOnce { if *runInventory {
logger.Info("Running one-shot inventory snapshot across all vCenters") logger.Info("Running one-shot inventory snapshot across all vCenters")
ct.RunVcenterSnapshotHourly(ctx, logger) ct.RunVcenterSnapshotHourly(ctx, logger)
logger.Info("One-shot inventory snapshot complete; exiting") logger.Info("One-shot inventory snapshot complete; exiting")

View File

@@ -83,7 +83,8 @@ func (h *Handler) VmTrace(w http.ResponseWriter, r *http.Request) {
ts := time.Unix(lifecycle.CreationTime, 0).Local().Format("2006-01-02 15:04:05") ts := time.Unix(lifecycle.CreationTime, 0).Local().Format("2006-01-02 15:04:05")
if lifecycle.CreationApprox { if lifecycle.CreationApprox {
creationLabel = fmt.Sprintf("%s (approx. earliest snapshot)", ts) creationLabel = fmt.Sprintf("%s (approx. earliest snapshot)", ts)
creationApprox = true // dont double up on the approximate text
//creationApprox = true
} else { } else {
creationLabel = ts creationLabel = ts
} }