uptime calculation fully sum in sql
This commit is contained in:
		
							parent
							
								
									0b1d0d22ff
								
							
						
					
					
						commit
						4f07c2ea9a
					
				
					 1 changed files with 35 additions and 44 deletions
				
			
		| 
						 | 
					@ -409,59 +409,50 @@ class Monitor extends BeanModel {
 | 
				
			||||||
    static async sendUptime(duration, io, monitorID, userID) {
 | 
					    static async sendUptime(duration, io, monitorID, userID) {
 | 
				
			||||||
        const timeLogger = new TimeLogger();
 | 
					        const timeLogger = new TimeLogger();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let sec = duration * 3600;
 | 
					        const startTime = R.isoDateTime(dayjs.utc().subtract(duration, "hour"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let heartbeatList = await R.getAll(`
 | 
					        // Handle if heartbeat duration longer than the target duration
 | 
				
			||||||
            SELECT duration, time, status
 | 
					        // e.g. If the last beat's duration is bigger that the 24hrs window, it will use the duration between the (beat time - window margin) (THEN case in SQL)
 | 
				
			||||||
 | 
					        let result = await R.getRow(`
 | 
				
			||||||
 | 
					            SELECT
 | 
				
			||||||
 | 
					               -- SUM all duration, also trim off the beat out of time window
 | 
				
			||||||
 | 
					                SUM(
 | 
				
			||||||
 | 
					                    CASE
 | 
				
			||||||
 | 
					                        WHEN (JULIANDAY(\`time\`) - JULIANDAY(?)) * 86400 < duration
 | 
				
			||||||
 | 
					                        THEN (JULIANDAY(\`time\`) - JULIANDAY(?)) * 86400
 | 
				
			||||||
 | 
					                        ELSE duration
 | 
				
			||||||
 | 
					                    END
 | 
				
			||||||
 | 
					                ) AS total_duration,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					               -- SUM all uptime duration, also trim off the beat out of time window
 | 
				
			||||||
 | 
					                SUM(
 | 
				
			||||||
 | 
					                    CASE
 | 
				
			||||||
 | 
					                        WHEN (status = 1)
 | 
				
			||||||
 | 
					                        THEN
 | 
				
			||||||
 | 
					                            CASE
 | 
				
			||||||
 | 
					                                WHEN (JULIANDAY(\`time\`) - JULIANDAY(?)) * 86400 < duration
 | 
				
			||||||
 | 
					                                    THEN (JULIANDAY(\`time\`) - JULIANDAY(?)) * 86400
 | 
				
			||||||
 | 
					                                ELSE duration
 | 
				
			||||||
 | 
					                            END
 | 
				
			||||||
 | 
					                        END
 | 
				
			||||||
 | 
					                ) AS uptime_duration
 | 
				
			||||||
            FROM heartbeat
 | 
					            FROM heartbeat
 | 
				
			||||||
            WHERE time > DATETIME('now', ? || ' hours')
 | 
					            WHERE time > ?
 | 
				
			||||||
            AND monitor_id = ? `, [
 | 
					            AND monitor_id = ?
 | 
				
			||||||
            -duration,
 | 
					        `, [
 | 
				
			||||||
 | 
					            startTime, startTime, startTime, startTime, startTime,
 | 
				
			||||||
            monitorID,
 | 
					            monitorID,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        timeLogger.print(`[Monitor: ${monitorID}][${duration}] sendUptime`);
 | 
					        timeLogger.print(`[Monitor: ${monitorID}][${duration}] sendUptime`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let downtime = 0;
 | 
					        let totalDuration = result.total_duration;
 | 
				
			||||||
        let total = 0;
 | 
					        let uptimeDuration = result.uptime_duration;
 | 
				
			||||||
        let uptime;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Special handle for the first heartbeat only
 | 
					        let uptime = uptimeDuration / totalDuration;
 | 
				
			||||||
        if (heartbeatList.length === 1) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (heartbeatList[0].status === 1) {
 | 
					        if (uptime < 0) {
 | 
				
			||||||
                uptime = 1;
 | 
					            uptime = 0;
 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                uptime = 0;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            for (let row of heartbeatList) {
 | 
					 | 
				
			||||||
                let value = parseInt(row.duration)
 | 
					 | 
				
			||||||
                let time = row.time
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Handle if heartbeat duration longer than the target duration
 | 
					 | 
				
			||||||
                // e.g.   Heartbeat duration = 28hrs, but target duration = 24hrs
 | 
					 | 
				
			||||||
                if (value > sec) {
 | 
					 | 
				
			||||||
                    let trim = dayjs.utc().diff(dayjs(time), "second");
 | 
					 | 
				
			||||||
                    value = sec - trim;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (value < 0) {
 | 
					 | 
				
			||||||
                        value = 0;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                total += value;
 | 
					 | 
				
			||||||
                if (row.status === 0 || row.status === 2) {
 | 
					 | 
				
			||||||
                    downtime += value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            uptime = (total - downtime) / total;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (uptime < 0) {
 | 
					 | 
				
			||||||
                uptime = 0;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        io.to(userID).emit("uptime", monitorID, duration, uptime);
 | 
					        io.to(userID).emit("uptime", monitorID, duration, uptime);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue