@ -409,60 +409,51 @@ class Monitor extends BeanModel {
static async sendUptime ( duration , io , monitorID , userID ) {
const timeLogger = new TimeLogger ( ) ;
let sec = duration * 3600 ;
const startTime = R . isoDateTime ( dayjs . utc ( ) . subtract ( duration , "hour" ) ) ;
let heartbeatList = await R . getAll ( `
SELECT duration , time , status
// Handle if heartbeat duration longer than the target duration
// 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
WHERE time > DATETIME ( 'now' , ? || ' hours' )
AND monitor _id = ? ` , [
- duration ,
WHERE time > ?
AND monitor _id = ?
` , [
startTime , startTime , startTime , startTime , startTime ,
monitorID ,
] ) ;
timeLogger . print ( ` [Monitor: ${ monitorID } ][ ${ duration } ] sendUptime ` ) ;
let downtime = 0 ;
let total = 0 ;
let uptime ;
// Special handle for the first heartbeat only
if ( heartbeatList . length === 1 ) {
if ( heartbeatList [ 0 ] . status === 1 ) {
uptime = 1 ;
} 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 ;
}
}
let totalDuration = result . total _duration ;
let uptimeDuration = result . uptime _duration ;
total += value ;
if ( row . status === 0 || row . status === 2 ) {
downtime += value ;
}
}
uptime = ( total - downtime ) / total ;
let uptime = uptimeDuration / totalDuration ;
if ( uptime < 0 ) {
uptime = 0 ;
}
}
io . to ( userID ) . emit ( "uptime" , monitorID , duration , uptime ) ;
}