enhance deletiontime detection
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -498,12 +498,73 @@ GROUP BY
|
|||||||
agg."InventoryId", agg."Name", agg."Vcenter", agg."VmId", agg."EventKey", agg."CloudId",
|
agg."InventoryId", agg."Name", agg."Vcenter", agg."VmId", agg."EventKey", agg."CloudId",
|
||||||
agg."Datacenter", agg."Cluster", agg."Folder", agg."ProvisionedDisk", agg."VcpuCount",
|
agg."Datacenter", agg."Cluster", agg."Folder", agg."ProvisionedDisk", agg."VcpuCount",
|
||||||
agg."RamGB", agg."IsTemplate", agg."PoweredOn", agg."SrmPlaceholder", agg."VmUuid",
|
agg."RamGB", agg."IsTemplate", agg."PoweredOn", agg."SrmPlaceholder", agg."VmUuid",
|
||||||
agg.any_creation, agg.any_deletion, agg.first_present, agg.last_present,
|
agg.any_creation, agg.any_deletion, agg.first_present, agg.last_present,
|
||||||
totals.total_samples;
|
totals.total_samples;
|
||||||
`, unionQuery, tableName)
|
`, unionQuery, tableName)
|
||||||
return insert, nil
|
return insert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RefineCreationDeletionFromUnion walks all snapshot rows in a period and tightens CreationTime/DeletionTime
|
||||||
|
// by using the first and last observed samples and the first sample after disappearance.
|
||||||
|
func RefineCreationDeletionFromUnion(ctx context.Context, dbConn *sqlx.DB, summaryTable, unionQuery string) error {
|
||||||
|
if unionQuery == "" {
|
||||||
|
return fmt.Errorf("union query is empty")
|
||||||
|
}
|
||||||
|
if _, err := SafeTableName(summaryTable); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sql := fmt.Sprintf(`
|
||||||
|
WITH snapshots AS (
|
||||||
|
%s
|
||||||
|
), timeline AS (
|
||||||
|
SELECT
|
||||||
|
s."VmId",
|
||||||
|
s."VmUuid",
|
||||||
|
s."Name",
|
||||||
|
s."Vcenter",
|
||||||
|
MIN(NULLIF(s."CreationTime", 0)) AS any_creation,
|
||||||
|
MIN(s."SnapshotTime") AS first_seen,
|
||||||
|
MAX(s."SnapshotTime") AS last_seen
|
||||||
|
FROM snapshots s
|
||||||
|
GROUP BY s."VmId", s."VmUuid", s."Name", s."Vcenter"
|
||||||
|
)
|
||||||
|
UPDATE %s dst
|
||||||
|
SET
|
||||||
|
"CreationTime" = CASE
|
||||||
|
WHEN t.any_creation IS NOT NULL AND t.any_creation > 0 THEN LEAST(COALESCE(NULLIF(dst."CreationTime", 0), t.any_creation), t.any_creation)
|
||||||
|
WHEN t.first_seen IS NOT NULL THEN LEAST(COALESCE(NULLIF(dst."CreationTime", 0), t.first_seen), t.first_seen)
|
||||||
|
ELSE dst."CreationTime"
|
||||||
|
END,
|
||||||
|
"DeletionTime" = CASE
|
||||||
|
WHEN t_last_after IS NOT NULL
|
||||||
|
AND (dst."DeletionTime" IS NULL OR dst."DeletionTime" = 0 OR t_last_after < dst."DeletionTime")
|
||||||
|
THEN t_last_after
|
||||||
|
ELSE dst."DeletionTime"
|
||||||
|
END
|
||||||
|
FROM (
|
||||||
|
SELECT
|
||||||
|
tl.*,
|
||||||
|
(
|
||||||
|
SELECT MIN(s2."SnapshotTime")
|
||||||
|
FROM snapshots s2
|
||||||
|
WHERE s2."Vcenter" = tl."Vcenter"
|
||||||
|
AND COALESCE(s2."VmId", '') = COALESCE(tl."VmId", '')
|
||||||
|
AND s2."SnapshotTime" > tl.last_seen
|
||||||
|
) AS t_last_after
|
||||||
|
FROM timeline tl
|
||||||
|
) t
|
||||||
|
WHERE dst."Vcenter" = t."Vcenter"
|
||||||
|
AND (
|
||||||
|
(dst."VmId" IS NOT DISTINCT FROM t."VmId")
|
||||||
|
OR (dst."VmUuid" IS NOT DISTINCT FROM t."VmUuid")
|
||||||
|
OR (dst."Name" IS NOT DISTINCT FROM t."Name")
|
||||||
|
);
|
||||||
|
`, unionQuery, summaryTable)
|
||||||
|
|
||||||
|
_, err := dbConn.ExecContext(ctx, sql)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// BuildMonthlySummaryInsert returns the SQL to aggregate daily summaries into a monthly summary table.
|
// BuildMonthlySummaryInsert returns the SQL to aggregate daily summaries into a monthly summary table.
|
||||||
func BuildMonthlySummaryInsert(tableName string, unionQuery string) (string, error) {
|
func BuildMonthlySummaryInsert(tableName string, unionQuery string) (string, error) {
|
||||||
if _, err := SafeTableName(tableName); err != nil {
|
if _, err := SafeTableName(tableName); err != nil {
|
||||||
|
|||||||
@@ -129,6 +129,9 @@ func (c *CronTask) aggregateDailySummary(ctx context.Context, targetTime time.Ti
|
|||||||
c.Logger.Error("failed to aggregate daily inventory", "error", err, "date", dayStart.Format("2006-01-02"))
|
c.Logger.Error("failed to aggregate daily inventory", "error", err, "date", dayStart.Format("2006-01-02"))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := db.RefineCreationDeletionFromUnion(ctx, dbConn, summaryTable, unionQuery); err != nil {
|
||||||
|
c.Logger.Warn("failed to refine creation/deletion times", "error", err, "table", summaryTable)
|
||||||
|
}
|
||||||
rowCount, err := db.TableRowCount(ctx, dbConn, summaryTable)
|
rowCount, err := db.TableRowCount(ctx, dbConn, summaryTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger.Warn("unable to count daily summary rows", "error", err, "table", summaryTable)
|
c.Logger.Warn("unable to count daily summary rows", "error", err, "table", summaryTable)
|
||||||
|
|||||||
Reference in New Issue
Block a user