@ -34,9 +34,12 @@ const Database = require("../database");
class Monitor extends BeanModel {
class Monitor extends BeanModel {
/ * *
/ * *
* Return an object that ready to parse to JSON for public
* Return an object that ready to parse to JSON for public Only show
* Only show necessary data to public
* necessary data to public
* @ returns { Object }
* @ param { boolean } showTags Include tags in JSON
* @ param { boolean } certExpiry Include certificate expiry info in
* JSON
* @ returns { object } Object ready to parse
* /
* /
async toPublicJSON ( showTags = false , certExpiry = false ) {
async toPublicJSON ( showTags = false , certExpiry = false ) {
let obj = {
let obj = {
@ -65,7 +68,9 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Return an object that ready to parse to JSON
* Return an object that ready to parse to JSON
* @ returns { Object }
* @ param { boolean } includeSensitiveData Include sensitive data in
* JSON
* @ returns { object } Object ready to parse
* /
* /
async toJSON ( includeSensitiveData = true ) {
async toJSON ( includeSensitiveData = true ) {
@ -184,7 +189,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Checks if the monitor is active based on itself and its parents
* Checks if the monitor is active based on itself and its parents
* @ returns { Promise < Boolean > }
* @ returns { Promise < boolean > } Is the monitor active ?
* /
* /
async isActive ( ) {
async isActive ( ) {
const parentActive = await Monitor . isParentActive ( this . id ) ;
const parentActive = await Monitor . isParentActive ( this . id ) ;
@ -194,7 +199,8 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Get all tags applied to this monitor
* Get all tags applied to this monitor
* @ returns { Promise < LooseObject < any > [ ] > }
* @ returns { Promise < LooseObject < any > [ ] > } List of tags on the
* monitor
* /
* /
async getTags ( ) {
async getTags ( ) {
return await R . getAll ( "SELECT mt.*, tag.name, tag.color FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ? ORDER BY tag.name" , [ this . id ] ) ;
return await R . getAll ( "SELECT mt.*, tag.name, tag.color FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ? ORDER BY tag.name" , [ this . id ] ) ;
@ -203,7 +209,8 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Gets certificate expiry for this monitor
* Gets certificate expiry for this monitor
* @ param { number } monitorID ID of monitor to send
* @ param { number } monitorID ID of monitor to send
* @ returns { Promise < LooseObject < any >> }
* @ returns { Promise < LooseObject < any >> } Certificate expiry info for
* monitor
* /
* /
async getCertExpiry ( monitorID ) {
async getCertExpiry ( monitorID ) {
let tlsInfoBean = await R . findOne ( "monitor_tls_info" , "monitor_id = ?" , [
let tlsInfoBean = await R . findOne ( "monitor_tls_info" , "monitor_id = ?" , [
@ -228,7 +235,9 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Encode user and password to Base64 encoding
* Encode user and password to Base64 encoding
* for HTTP "basic" auth , as per RFC - 7617
* for HTTP "basic" auth , as per RFC - 7617
* @ returns { string }
* @ param { string } user Username to encode
* @ param { string } pass Password to encode
* @ returns { string } Encoded username : password
* /
* /
encodeBase64 ( user , pass ) {
encodeBase64 ( user , pass ) {
return Buffer . from ( user + ":" + pass ) . toString ( "base64" ) ;
return Buffer . from ( user + ":" + pass ) . toString ( "base64" ) ;
@ -236,7 +245,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Is the TLS expiry notification enabled ?
* Is the TLS expiry notification enabled ?
* @ returns { boolean }
* @ returns { boolean } Enabled ?
* /
* /
isEnabledExpiryNotification ( ) {
isEnabledExpiryNotification ( ) {
return Boolean ( this . expiryNotification ) ;
return Boolean ( this . expiryNotification ) ;
@ -244,7 +253,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Parse to boolean
* Parse to boolean
* @ returns { boolean }
* @ returns { boolean } Should TLS errors be ignored ?
* /
* /
getIgnoreTls ( ) {
getIgnoreTls ( ) {
return Boolean ( this . ignoreTls ) ;
return Boolean ( this . ignoreTls ) ;
@ -252,7 +261,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Parse to boolean
* Parse to boolean
* @ returns { boolean }
* @ returns { boolean } Is the monitor in upside down mode ?
* /
* /
isUpsideDown ( ) {
isUpsideDown ( ) {
return Boolean ( this . upsideDown ) ;
return Boolean ( this . upsideDown ) ;
@ -260,7 +269,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Parse to boolean
* Parse to boolean
* @ returns { boolean }
* @ returns { boolean } Invert keyword match ?
* /
* /
isInvertKeyword ( ) {
isInvertKeyword ( ) {
return Boolean ( this . invertKeyword ) ;
return Boolean ( this . invertKeyword ) ;
@ -268,7 +277,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Parse to boolean
* Parse to boolean
* @ returns { boolean }
* @ returns { boolean } Enable TLS for gRPC ?
* /
* /
getGrpcEnableTls ( ) {
getGrpcEnableTls ( ) {
return Boolean ( this . grpcEnableTls ) ;
return Boolean ( this . grpcEnableTls ) ;
@ -276,7 +285,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Get accepted status codes
* Get accepted status codes
* @ returns { Object }
* @ returns { object } Accepted status codes
* /
* /
getAcceptedStatuscodes ( ) {
getAcceptedStatuscodes ( ) {
return JSON . parse ( this . accepted _statuscodes _json ) ;
return JSON . parse ( this . accepted _statuscodes _json ) ;
@ -289,6 +298,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Start monitor
* Start monitor
* @ param { Server } io Socket server instance
* @ param { Server } io Socket server instance
* @ returns { void }
* /
* /
start ( io ) {
start ( io ) {
let previousBeat = null ;
let previousBeat = null ;
@ -980,7 +990,10 @@ class Monitor extends BeanModel {
} ;
} ;
/** Get a heartbeat and handle errors */
/ * *
* Get a heartbeat and handle errors7
* @ returns { void }
* /
const safeBeat = async ( ) => {
const safeBeat = async ( ) => {
try {
try {
await beat ( ) ;
await beat ( ) ;
@ -1008,10 +1021,10 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Make a request using axios
* Make a request using axios
* @ param { O bject} options Options for Axios
* @ param { o bject} options Options for Axios
* @ param { boolean } finalCall Should this be the final call i . e
* @ param { boolean } finalCall Should this be the final call i . e
* don ' t retry on fa l iure
* don ' t retry on fa il ure
* @ returns { O bject} Axios response
* @ returns { o bject} Axios response
* /
* /
async makeAxiosRequest ( options , finalCall = false ) {
async makeAxiosRequest ( options , finalCall = false ) {
try {
try {
@ -1046,7 +1059,10 @@ class Monitor extends BeanModel {
}
}
}
}
/** Stop monitor */
/ * *
* Stop monitor
* @ returns { void }
* /
stop ( ) {
stop ( ) {
clearTimeout ( this . heartbeatInterval ) ;
clearTimeout ( this . heartbeatInterval ) ;
this . isStop = true ;
this . isStop = true ;
@ -1056,7 +1072,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Get prometheus instance
* Get prometheus instance
* @ returns { Prometheus | undefined }
* @ returns { Prometheus | undefined } Current prometheus instance
* /
* /
getPrometheus ( ) {
getPrometheus ( ) {
return this . prometheus ;
return this . prometheus ;
@ -1066,7 +1082,7 @@ class Monitor extends BeanModel {
* Helper Method :
* Helper Method :
* returns URL object for further usage
* returns URL object for further usage
* returns null if url is invalid
* returns null if url is invalid
* @ returns { ( null | URL ) }
* @ returns { ( null | URL ) } Monitor URL
* /
* /
getUrl ( ) {
getUrl ( ) {
try {
try {
@ -1078,8 +1094,8 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Store TLS info to database
* Store TLS info to database
* @ param checkCertificateResult
* @ param { object } checkCertificateResult Certificate to update
* @ returns { Promise < Object > }
* @ returns { Promise < object > } Updated certificate
* /
* /
async updateTlsInfo ( checkCertificateResult ) {
async updateTlsInfo ( checkCertificateResult ) {
let tlsInfoBean = await R . findOne ( "monitor_tls_info" , "monitor_id = ?" , [
let tlsInfoBean = await R . findOne ( "monitor_tls_info" , "monitor_id = ?" , [
@ -1126,6 +1142,7 @@ class Monitor extends BeanModel {
* @ param { Server } io Socket server instance
* @ param { Server } io Socket server instance
* @ param { number } monitorID ID of monitor to send
* @ param { number } monitorID ID of monitor to send
* @ param { number } userID ID of user to send to
* @ param { number } userID ID of user to send to
* @ returns { void }
* /
* /
static async sendStats ( io , monitorID , userID ) {
static async sendStats ( io , monitorID , userID ) {
const hasClients = getTotalClientInRoom ( io , userID ) > 0 ;
const hasClients = getTotalClientInRoom ( io , userID ) > 0 ;
@ -1143,6 +1160,10 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Send the average ping to user
* Send the average ping to user
* @ param { number } duration Hours
* @ param { number } duration Hours
* @ param { Server } io Socket instance to send data to
* @ param { number } monitorID ID of monitor to read
* @ param { number } userID ID of user to send data to
* @ returns { void }
* /
* /
static async sendAvgPing ( duration , io , monitorID , userID ) {
static async sendAvgPing ( duration , io , monitorID , userID ) {
const timeLogger = new TimeLogger ( ) ;
const timeLogger = new TimeLogger ( ) ;
@ -1168,6 +1189,7 @@ class Monitor extends BeanModel {
* @ param { Server } io Socket server instance
* @ param { Server } io Socket server instance
* @ param { number } monitorID ID of monitor to send
* @ param { number } monitorID ID of monitor to send
* @ param { number } userID ID of user to send to
* @ param { number } userID ID of user to send to
* @ returns { void }
* /
* /
static async sendCertInfo ( io , monitorID , userID ) {
static async sendCertInfo ( io , monitorID , userID ) {
let tlsInfo = await R . findOne ( "monitor_tls_info" , "monitor_id = ?" , [
let tlsInfo = await R . findOne ( "monitor_tls_info" , "monitor_id = ?" , [
@ -1184,6 +1206,8 @@ class Monitor extends BeanModel {
* https : //www.uptrends.com/support/kb/reporting/calculation-of-uptime-and-downtime
* https : //www.uptrends.com/support/kb/reporting/calculation-of-uptime-and-downtime
* @ param { number } duration Hours
* @ param { number } duration Hours
* @ param { number } monitorID ID of monitor to calculate
* @ param { number } monitorID ID of monitor to calculate
* @ param { boolean } forceNoCache Should the uptime be recalculated ?
* @ returns { number } Uptime of monitor
* /
* /
static async calcUptime ( duration , monitorID , forceNoCache = false ) {
static async calcUptime ( duration , monitorID , forceNoCache = false ) {
@ -1264,6 +1288,7 @@ class Monitor extends BeanModel {
* @ param { Server } io Socket server instance
* @ param { Server } io Socket server instance
* @ param { number } monitorID ID of monitor to send
* @ param { number } monitorID ID of monitor to send
* @ param { number } userID ID of user to send to
* @ param { number } userID ID of user to send to
* @ returns { void }
* /
* /
static async sendUptime ( duration , io , monitorID , userID ) {
static async sendUptime ( duration , io , monitorID , userID ) {
const uptime = await this . calcUptime ( duration , monitorID ) ;
const uptime = await this . calcUptime ( duration , monitorID ) ;
@ -1338,6 +1363,7 @@ class Monitor extends BeanModel {
* @ param { boolean } isFirstBeat Is this beat the first of this monitor ?
* @ param { boolean } isFirstBeat Is this beat the first of this monitor ?
* @ param { Monitor } monitor The monitor to send a notificaton about
* @ param { Monitor } monitor The monitor to send a notificaton about
* @ param { Bean } bean Status information about monitor
* @ param { Bean } bean Status information about monitor
* @ returns { void }
* /
* /
static async sendNotification ( isFirstBeat , monitor , bean ) {
static async sendNotification ( isFirstBeat , monitor , bean ) {
if ( ! isFirstBeat || bean . status === DOWN ) {
if ( ! isFirstBeat || bean . status === DOWN ) {
@ -1378,7 +1404,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Get list of notification providers for a given monitor
* Get list of notification providers for a given monitor
* @ param { Monitor } monitor Monitor to get notification providers for
* @ param { Monitor } monitor Monitor to get notification providers for
* @ returns { Promise < LooseObject < any > [ ] > }
* @ returns { Promise < LooseObject < any > [ ] > } List of notifications
* /
* /
static async getNotificationList ( monitor ) {
static async getNotificationList ( monitor ) {
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 " , [
@ -1389,7 +1415,8 @@ class Monitor extends BeanModel {
/ * *
/ * *
* checks certificate chain for expiring certificates
* checks certificate chain for expiring certificates
* @ param { Object } tlsInfoObject Information about certificate
* @ param { object } tlsInfoObject Information about certificate
* @ returns { void }
* /
* /
async checkCertExpiryNotifications ( tlsInfoObject ) {
async checkCertExpiryNotifications ( tlsInfoObject ) {
if ( tlsInfoObject && tlsInfoObject . certInfo && tlsInfoObject . certInfo . daysRemaining ) {
if ( tlsInfoObject && tlsInfoObject . certInfo && tlsInfoObject . certInfo . daysRemaining ) {
@ -1476,7 +1503,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Get the status of the previous heartbeat
* Get the status of the previous heartbeat
* @ param { number } monitorID ID of monitor to check
* @ param { number } monitorID ID of monitor to check
* @ returns { Promise < LooseObject < any >> }
* @ returns { Promise < LooseObject < any >> } Previous heartbeat
* /
* /
static async getPreviousHeartbeat ( monitorID ) {
static async getPreviousHeartbeat ( monitorID ) {
return await R . getRow ( `
return await R . getRow ( `
@ -1490,7 +1517,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Check if monitor is under maintenance
* Check if monitor is under maintenance
* @ param { number } monitorID ID of monitor to check
* @ param { number } monitorID ID of monitor to check
* @ returns { Promise < boolean > }
* @ returns { Promise < boolean > } Is the monitor under maintenance
* /
* /
static async isUnderMaintenance ( monitorID ) {
static async isUnderMaintenance ( monitorID ) {
const maintenanceIDList = await R . getCol ( `
const maintenanceIDList = await R . getCol ( `
@ -1513,7 +1540,11 @@ class Monitor extends BeanModel {
return false ;
return false ;
}
}
/** Make sure monitor interval is between bounds */
/ * *
* Make sure monitor interval is between bounds
* @ returns { void }
* @ throws Interval is outside of range
* /
validate ( ) {
validate ( ) {
if ( this . interval > MAX _INTERVAL _SECOND ) {
if ( this . interval > MAX _INTERVAL _SECOND ) {
throw new Error ( ` Interval cannot be more than ${ MAX _INTERVAL _SECOND } seconds ` ) ;
throw new Error ( ` Interval cannot be more than ${ MAX _INTERVAL _SECOND } seconds ` ) ;
@ -1526,7 +1557,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Gets Parent of the monitor
* Gets Parent of the monitor
* @ param { number } monitorID ID of monitor to get
* @ param { number } monitorID ID of monitor to get
* @ returns { Promise < LooseObject < any >> }
* @ returns { Promise < LooseObject < any >> } Parent
* /
* /
static async getParent ( monitorID ) {
static async getParent ( monitorID ) {
return await R . getRow ( `
return await R . getRow ( `
@ -1542,7 +1573,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Gets all Children of the monitor
* Gets all Children of the monitor
* @ param { number } monitorID ID of monitor to get
* @ param { number } monitorID ID of monitor to get
* @ returns { Promise < LooseObject < any >> }
* @ returns { Promise < LooseObject < any >> } Children
* /
* /
static async getChildren ( monitorID ) {
static async getChildren ( monitorID ) {
return await R . getAll ( `
return await R . getAll ( `
@ -1555,7 +1586,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Gets Full Path - Name ( Groups and Name )
* Gets Full Path - Name ( Groups and Name )
* @ returns { Promise < String > }
* @ returns { Promise < string > } Full path name of this monitor
* /
* /
async getPathName ( ) {
async getPathName ( ) {
let path = this . name ;
let path = this . name ;
@ -1576,7 +1607,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Gets recursive all child ids
* Gets recursive all child ids
* @ param { number } monitorID ID of the monitor to get
* @ param { number } monitorID ID of the monitor to get
* @ returns { Promise < Array > }
* @ returns { Promise < Array > } IDs of all children
* /
* /
static async getAllChildrenIDs ( monitorID ) {
static async getAllChildrenIDs ( monitorID ) {
const childs = await Monitor . getChildren ( monitorID ) ;
const childs = await Monitor . getChildren ( monitorID ) ;
@ -1609,7 +1640,7 @@ class Monitor extends BeanModel {
/ * *
/ * *
* Checks recursive if parent ( ancestors ) are active
* Checks recursive if parent ( ancestors ) are active
* @ param { number } monitorID ID of the monitor to get
* @ param { number } monitorID ID of the monitor to get
* @ returns { Promise < Boolean > }
* @ returns { Promise < boolean > } Is the parent monitor active ?
* /
* /
static async isParentActive ( monitorID ) {
static async isParentActive ( monitorID ) {
const parent = await Monitor . getParent ( monitorID ) ;
const parent = await Monitor . getParent ( monitorID ) ;