mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-10-31 14:18:56 -04:00 
			
		
		
		
	wip
This commit is contained in:
		
							parent
							
								
									344fd52501
								
							
						
					
					
						commit
						d7c3c40d74
					
				
					 2 changed files with 75 additions and 47 deletions
				
			
		|  | @ -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 | ||||||
|         `);
 |         `);
 | ||||||
| 
 | 
 | ||||||
|         // 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" ]) { |  | ||||||
|             let countResult = await trx.raw(`SELECT COUNT(*) AS count FROM ${table}`); |  | ||||||
|             let count = countResult[0].count; |  | ||||||
|             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?)`); |  | ||||||
|                 trx.rollback(); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         console.log("Dates", dates); |         console.log("Dates", dates); | ||||||
|         console.log("Monitors", monitors); |         console.log("Monitors", monitors); | ||||||
| 
 | 
 | ||||||
|  |         // Stop if stat_* tables are not empty
 | ||||||
|  |         for (let table of [ "stat_minutely", "stat_hourly", "stat_daily" ]) { | ||||||
|  |             let countResult = await R.getRow(`SELECT COUNT(*) AS count FROM ${table}`); | ||||||
|  |             let count = countResult.count; | ||||||
|  |             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?)`); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Louis Lam
						Louis Lam