2.0-last-part
Louis Lam 2 months ago
parent 344fd52501
commit d7c3c40d74

@ -741,6 +741,14 @@ class Database {
await Settings.set("migratedAggregateTable", true); await Settings.set("migratedAggregateTable", true);
} }
// Empty the aggregate table if FORCE_MIGRATE_AGGREGATE_TABLE is set to 1
if (process.env.FORCE_MIGRATE_AGGREGATE_TABLE === "1") {
log.warn("db", "FORCE_MIGRATE_AGGREGATE_TABLE is set to 1, forcing aggregate table migration");
await R.exec("DELETE FROM stat_minutely");
await R.exec("DELETE FROM stat_hourly");
await R.exec("DELETE FROM stat_daily");
}
// //
let migrated = await Settings.get("migratedAggregateTable"); let migrated = await Settings.get("migratedAggregateTable");
@ -751,61 +759,62 @@ class Database {
log.info("db", "Migrating Aggregate Table"); log.info("db", "Migrating Aggregate Table");
// Migrate heartbeat to stat_minutely, using knex transaction log.info("db", "Getting list of unique dates and monitors");
const trx = await R.knex.transaction();
// Get a list of unique dates from the heartbeat table, using raw sql // Get a list of unique dates from the heartbeat table, using raw sql
let dates = await trx.raw(` let dates = await R.getAll(`
SELECT DISTINCT DATE(time) AS date SELECT DISTINCT DATE(time) AS date
FROM heartbeat FROM heartbeat
ORDER BY date ASC ORDER BY date ASC
`); `);
// Get a list of unique monitors from the heartbeat table, using raw sql // Get a list of unique monitors from the heartbeat table, using raw sql
let monitors = await trx.raw(` let monitors = await R.getAll(`
SELECT DISTINCT monitor_id SELECT DISTINCT monitor_id
FROM heartbeat FROM heartbeat
ORDER BY monitor_id ASC
`); `);
console.log("Dates", dates);
console.log("Monitors", monitors);
// Stop if stat_* tables are not empty // Stop if stat_* tables are not empty
// SQL to empty these tables: DELETE FROM stat_minutely; DELETE FROM stat_hourly; DELETE FROM stat_daily;
for (let table of [ "stat_minutely", "stat_hourly", "stat_daily" ]) { for (let table of [ "stat_minutely", "stat_hourly", "stat_daily" ]) {
let countResult = await trx.raw(`SELECT COUNT(*) AS count FROM ${table}`); let countResult = await R.getRow(`SELECT COUNT(*) AS count FROM ${table}`);
let count = countResult[0].count; let count = countResult.count;
if (count > 0) { if (count > 0) {
log.warn("db", `Aggregate table ${table} is not empty, migration will not be started (Maybe you were using 2.0.0-dev?)`); log.warn("db", `Aggregate table ${table} is not empty, migration will not be started (Maybe you were using 2.0.0-dev?)`);
trx.rollback();
return; return;
} }
} }
console.log("Dates", dates);
console.log("Monitors", monitors);
for (let monitor of monitors) { for (let monitor of monitors) {
for (let date of dates) { for (let date of dates) {
log.info("db", `Migrating monitor ${monitor.monitor_id} on date ${date.date}`);
// New Uptime Calculator // New Uptime Calculator
let calculator = new UptimeCalculator(); let calculator = new UptimeCalculator();
calculator.monitorID = monitor.monitor_id;
// TODO: Pass transaction to the calculator calculator.setMigrationMode(true);
// calculator.setTransaction(trx);
// Get all the heartbeats for this monitor and date // Get all the heartbeats for this monitor and date
let heartbeats = await trx("heartbeat") let heartbeats = await R.getAll(`
.where("monitor_id", monitor.monitor_id) SELECT status, ping, time
.whereRaw("DATE(time) = ?", [ date.date ]) FROM heartbeat
.orderBy("time", "asc"); WHERE monitor_id = ?
AND DATE(time) = ?
ORDER BY time ASC
`, [ monitor.monitor_id, date.date ]);
if (heartbeats.length > 0) {
log.info("db", `Migrating monitor ${monitor.monitor_id} on date ${date.date}`);
}
for (let heartbeat of heartbeats) { for (let heartbeat of heartbeats) {
calculator.update(heartbeat.status, heartbeat.ping, dayjs(heartbeat.time)); await calculator.update(heartbeat.status, parseFloat(heartbeat.ping), dayjs(heartbeat.time));
} }
} }
} }
trx.commit();
//await Settings.set("migratedAggregateTable", true); //await Settings.set("migratedAggregateTable", true);
} }

@ -12,7 +12,6 @@ class UptimeCalculator {
* @private * @private
* @type {{string:UptimeCalculator}} * @type {{string:UptimeCalculator}}
*/ */
static list = {}; static list = {};
/** /**
@ -55,6 +54,12 @@ class UptimeCalculator {
lastHourlyStatBean = null; lastHourlyStatBean = null;
lastMinutelyStatBean = null; lastMinutelyStatBean = null;
/**
* For migration purposes.
* @type {boolean}
*/
migrationMode = false;
/** /**
* Get the uptime calculator for a monitor * Get the uptime calculator for a monitor
* Initializes and returns the monitor if it does not exist * Initializes and returns the monitor if it does not exist
@ -194,6 +199,10 @@ class UptimeCalculator {
* @throws {Error} Invalid status * @throws {Error} Invalid status
*/ */
async update(status, ping = 0, date) { async update(status, ping = 0, date) {
if (!this.monitorID) {
throw new Error("Monitor ID is required");
}
if (!date) { if (!date) {
date = this.getCurrentDate(); date = this.getCurrentDate();
} }
@ -330,6 +339,7 @@ class UptimeCalculator {
} }
await R.store(minutelyStatBean); await R.store(minutelyStatBean);
if (!this.migrationMode) {
// Remove the old data // Remove the old data
log.debug("uptime-calc", "Remove old data"); log.debug("uptime-calc", "Remove old data");
await R.exec("DELETE FROM stat_minutely WHERE monitor_id = ? AND timestamp < ?", [ await R.exec("DELETE FROM stat_minutely WHERE monitor_id = ? AND timestamp < ?", [
@ -341,6 +351,7 @@ class UptimeCalculator {
this.monitorID, this.monitorID,
this.getHourlyKey(date.subtract(30, "day")), this.getHourlyKey(date.subtract(30, "day")),
]); ]);
}
return date; return date;
} }
@ -815,6 +826,14 @@ class UptimeCalculator {
return dayjs.utc(); return dayjs.utc();
} }
/**
* For migration purposes.
* @param {boolean} value Migration mode on/off
* @returns {void}
*/
setMigrationMode(value) {
this.migrationMode = value;
}
} }
class UptimeDataResult { class UptimeDataResult {

Loading…
Cancel
Save