diff --git a/.gitignore b/.gitignore index bf28bbd..cae142a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ docker/build.tar.gz docker/.clone/ docker/settings.json src/.env +src/tests/user/ diff --git a/examples/body.js b/examples/body.js index ee93688..e73098e 100644 --- a/examples/body.js +++ b/examples/body.js @@ -22,6 +22,6 @@ async function downloadString(url){ }; module.exports = async function(job){ - let response = await downloadString(job.url); + let response = await downloadString(job.config.url); return response.body === 'some expected text'; } \ No newline at end of file diff --git a/examples/jenkinsBuildStatus.js b/examples/jenkinsBuildStatus.js index 878048e..d5072ec 100644 --- a/examples/jenkinsBuildStatus.js +++ b/examples/jenkinsBuildStatus.js @@ -4,7 +4,7 @@ let httpHelper = require('./../../lib/httpHelper'); module.exports = async function(job){ - let json = await httpHelper.downloadJSON(job.url); + let json = await httpHelper.downloadJSON(job.config.url); return json.result === 'SUCCESS'; } diff --git a/src/lib/daemon.js b/src/lib/daemon.js index bb14732..9ffdd76 100644 --- a/src/lib/daemon.js +++ b/src/lib/daemon.js @@ -15,16 +15,11 @@ let cronJobs = []; class CronProcess { - constructor(name, url, interval, expect, test, args, recipients){ + constructor(config){ + this.config = config; this.logInfo = Logger.instance().info.info; this.logError = Logger.instance().error.error; - this.interval = interval; - this.expect = expect; - this.test = test; - this.name = name; - this.url = url; - this.args = args; this.isPassing = false; this.errorMessage = 'Checking has not run yet'; this.busy = false; @@ -33,17 +28,21 @@ class CronProcess this.recipients = []; // recipients is optional. It is a list of strings which must correspond to "name" values in objects in settings.people array. - if (!recipients) - recipients = []; + if (!this.config.recipients) + this.config.recipients = []; - if (recipients && typeof recipients === 'string'){ - recipients = recipients.split(','); + if (this.config.recipients && typeof this.config.recipients === 'string'){ + this.config.recipients = this.config.recipients.split(','); } - for (let recipientName of recipients){ + + for (let recipientName of this.config.recipients){ let recipientObject = settings.people.find((r)=> { return r.name === recipientName ? r : null; }); + + console.log('>>>>', recipientName); + if (!recipientObject){ - this.logError(`Recipient name "${recipientName}" in job ${this.name} could not be matched to a recipient in settings. This person will not receive notifications.`); + this.logError(`Recipient name "${recipientName}" in job ${this.config.name} could not be matched to a recipient in settings. This person will not receive notifications.`); continue; } @@ -61,13 +60,13 @@ class CronProcess start(){ - this.logInfo('Starting service' + this.interval) + this.logInfo('Starting service' + this.config.interval) - this.cron = new CronJob(this.interval, async()=>{ + this.cron = new CronJob(this.config.interval, async()=>{ try { if (this.busy){ - this.logInfo(`${this.name} check was busy from previous run, skipping`); + this.logInfo(`${this.config.name} check was busy from previous run, skipping`); return; } @@ -89,24 +88,24 @@ class CronProcess this.isPassing = true; this.lastRun = new Date(); - if (this.test){ + if (this.config.test){ try { - let test = require(`./../tests/${this.test}`); - let result = await test.call(this, this, this.args); + let test = require(`./../tests/${this.config.test}`); + let result = await test.call(this, this); this.isPassing = result === true; } catch(ex){ - this.logError(`Unhandled exception in user test ${this.test} : ${ex}`); + this.logError(`Unhandled exception in user test ${this.config.test} : ${ex}`); this.isPassing = false; this.errorMessage = ex; } } else { // do a simple http get - await httpHelper.downloadString(this.url); + await httpHelper.downloadString(this.config.url); } } catch(ex){ - this.errorMessage = ex.errno === 'ENOTFOUND' || ex.errno === 'EAI_AGAIN' ? `${this.url} could not be reached.` :this.errorMessage = ex; + this.errorMessage = ex.errno === 'ENOTFOUND' || ex.errno === 'EAI_AGAIN' ? `${this.config.url} could not be reached.` :this.errorMessage = ex; this.isPassing = false; } @@ -115,20 +114,17 @@ class CronProcess if (this.errorMessage) this.logInfo(this.errorMessage); - else - this.logInfo(`${this.name} check passed`); - - let flag = path.join(flagFolder, this.name), + let flag = path.join(flagFolder, this.config.name), statusChanged = false, - historyLogFolder = path.join(flagFolder, `${this.name}_history`); + historyLogFolder = path.join(flagFolder, `${this.config.name}_history`); if (this.isPassing){ await fs.ensureDir(historyLogFolder); jsonfile.writeFileSync(path.join(historyLogFolder, `status.json`), { status : 'up', - url : this.url, + url : this.config.url, date : this.lastRun }); @@ -139,11 +135,11 @@ class CronProcess jsonfile.writeFileSync(path.join(historyLogFolder, `${this.lastRun.getTime()}.json`), { status : 'up', - url : this.url, + url : this.config.url, date : this.lastRun }); - this.logInfo(`Status changed, flag removed for ${this.name}`); + this.logInfo(`Status changed, flag removed for ${this.config.name}`); statusChanged = true; } } else { @@ -154,23 +150,23 @@ class CronProcess // site is down, write fail flag and log jsonfile.writeFileSync(flag, { - url : this.url, + url : this.config.url, date : new Date() }); jsonfile.writeFileSync(path.join(historyLogFolder, `${this.lastRun.getTime()}.json`), { status : 'down', - url : this.url, + url : this.config.url, date : new Date() }); jsonfile.writeFileSync(path.join(historyLogFolder, `status.json`), { status : 'down', - url : this.url, + url : this.config.url, date : this.lastRun }); - this.logInfo(`Status changed, flag created for ${this.name}`); + this.logInfo(`Status changed, flag created for ${this.config.name}`); statusChanged = true; } } @@ -178,8 +174,8 @@ class CronProcess // send email if site status has change changed if (statusChanged){ - let subject = this.isPassing ? `${this.name} is up` : `${this.name} is down`, - message = this.isPassing ? `${this.name} is up` : `${this.name} is down`; + let subject = this.isPassing ? `${this.config.name} is up` : `${this.config.name} is down`, + message = this.isPassing ? `${this.config.name} is up` : `${this.config.name} is down`; let sendMethod = settings.smtp ? smtp : settings.sendgrid ? sendgrid : @@ -187,11 +183,13 @@ class CronProcess if (sendMethod){ for (let recipient of this.recipients){ - if (!recipient.email) - continue; + // handle email + if (recipient.email){ + let result = await sendMethod(recipient.email, subject, message); + this.logInfo(`Sent email to ${recipient.email} for process ${this.config.name} with result : ${result}` ); + } - let result = await sendMethod(recipient.email, subject, message); - this.logInfo(`Sent email to ${recipient.email} for process ${this.name} with result : ${result}` ); + // handle slack } } } @@ -205,7 +203,7 @@ module.exports = { start : ()=>{ for (const job of settings.jobs){ - const cronjob = new CronProcess(job.name, job.url, job.interval, job.expect, job.test, job.args, job.recipients ); + const cronjob = new CronProcess(job); cronJobs.push(cronjob); cronjob.start(); } diff --git a/src/lib/handlebars.js b/src/lib/handlebars.js index a4aeead..2f4fd07 100644 --- a/src/lib/handlebars.js +++ b/src/lib/handlebars.js @@ -33,6 +33,14 @@ Handlebars.registerHelper('ago', function(date){ return ago(date); }); +Handlebars.registerHelper('secondsFromNow', function(futureDate){ + if (typeof futureDate === 'string') + futureDate = new Date(futureDate); + + + return Math.floor((futureDate.getTime() - Date.now()) / 1000); +}); + Handlebars.registerHelper('time', function(date){ if (typeof date === 'string') date = new Date(date); diff --git a/src/public/css/style.css b/src/public/css/style.css index 11d7475..f1113d8 100644 --- a/src/public/css/style.css +++ b/src/public/css/style.css @@ -128,7 +128,6 @@ body { } .layout-renderTime{ - color: gray; font-style: italic; padding-top: var(--dimension-universalUnit); } diff --git a/src/public/js/base.js b/src/public/js/base.js index 4cfc46e..ad2f848 100644 --- a/src/public/js/base.js +++ b/src/public/js/base.js @@ -1,6 +1,10 @@ var clientRefreshInterval = document.querySelector('body').getAttribute('data-clientRefreshInterval'); var updateInSeconds = document.querySelector('.layout-updateTime'); -var renderTime = new Date(document.querySelector('.renderTime').getAttribute('data-value')); +var renderTime = null; //new Date(document.querySelector('.renderTime').getAttribute('data-value')); + +var nowHolder = document.querySelector('.now'); +var now = new Date(); +nowHolder.innerHTML = now.toLocaleDateString() + ' ' + now.toLocaleTimeString(); if (clientRefreshInterval) clientRefreshInterval = parseInt(clientRefreshInterval); @@ -43,9 +47,9 @@ function showUpdateTime(){ setInterval(function(){ showTimes(); - showUpdateTime(); + //showUpdateTime(); }, 1000); showTimes(); -showUpdateTime(); +//showUpdateTime(); diff --git a/src/routes/default.js b/src/routes/default.js index eb31686..9c8e2cd 100644 --- a/src/routes/default.js +++ b/src/routes/default.js @@ -25,7 +25,7 @@ module.exports = function(app){ }).length === 0; cronJobs.sort((a,b)=>{ - return a.isPassing - b.isPassing || a.name.localeCompare(b.name) + return a.isPassing - b.isPassing || a.config.name.localeCompare(b.config.name) /* return a.isPassing? 1 : b.isPassing? -1 : @@ -34,7 +34,7 @@ module.exports = function(app){ }); for (let cronJob of cronJobs){ - const statusFilePath = path.join(__dirname, './../flags', `${cronJob.name}_history` , 'status.json'); + const statusFilePath = path.join(__dirname, './../flags', `${cronJob.config.name}_history` , 'status.json'); cronJob.status = 'unknown' cronJob.statusDate = null; @@ -45,16 +45,19 @@ module.exports = function(app){ const status = jsonfile.readFileSync(statusFilePath); cronJob.status = status.status; cronJob.statusDate = new Date(status.date); + if (cronJob.nextRun){ //console.log(cronJob.nextRun.getTime()); cronJob.next = Math.floor((cronJob.nextRun.getTime() - new Date().getTime()) / 1000) + 's'; } } + const now = new Date(); + res.send(view({ clientRefreshInterval : settings.clientRefreshInterval, allJobsPassed, - renderDate: new Date(), + renderDate: `${now.toLocaleDateString()} ${now.toLocaleTimeString()}`, jobs : cronJobs })); }); diff --git a/src/views/pages/status.hbs b/src/views/pages/status.hbs index 8d62e81..7819498 100644 --- a/src/views/pages/status.hbs +++ b/src/views/pages/status.hbs @@ -15,19 +15,21 @@ Target