@ -1,16 +1,16 @@
const https = require ( "https" ) ;
const https = require ( "https" ) ;
const dayjs = require ( "dayjs" ) ;
const dayjs = require ( "dayjs" ) ;
const utc = require ( "dayjs/plugin/utc" )
const utc = require ( "dayjs/plugin/utc" ) ;
let timezone = require ( "dayjs/plugin/timezone" )
let timezone = require ( "dayjs/plugin/timezone" ) ;
dayjs . extend ( utc )
dayjs . extend ( utc ) ;
dayjs . extend ( timezone )
dayjs . extend ( timezone ) ;
const axios = require ( "axios" ) ;
const axios = require ( "axios" ) ;
const { Prometheus } = require ( "../prometheus" ) ;
const { Prometheus } = require ( "../prometheus" ) ;
const { debug , UP , DOWN , PENDING , flipStatus , TimeLogger } = require ( "../../src/util" ) ;
const { debug , UP , DOWN , PENDING , flipStatus , TimeLogger } = require ( "../../src/util" ) ;
const { tcping , ping , dnsResolve , checkCertificate , checkStatusCode , getTotalClientInRoom } = require ( "../util-server" ) ;
const { tcping , ping , dnsResolve , checkCertificate , checkStatusCode , getTotalClientInRoom } = require ( "../util-server" ) ;
const { R } = require ( "redbean-node" ) ;
const { R } = require ( "redbean-node" ) ;
const { BeanModel } = require ( "redbean-node/dist/bean-model" ) ;
const { BeanModel } = require ( "redbean-node/dist/bean-model" ) ;
const { Notification } = require ( "../notification" )
const { Notification } = require ( "../notification" ) ;
const version = require ( "../../package.json" ) . version ;
const version = require ( "../../package.json" ) . version ;
/ * *
/ * *
@ -39,7 +39,7 @@ class Monitor extends BeanModel {
let list = await R . find ( "monitor_notification" , " monitor_id = ? " , [
let list = await R . find ( "monitor_notification" , " monitor_id = ? " , [
this . id ,
this . id ,
] )
] ) ;
for ( let bean of list ) {
for ( let bean of list ) {
notificationIDList [ bean . notification _id ] = true ;
notificationIDList [ bean . notification _id ] = true ;
@ -77,7 +77,7 @@ class Monitor extends BeanModel {
* @ returns { boolean }
* @ returns { boolean }
* /
* /
getIgnoreTls ( ) {
getIgnoreTls ( ) {
return Boolean ( this . ignoreTls )
return Boolean ( this . ignoreTls ) ;
}
}
/ * *
/ * *
@ -107,12 +107,12 @@ class Monitor extends BeanModel {
if ( ! previousBeat ) {
if ( ! previousBeat ) {
previousBeat = await R . findOne ( "heartbeat" , " monitor_id = ? ORDER BY time DESC" , [
previousBeat = await R . findOne ( "heartbeat" , " monitor_id = ? ORDER BY time DESC" , [
this . id ,
this . id ,
] )
] ) ;
}
}
const isFirstBeat = ! previousBeat ;
const isFirstBeat = ! previousBeat ;
let bean = R . dispense ( "heartbeat" )
let bean = R . dispense ( "heartbeat" ) ;
bean . monitor _id = this . id ;
bean . monitor _id = this . id ;
bean . time = R . isoDateTime ( dayjs . utc ( ) ) ;
bean . time = R . isoDateTime ( dayjs . utc ( ) ) ;
bean . status = DOWN ;
bean . status = DOWN ;
@ -148,7 +148,7 @@ class Monitor extends BeanModel {
return checkStatusCode ( status , this . getAcceptedStatuscodes ( ) ) ;
return checkStatusCode ( status , this . getAcceptedStatuscodes ( ) ) ;
} ,
} ,
} ) ;
} ) ;
bean . msg = ` ${ res . status } - ${ res . statusText } `
bean . msg = ` ${ res . status } - ${ res . statusText } ` ;
bean . ping = dayjs ( ) . valueOf ( ) - startTime ;
bean . ping = dayjs ( ) . valueOf ( ) - startTime ;
// Check certificate if https is used
// Check certificate if https is used
@ -158,12 +158,12 @@ class Monitor extends BeanModel {
tlsInfo = await this . updateTlsInfo ( checkCertificate ( res ) ) ;
tlsInfo = await this . updateTlsInfo ( checkCertificate ( res ) ) ;
} catch ( e ) {
} catch ( e ) {
if ( e . message !== "No TLS certificate in response" ) {
if ( e . message !== "No TLS certificate in response" ) {
console . error ( e . message )
console . error ( e . message ) ;
}
}
}
}
}
}
debug ( "Cert Info Query Time: " + ( dayjs ( ) . valueOf ( ) - certInfoStartTime ) + "ms" )
debug ( "Cert Info Query Time: " + ( dayjs ( ) . valueOf ( ) - certInfoStartTime ) + "ms" ) ;
if ( this . type === "http" ) {
if ( this . type === "http" ) {
bean . status = UP ;
bean . status = UP ;
@ -173,26 +173,26 @@ class Monitor extends BeanModel {
// Convert to string for object/array
// Convert to string for object/array
if ( typeof data !== "string" ) {
if ( typeof data !== "string" ) {
data = JSON . stringify ( data )
data = JSON . stringify ( data ) ;
}
}
if ( data . includes ( this . keyword ) ) {
if ( data . includes ( this . keyword ) ) {
bean . msg += ", keyword is found"
bean . msg += ", keyword is found" ;
bean . status = UP ;
bean . status = UP ;
} else {
} else {
throw new Error ( bean . msg + ", but keyword is not found" )
throw new Error ( bean . msg + ", but keyword is not found" ) ;
}
}
}
}
} else if ( this . type === "port" ) {
} else if ( this . type === "port" ) {
bean . ping = await tcping ( this . hostname , this . port ) ;
bean . ping = await tcping ( this . hostname , this . port ) ;
bean . msg = ""
bean . msg = "" ;
bean . status = UP ;
bean . status = UP ;
} else if ( this . type === "ping" ) {
} else if ( this . type === "ping" ) {
bean . ping = await ping ( this . hostname ) ;
bean . ping = await ping ( this . hostname ) ;
bean . msg = ""
bean . msg = "" ;
bean . status = UP ;
bean . status = UP ;
} else if ( this . type === "dns" ) {
} else if ( this . type === "dns" ) {
let startTime = dayjs ( ) . valueOf ( ) ;
let startTime = dayjs ( ) . valueOf ( ) ;
@ -212,7 +212,7 @@ class Monitor extends BeanModel {
dnsRes . forEach ( record => {
dnsRes . forEach ( record => {
dnsMessage += ` Hostname: ${ record . exchange } - Priority: ${ record . priority } | ` ;
dnsMessage += ` Hostname: ${ record . exchange } - Priority: ${ record . priority } | ` ;
} ) ;
} ) ;
dnsMessage = dnsMessage . slice ( 0 , - 2 )
dnsMessage = dnsMessage . slice ( 0 , - 2 ) ;
} else if ( this . dns _resolve _type == "NS" ) {
} else if ( this . dns _resolve _type == "NS" ) {
dnsMessage += "Servers: " ;
dnsMessage += "Servers: " ;
dnsMessage += dnsRes . join ( " | " ) ;
dnsMessage += dnsRes . join ( " | " ) ;
@ -222,7 +222,7 @@ class Monitor extends BeanModel {
dnsRes . forEach ( record => {
dnsRes . forEach ( record => {
dnsMessage += ` Name: ${ record . name } | Port: ${ record . port } | Priority: ${ record . priority } | Weight: ${ record . weight } | ` ;
dnsMessage += ` Name: ${ record . name } | Port: ${ record . port } | Priority: ${ record . priority } | Weight: ${ record . weight } | ` ;
} ) ;
} ) ;
dnsMessage = dnsMessage . slice ( 0 , - 2 )
dnsMessage = dnsMessage . slice ( 0 , - 2 ) ;
}
}
if ( this . dnsLastResult !== dnsMessage ) {
if ( this . dnsLastResult !== dnsMessage ) {
@ -285,20 +285,20 @@ class Monitor extends BeanModel {
if ( ! isFirstBeat || bean . status === DOWN ) {
if ( ! isFirstBeat || bean . status === DOWN ) {
let notificationList = await R . getAll ( "SELECT notification.* FROM notification, monitor_notification WHERE monitor_id = ? AND monitor_notification.notification_id = notification.id " , [
let notificationList = await R . getAll ( "SELECT notification.* FROM notification, monitor_notification WHERE monitor_id = ? AND monitor_notification.notification_id = notification.id " , [
this . id ,
this . id ,
] )
] ) ;
let text ;
let text ;
if ( bean . status === UP ) {
if ( bean . status === UP ) {
text = "✅ Up"
text = "✅ Up" ;
} else {
} else {
text = "🔴 Down"
text = "🔴 Down" ;
}
}
let msg = ` [ ${ this . name } ] [ ${ text } ] ${ bean . msg } ` ;
let msg = ` [ ${ this . name } ] [ ${ text } ] ${ bean . msg } ` ;
for ( let notification of notificationList ) {
for ( let notification of notificationList ) {
try {
try {
await Notification . send ( JSON . parse ( notification . config ) , msg , await this . toJSON ( ) , bean . toJSON ( ) )
await Notification . send ( JSON . parse ( notification . config ) , msg , await this . toJSON ( ) , bean . toJSON ( ) ) ;
} catch ( e ) {
} catch ( e ) {
console . error ( "Cannot send notification to " + notification . name ) ;
console . error ( "Cannot send notification to " + notification . name ) ;
console . log ( e ) ;
console . log ( e ) ;
@ -313,18 +313,18 @@ class Monitor extends BeanModel {
let beatInterval = this . interval ;
let beatInterval = this . interval ;
if ( bean . status === UP ) {
if ( bean . status === UP ) {
console . info ( ` Monitor # ${ this . id } ' ${ this . name } ': Successful Response: ${ bean . ping } ms | Interval: ${ beatInterval } seconds | Type: ${ this . type } ` )
console . info ( ` Monitor # ${ this . id } ' ${ this . name } ': Successful Response: ${ bean . ping } ms | Interval: ${ beatInterval } seconds | Type: ${ this . type } ` ) ;
} else if ( bean . status === PENDING ) {
} else if ( bean . status === PENDING ) {
if ( this . retryInterval !== this . interval ) {
if ( this . retryInterval !== this . interval ) {
beatInterval = this . retryInterval ;
beatInterval = this . retryInterval ;
}
}
console . warn ( ` Monitor # ${ this . id } ' ${ this . name } ': Pending: ${ bean . msg } | Max retries: ${ this . maxretries } | Retry: ${ retries } | Retry Interval: ${ beatInterval } seconds | Type: ${ this . type } ` )
console . warn ( ` Monitor # ${ this . id } ' ${ this . name } ': Pending: ${ bean . msg } | Max retries: ${ this . maxretries } | Retry: ${ retries } | Retry Interval: ${ beatInterval } seconds | Type: ${ this . type } ` ) ;
} else {
} else {
console . warn ( ` Monitor # ${ this . id } ' ${ this . name } ': Failing: ${ bean . msg } | Interval: ${ beatInterval } seconds | Type: ${ this . type } ` )
console . warn ( ` Monitor # ${ this . id } ' ${ this . name } ': Failing: ${ bean . msg } | Interval: ${ beatInterval } seconds | Type: ${ this . type } ` ) ;
}
}
io . to ( this . user _id ) . emit ( "heartbeat" , bean . toJSON ( ) ) ;
io . to ( this . user _id ) . emit ( "heartbeat" , bean . toJSON ( ) ) ;
Monitor . sendStats ( io , this . id , this . user _id )
Monitor . sendStats ( io , this . id , this . user _id ) ;
await R . store ( bean ) ;
await R . store ( bean ) ;
prometheus . update ( bean , tlsInfo ) ;
prometheus . update ( bean , tlsInfo ) ;
@ -335,7 +335,7 @@ class Monitor extends BeanModel {
this . heartbeatInterval = setTimeout ( beat , beatInterval * 1000 ) ;
this . heartbeatInterval = setTimeout ( beat , beatInterval * 1000 ) ;
}
}
}
} ;
beat ( ) ;
beat ( ) ;
}
}
@ -481,7 +481,7 @@ class Monitor extends BeanModel {
} else {
} else {
// Handle new monitor with only one beat, because the beat's duration = 0
// Handle new monitor with only one beat, because the beat's duration = 0
let status = parseInt ( await R . getCell ( "SELECT `status` FROM heartbeat WHERE monitor_id = ?" , [ monitorID ] ) ) ;
let status = parseInt ( await R . getCell ( "SELECT `status` FROM heartbeat WHERE monitor_id = ?" , [ monitorID ] ) ) ;
console . log ( "here???" + status ) ;
if ( status === UP ) {
if ( status === UP ) {
uptime = 1 ;
uptime = 1 ;
}
}