2024-12-24 11:58:26 -08:00
const SERVICE_NAME = "StatusService" ;
2024-10-28 14:19:14 +08:00
class StatusService {
2024-12-24 11:58:26 -08:00
static SERVICE_NAME = SERVICE_NAME ;
2024-10-28 14:19:14 +08:00
/**
* Creates an instance of StatusService.
*
* @param {Object} db - The database instance.
* @param {Object} logger - The logger instance.
*/
constructor ( db , logger ) {
this . db = db ;
this . logger = logger ;
2024-12-24 11:58:26 -08:00
this . SERVICE_NAME = SERVICE_NAME ;
2024-10-28 14:19:14 +08:00
}
2024-11-24 15:59:09 +08:00
getStatusString = ( status ) => {
if ( status === true ) return "up" ;
if ( status === false ) return "down" ;
return "unknown" ;
};
2024-10-28 14:19:14 +08:00
/**
* Updates the status of a monitor based on the network response.
*
* @param {Object} networkResponse - The network response containing monitorId and status.
* @param {string} networkResponse.monitorId - The ID of the monitor.
* @param {string} networkResponse.status - The new status of the monitor.
* @returns {Promise<Object>} - A promise that resolves to an object containing the monitor, statusChanged flag, and previous status if the status changed, or false if an error occurred.
* @returns {Promise<Object>} returnObject - The object returned by the function.
* @returns {Object} returnObject.monitor - The monitor object.
* @returns {boolean} returnObject.statusChanged - Flag indicating if the status has changed.
* @returns {boolean} returnObject.prevStatus - The previous status of the monitor
*/
updateStatus = async ( networkResponse ) => {
this . insertCheck ( networkResponse );
try {
const { monitorId , status } = networkResponse ;
const monitor = await this . db . getMonitorById ( monitorId );
// No change in monitor status, return early
2024-11-22 11:56:13 +08:00
if ( monitor . status === status )
return { monitor , statusChanged : false , prevStatus : monitor . status };
2024-10-28 14:19:14 +08:00
// Monitor status changed, save prev status and update monitor
this . logger . info ({
service : this . SERVICE_NAME ,
2024-11-24 15:59:09 +08:00
message : ` ${ monitor . name } went from ${ this . getStatusString ( monitor . status ) } to ${ this . getStatusString ( status ) } ` ,
2024-10-28 14:19:14 +08:00
prevStatus : monitor . status ,
newStatus : status ,
});
const prevStatus = monitor . status ;
monitor . status = status ;
2024-10-28 15:34:19 +08:00
await monitor . save ();
2024-10-28 14:19:14 +08:00
return {
monitor ,
statusChanged : true ,
prevStatus : prevStatus ,
};
//
} catch ( error ) {
this . logger . error ({
service : this . SERVICE_NAME ,
message : error . message ,
method : "updateStatus" ,
stack : error . stack ,
});
throw error ;
}
};
/**
* Builds a check object from the network response.
*
* @param {Object} networkResponse - The network response object.
* @param {string} networkResponse.monitorId - The monitor ID.
* @param {string} networkResponse.type - The type of the response.
* @param {string} networkResponse.status - The status of the response.
* @param {number} networkResponse.responseTime - The response time.
* @param {number} networkResponse.code - The status code.
* @param {string} networkResponse.message - The message.
* @param {Object} networkResponse.payload - The payload of the response.
* @returns {Object} The check object.
*/
buildCheck = ( networkResponse ) => {
2025-01-21 15:30:51 -08:00
const { monitorId , teamId , type , status , responseTime , code , message , payload } =
2024-10-28 14:19:14 +08:00
networkResponse ;
const check = {
monitorId ,
2025-01-21 15:30:51 -08:00
teamId ,
2024-10-28 14:19:14 +08:00
status ,
statusCode : code ,
responseTime ,
message ,
};
2024-11-11 08:52:51 +08:00
2024-10-28 14:19:14 +08:00
if ( type === "pagespeed" ) {
const categories = payload . lighthouseResult ? . categories ;
const audits = payload . lighthouseResult ? . audits ;
const {
"cumulative-layout-shift" : cls = 0 ,
"speed-index" : si = 0 ,
"first-contentful-paint" : fcp = 0 ,
"largest-contentful-paint" : lcp = 0 ,
"total-blocking-time" : tbt = 0 ,
} = audits ;
check . accessibility = ( categories . accessibility ? . score || 0 ) * 100 ;
check . bestPractices = ( categories [ "best-practices" ] ? . score || 0 ) * 100 ;
check . seo = ( categories . seo ? . score || 0 ) * 100 ;
check . performance = ( categories . performance ? . score || 0 ) * 100 ;
check . audits = { cls , si , fcp , lcp , tbt };
}
2024-10-29 13:51:31 +08:00
if ( type === "hardware" ) {
2024-11-11 08:52:51 +08:00
const { cpu , memory , disk , host } = payload ? . data ?? {};
2024-11-24 17:39:05 +08:00
const { errors } = payload ? . errors ?? [];
2024-11-11 08:52:51 +08:00
check . cpu = cpu ?? {};
check . memory = memory ?? {};
check . disk = disk ?? {};
check . host = host ?? {};
check . errors = errors ?? [];
2024-10-29 13:51:31 +08:00
}
2024-10-28 14:19:14 +08:00
return check ;
};
/**
* Inserts a check into the database based on the network response.
*
* @param {Object} networkResponse - The network response object.
* @param {string} networkResponse.monitorId - The monitor ID.
* @param {string} networkResponse.type - The type of the response.
* @param {string} networkResponse.status - The status of the response.
* @param {number} networkResponse.responseTime - The response time.
* @param {number} networkResponse.code - The status code.
* @param {string} networkResponse.message - The message.
* @param {Object} networkResponse.payload - The payload of the response.
* @returns {Promise<void>} A promise that resolves when the check is inserted.
*/
insertCheck = async ( networkResponse ) => {
try {
const operationMap = {
http : this . db . createCheck ,
ping : this . db . createCheck ,
pagespeed : this . db . createPageSpeedCheck ,
2024-10-29 13:51:31 +08:00
hardware : this . db . createHardwareCheck ,
2024-11-13 11:07:36 +08:00
docker : this . db . createCheck ,
2024-12-27 10:49:45 -08:00
port : this . db . createCheck ,
2024-10-28 14:19:14 +08:00
};
const operation = operationMap [ networkResponse . type ];
2024-11-11 08:52:51 +08:00
2024-10-28 14:19:14 +08:00
const check = this . buildCheck ( networkResponse );
await operation ( check );
} catch ( error ) {
this . logger . error ({
message : error . message ,
service : this . SERVICE_NAME ,
method : "insertCheck" ,
2024-10-29 13:51:31 +08:00
details : `Error inserting check for monitor: ${ networkResponse ? . monitorId } ` ,
2024-10-28 14:19:14 +08:00
stack : error . stack ,
});
}
};
}
export default StatusService ;