even more diagnostics
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Nathan Coad
2026-01-27 11:21:47 +11:00
parent fe96172253
commit 6981bd9994
6 changed files with 103 additions and 0 deletions

View File

@@ -155,6 +155,11 @@ func (c *CronTask) aggregateDailySummary(ctx context.Context, targetTime time.Ti
} else {
c.Logger.Info("Daily aggregation deletion times", "source_lifecycle_cache", applied)
}
if applied, err := db.ApplyLifecycleCreationToSummary(ctx, dbConn, summaryTable); err != nil {
c.Logger.Warn("failed to apply lifecycle creations to daily summary", "error", err, "table", summaryTable)
} else if applied > 0 {
c.Logger.Info("Daily aggregation creation times", "source_lifecycle_cache", applied)
}
if err := db.RefineCreationDeletionFromUnion(ctx, dbConn, summaryTable, unionQuery); err != nil {
c.Logger.Warn("failed to refine creation/deletion times", "error", err, "table", summaryTable)
}
@@ -406,6 +411,11 @@ LIMIT 1
} else {
c.Logger.Debug("refined creation/deletion times", "table", summaryTable)
}
if applied, err := db.ApplyLifecycleCreationToSummary(ctx, dbConn, summaryTable); err != nil {
c.Logger.Warn("failed to apply lifecycle creations to daily summary (Go path)", "error", err, "table", summaryTable)
} else if applied > 0 {
c.Logger.Info("Daily aggregation creation times (Go path)", "source_lifecycle_cache", applied)
}
if err := db.UpdateSummaryPresenceByWindow(ctx, dbConn, summaryTable, dayStart.Unix(), dayEnd.Unix()); err != nil {
c.Logger.Warn("failed to update daily AvgIsPresent from lifecycle window (Go path)", "error", err, "table", summaryTable)
}

View File

@@ -171,6 +171,11 @@ func (c *CronTask) aggregateMonthlySummary(ctx context.Context, targetMonth time
} else {
c.Logger.Info("Monthly aggregation deletion times", "source_lifecycle_cache", applied)
}
if applied, err := db.ApplyLifecycleCreationToSummary(ctx, dbConn, monthlyTable); err != nil {
c.Logger.Warn("failed to apply lifecycle creations to monthly summary", "error", err, "table", monthlyTable)
} else if applied > 0 {
c.Logger.Info("Monthly aggregation creation times", "source_lifecycle_cache", applied)
}
if err := db.UpdateSummaryPresenceByWindow(ctx, dbConn, monthlyTable, monthStart.Unix(), monthEnd.Unix()); err != nil {
c.Logger.Warn("failed to update monthly AvgIsPresent from lifecycle window", "error", err, "table", monthlyTable)
}
@@ -293,6 +298,11 @@ func (c *CronTask) aggregateMonthlySummaryGoHourly(ctx context.Context, monthSta
if err := c.insertDailyAggregates(ctx, summaryTable, aggMap, totalSamples, totalSamplesByVcenter); err != nil {
return err
}
if applied, err := db.ApplyLifecycleCreationToSummary(ctx, dbConn, summaryTable); err != nil {
c.Logger.Warn("failed to apply lifecycle creations to monthly summary (Go hourly)", "error", err, "table", summaryTable)
} else if applied > 0 {
c.Logger.Info("Monthly aggregation creation times (Go hourly)", "source_lifecycle_cache", applied)
}
if err := db.UpdateSummaryPresenceByWindow(ctx, dbConn, summaryTable, monthStart.Unix(), monthEnd.Unix()); err != nil {
c.Logger.Warn("failed to update monthly AvgIsPresent from lifecycle window (Go hourly)", "error", err, "table", summaryTable)
}
@@ -365,6 +375,11 @@ func (c *CronTask) aggregateMonthlySummaryGo(ctx context.Context, monthStart, mo
} else {
c.Logger.Info("Monthly aggregation deletion times", "source_lifecycle_cache", applied)
}
if applied, err := db.ApplyLifecycleCreationToSummary(ctx, dbConn, summaryTable); err != nil {
c.Logger.Warn("failed to apply lifecycle creations to monthly summary (Go)", "error", err, "table", summaryTable)
} else if applied > 0 {
c.Logger.Info("Monthly aggregation creation times (Go)", "source_lifecycle_cache", applied)
}
if err := db.RefineCreationDeletionFromUnion(ctx, dbConn, summaryTable, unionQuery); err != nil {
c.Logger.Warn("failed to refine creation/deletion times (monthly Go)", "error", err, "table", summaryTable)

View File

@@ -68,6 +68,22 @@ func (h *Handler) DailyCreationDiagnostics(w http.ResponseWriter, r *http.Reques
return
}
var avgIsPresentLtOne int64
avgPresenceQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s WHERE "AvgIsPresent" IS NOT NULL AND "AvgIsPresent" < 0.999999`, tableName)
if err := dbConn.GetContext(ctx, &avgIsPresentLtOne, avgPresenceQuery); err != nil {
h.Logger.Warn("daily creation diagnostics avg-is-present count failed", "table", tableName, "error", err)
writeJSONError(w, http.StatusInternalServerError, "failed to read avg is present rows")
return
}
var missingPartialCount int64
missingPartialQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s WHERE ("CreationTime" IS NULL OR "CreationTime" = 0) AND "AvgIsPresent" IS NOT NULL AND "AvgIsPresent" < 0.999999`, tableName)
if err := dbConn.GetContext(ctx, &missingPartialCount, missingPartialQuery); err != nil {
h.Logger.Warn("daily creation diagnostics missing partial count failed", "table", tableName, "error", err)
writeJSONError(w, http.StatusInternalServerError, "failed to read missing partial rows")
return
}
missingPct := 0.0
if totalRows > 0 {
missingPct = float64(missingTotal) * 100 / float64(totalRows)
@@ -133,6 +149,42 @@ LIMIT %d
rows.Close()
}
partialSamples := make([]models.DailyCreationMissingSample, 0, sampleLimit)
partialSampleQuery := fmt.Sprintf(`
SELECT "Vcenter","VmId","VmUuid","Name","SamplesPresent","AvgIsPresent","SnapshotTime"
FROM %s
WHERE ("CreationTime" IS NULL OR "CreationTime" = 0)
AND "AvgIsPresent" IS NOT NULL
AND "AvgIsPresent" < 0.999999
ORDER BY "SamplesPresent" DESC
LIMIT %d
`, tableName, sampleLimit)
if rows, err := dbConn.QueryxContext(ctx, partialSampleQuery); err != nil {
h.Logger.Warn("daily creation diagnostics partial sample failed", "table", tableName, "error", err)
} else {
for rows.Next() {
var (
vcenter string
vmId, vmUuid, name sql.NullString
samplesPresent, snapshotTime sql.NullInt64
avgIsPresent sql.NullFloat64
)
if err := rows.Scan(&vcenter, &vmId, &vmUuid, &name, &samplesPresent, &avgIsPresent, &snapshotTime); err != nil {
continue
}
partialSamples = append(partialSamples, models.DailyCreationMissingSample{
Vcenter: vcenter,
VmId: vmId.String,
VmUuid: vmUuid.String,
Name: name.String,
SamplesPresent: samplesPresent.Int64,
AvgIsPresent: avgIsPresent.Float64,
SnapshotTime: snapshotTime.Int64,
})
}
rows.Close()
}
response := models.DailyCreationDiagnosticsResponse{
Status: "OK",
Date: parsed.Format("2006-01-02"),
@@ -140,8 +192,11 @@ LIMIT %d
TotalRows: totalRows,
MissingCreationCount: missingTotal,
MissingCreationPct: missingPct,
AvgIsPresentLtOneCount: avgIsPresentLtOne,
MissingCreationPartialCount: missingPartialCount,
MissingByVcenter: byVcenter,
Samples: samples,
MissingCreationPartialSamples: partialSamples,
}
w.Header().Set("Content-Type", "application/json")

View File

@@ -25,6 +25,9 @@ type DailyCreationDiagnosticsResponse struct {
TotalRows int64 `json:"total_rows"`
MissingCreationCount int64 `json:"missing_creation_count"`
MissingCreationPct float64 `json:"missing_creation_pct"`
AvgIsPresentLtOneCount int64 `json:"avg_is_present_lt_one_count"`
MissingCreationPartialCount int64 `json:"missing_creation_partial_count"`
MissingByVcenter []DailyCreationMissingByVcenter `json:"missing_by_vcenter"`
Samples []DailyCreationMissingSample `json:"samples"`
MissingCreationPartialSamples []DailyCreationMissingSample `json:"missing_creation_partial_samples"`
}

View File

@@ -1356,6 +1356,12 @@
"missing_creation_pct": {
"type": "number"
},
"avg_is_present_lt_one_count": {
"type": "integer"
},
"missing_creation_partial_count": {
"type": "integer"
},
"missing_by_vcenter": {
"type": "array",
"items": {
@@ -1367,6 +1373,12 @@
"items": {
"$ref": "#/definitions/models.DailyCreationMissingSample"
}
},
"missing_creation_partial_samples": {
"type": "array",
"items": {
"$ref": "#/definitions/models.DailyCreationMissingSample"
}
}
}
},

View File

@@ -247,6 +247,10 @@ definitions:
type: integer
missing_creation_pct:
type: number
avg_is_present_lt_one_count:
type: integer
missing_creation_partial_count:
type: integer
missing_by_vcenter:
items:
$ref: '#/definitions/models.DailyCreationMissingByVcenter'
@@ -255,6 +259,10 @@ definitions:
items:
$ref: '#/definitions/models.DailyCreationMissingSample'
type: array
missing_creation_partial_samples:
items:
$ref: '#/definitions/models.DailyCreationMissingSample'
type: array
type: object
models.DailyCreationMissingByVcenter:
properties: