From 137d53715ebe0ec96430d95e0a230547b34e4262 Mon Sep 17 00:00:00 2001 From: Luke Cheng Date: Sun, 1 Dec 2024 20:53:44 -0800 Subject: [PATCH 1/4] created a script to check website status and send email to users if website is down --- package-lock.json | 32 ++++++++++++++ package.json | 3 ++ src/server/services/checkWebsiteStatus.js | 52 +++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 src/server/services/checkWebsiteStatus.js diff --git a/package-lock.json b/package-lock.json index 68bc1cd28..30f020e45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "bcryptjs": "~2.4.3", "body-parser": "~1.20.2", "bootstrap": "~5.3.3", + "colors": "~1.4.0", "csv": "~5.3.2", "csv-stringify": "~5.6.5", "d3": "~7.8.5", @@ -34,6 +35,7 @@ "multer": "~1.4.5-lts.1", "ngraph.graph": "~20.0.0", "ngraph.path": "~1.5.0", + "node-cron": "~3.0.3", "nodemailer": "~6.9.13", "pg": "~8.12.0", "pg-promise": "~11.8.0", @@ -2886,6 +2888,15 @@ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -7252,6 +7263,27 @@ "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", "dev": true }, + "node_modules/node-cron": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz", + "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==", + "license": "ISC", + "dependencies": { + "uuid": "8.3.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/node-cron/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/node-polyfill-webpack-plugin": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-1.1.4.tgz", diff --git a/package.json b/package.json index fa5f6d8de..4fc5b5ad3 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "scripts": { "start": "node ./src/bin/www", "start:dev": "nodemon --legacy-watch --inspect=0.0.0.0 ./src/bin/www", + "status": "node src/server/services/checkWebsiteStatus.js", "webpack:dev": "webpack watch --color --progress --mode development", "webpack:build": "webpack build --node-env production", "webpack": "webpack build --color --progress --mode development", @@ -62,6 +63,7 @@ "bcryptjs": "~2.4.3", "body-parser": "~1.20.2", "bootstrap": "~5.3.3", + "colors": "~1.4.0", "csv": "~5.3.2", "csv-stringify": "~5.6.5", "d3": "~7.8.5", @@ -81,6 +83,7 @@ "multer": "~1.4.5-lts.1", "ngraph.graph": "~20.0.0", "ngraph.path": "~1.5.0", + "node-cron": "~3.0.3", "nodemailer": "~6.9.13", "pg": "~8.12.0", "pg-promise": "~11.8.0", diff --git a/src/server/services/checkWebsiteStatus.js b/src/server/services/checkWebsiteStatus.js new file mode 100644 index 000000000..b8e2ad9de --- /dev/null +++ b/src/server/services/checkWebsiteStatus.js @@ -0,0 +1,52 @@ +const cron = require('node-cron'); +const { getConnection } = require('../db'); +const { logMailer } = require('../logMailer'); +const LogEmail = require('../models/LogEmail'); +const colors = require('colors'); + +async function checkWebsite() { + const conn = getConnection(); + + try { + const response = await fetch('https://httpstat.us/500/', { method: 'HEAD' }); + + if (response.ok) { + console.log('The server is up'.green.inverse); + } else { + console.error('The server is down'.red.inverse); + + const errorMessage = 'The server at https://httpstat.us/500/ is down.'; + + // Log the error in the database + const log = new LogEmail(undefined, errorMessage); + await log.insert(conn); + + // Send a logging email + await logMailer(conn); + } + } + catch (error) { + console.error('Error:', error); + + const errorMessage = `Failed to reach https://httpstat.us/500/. Error: ${error.message}`; + + // Log the error in the database + const log = new LogEmail(undefined, errorMessage); + await log.insert(conn); + + // Send a logging email + await logMailer(conn); + } finally { + if (conn.close) { + await conn.close(); + } + } +} + +// Schedule the task to run every hour +// cron.schedule('0 * * * *', () => { +// console.log('Running website status check...'); +// checkWebsite(); +// }); + +checkWebsite(); \ No newline at end of file From 818f66c2b0ca6547397b21a2c5fd8e1564821adc Mon Sep 17 00:00:00 2001 From: Luke Cheng Date: Sat, 7 Dec 2024 09:06:32 -0800 Subject: [PATCH 2/4] Updated checWebsiteStatus.js to log the error using log.js. Created a shell script that runs checWebsiteStatus script in docker with ability to provide URL --- package.json | 3 +- src/scripts/checkWebsiteStatusCron.bash | 16 +++++ src/server/services/checkWebsiteStatus.js | 80 ++++++++--------------- 3 files changed, 45 insertions(+), 54 deletions(-) create mode 100644 src/scripts/checkWebsiteStatusCron.bash diff --git a/package.json b/package.json index 4fc5b5ad3..d725b94d8 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "start": "node ./src/bin/www", "start:dev": "nodemon --legacy-watch --inspect=0.0.0.0 ./src/bin/www", - "status": "node src/server/services/checkWebsiteStatus.js", + "checkWebsiteStatus": "node src/server/services/checkWebsiteStatus.js", "webpack:dev": "webpack watch --color --progress --mode development", "webpack:build": "webpack build --node-env production", "webpack": "webpack build --color --progress --mode development", @@ -63,7 +63,6 @@ "bcryptjs": "~2.4.3", "body-parser": "~1.20.2", "bootstrap": "~5.3.3", - "colors": "~1.4.0", "csv": "~5.3.2", "csv-stringify": "~5.6.5", "d3": "~7.8.5", diff --git a/src/scripts/checkWebsiteStatusCron.bash b/src/scripts/checkWebsiteStatusCron.bash new file mode 100644 index 000000000..3d5b15687 --- /dev/null +++ b/src/scripts/checkWebsiteStatusCron.bash @@ -0,0 +1,16 @@ +# This aggregates the readings data at hour level. +# This should be copied to /etc/ or /etc/cron.hourly/ or /etc/cron.daily and the copy renamed so that its function will be clear to admins. + +# Check if a URL is provided as an argument +if [ -z "$1" ]; then + echo "Error: No URL provided. Usage: $0" + exit 1 +fi + +URL=$1 + +# The absolute path the project root directory (OED) +cd '/example/path/to/project/OED' + +# The following line should NOT need to be edited except by devs or if you have an old system with only docker-compose. +docker compose run --rm web npm run --silent checkWebsiteStatus -- $URL &>> /dev/null & diff --git a/src/server/services/checkWebsiteStatus.js b/src/server/services/checkWebsiteStatus.js index b8e2ad9de..1009f4e75 100644 --- a/src/server/services/checkWebsiteStatus.js +++ b/src/server/services/checkWebsiteStatus.js @@ -1,52 +1,28 @@ -const cron = require('node-cron'); -const { getConnection } = require('../db'); -const { logMailer } = require('../logMailer'); -const LogEmail = require('../models/LogEmail'); -const colors = require('colors'); - -async function checkWebsite() { - const conn = getConnection(); - - try { - const response = await fetch('https://httpstat.us/500/', { method: 'HEAD' }); - - if (response.ok) { - console.log('The server is up'.green.inverse); - } else { - console.error('The server is down'.red.inverse); - - const errorMessage = 'The server at https://httpstat.us/500/ is down.'; - - // Log the error in the database - const log = new LogEmail(undefined, errorMessage); - await log.insert(conn); - - // Send a logging email - await logMailer(conn); - } - } - catch (error) { - console.error('Error:', error); - - const errorMessage = `Failed to reach https://httpstat.us/500/. Error: ${error.message}`; - - // Log the error in the database - const log = new LogEmail(undefined, errorMessage); - await log.insert(conn); - - // Send a logging email - await logMailer(conn); - } finally { - if (conn.close) { - await conn.close(); - } - } -} - -// Schedule the task to run every hour -// cron.schedule('0 * * * *', () => { -// console.log('Running website status check...'); -// checkWebsite(); -// }); - -checkWebsite(); \ No newline at end of file +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + const cron = require('node-cron'); + const { getConnection } = require('../db'); + const { log } = require('../log'); + const { logMailer } = require('../logMailer'); + const LogEmail = require('../models/LogEmail'); + const WEBSITE_URL = process.argv[2]; + + async function checkWebsite() { + try { + const response = await fetch(WEBSITE_URL, { method: 'HEAD' }); + + if (!response.ok) { + const errorMessage = `The server at ${WEBSITE_URL} is down.`; + // Log the error using Logger class + log.error(errorMessage); + } + } catch (error) { + const errorMessage = `Failed to reach ${WEBSITE_URL}. Error: ${error.message}`; + log.error(errorMessage, error); + } + } + + checkWebsite(); + \ No newline at end of file From f7006f21c61310b2e64c2c7a10a4db4844d5e08a Mon Sep 17 00:00:00 2001 From: Luke Cheng Date: Mon, 9 Dec 2024 13:19:18 -0800 Subject: [PATCH 3/4] Cleaned up unnecessary imports and comments --- package.json | 1 - src/scripts/checkWebsiteStatusCron.bash | 11 +++++++++-- src/server/services/checkWebsiteStatus.js | 4 ---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index d725b94d8..031ad7646 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,6 @@ "multer": "~1.4.5-lts.1", "ngraph.graph": "~20.0.0", "ngraph.path": "~1.5.0", - "node-cron": "~3.0.3", "nodemailer": "~6.9.13", "pg": "~8.12.0", "pg-promise": "~11.8.0", diff --git a/src/scripts/checkWebsiteStatusCron.bash b/src/scripts/checkWebsiteStatusCron.bash index 3d5b15687..b4e1cbb55 100644 --- a/src/scripts/checkWebsiteStatusCron.bash +++ b/src/scripts/checkWebsiteStatusCron.bash @@ -1,9 +1,16 @@ -# This aggregates the readings data at hour level. +#!/bin/bash +# * +# * This Source Code Form is subject to the terms of the Mozilla Public +# * License, v. 2.0. If a copy of the MPL was not distributed with this +# * file, You can obtain one at http://mozilla.org/MPL/2.0/. +# * + +# This check the website status at hour level. # This should be copied to /etc/ or /etc/cron.hourly/ or /etc/cron.daily and the copy renamed so that its function will be clear to admins. # Check if a URL is provided as an argument if [ -z "$1" ]; then - echo "Error: No URL provided. Usage: $0" + echo "Error: No URL provided. Usage: $0 URL-to-check" exit 1 fi diff --git a/src/server/services/checkWebsiteStatus.js b/src/server/services/checkWebsiteStatus.js index 1009f4e75..144aa903f 100644 --- a/src/server/services/checkWebsiteStatus.js +++ b/src/server/services/checkWebsiteStatus.js @@ -2,11 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - const cron = require('node-cron'); - const { getConnection } = require('../db'); const { log } = require('../log'); - const { logMailer } = require('../logMailer'); - const LogEmail = require('../models/LogEmail'); const WEBSITE_URL = process.argv[2]; async function checkWebsite() { From 08c24c9be0840dd257f64f0d3fcf230e5c92db85 Mon Sep 17 00:00:00 2001 From: Steven Huss-Lederman Date: Mon, 9 Dec 2024 18:27:09 -0600 Subject: [PATCH 4/4] comment fixes - Fix formatting. - uninstall node-cron so gone from package-lock.json --- package-lock.json | 32 --------------------- src/server/services/checkWebsiteStatus.js | 35 +++++++++++------------ 2 files changed, 17 insertions(+), 50 deletions(-) diff --git a/package-lock.json b/package-lock.json index 30f020e45..68bc1cd28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,6 @@ "bcryptjs": "~2.4.3", "body-parser": "~1.20.2", "bootstrap": "~5.3.3", - "colors": "~1.4.0", "csv": "~5.3.2", "csv-stringify": "~5.6.5", "d3": "~7.8.5", @@ -35,7 +34,6 @@ "multer": "~1.4.5-lts.1", "ngraph.graph": "~20.0.0", "ngraph.path": "~1.5.0", - "node-cron": "~3.0.3", "nodemailer": "~6.9.13", "pg": "~8.12.0", "pg-promise": "~11.8.0", @@ -2888,15 +2886,6 @@ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "license": "MIT", - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -7263,27 +7252,6 @@ "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", "dev": true }, - "node_modules/node-cron": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz", - "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==", - "license": "ISC", - "dependencies": { - "uuid": "8.3.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/node-cron/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/node-polyfill-webpack-plugin": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-1.1.4.tgz", diff --git a/src/server/services/checkWebsiteStatus.js b/src/server/services/checkWebsiteStatus.js index 144aa903f..3c63ad65f 100644 --- a/src/server/services/checkWebsiteStatus.js +++ b/src/server/services/checkWebsiteStatus.js @@ -2,23 +2,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - const { log } = require('../log'); - const WEBSITE_URL = process.argv[2]; - - async function checkWebsite() { - try { - const response = await fetch(WEBSITE_URL, { method: 'HEAD' }); - - if (!response.ok) { - const errorMessage = `The server at ${WEBSITE_URL} is down.`; - // Log the error using Logger class - log.error(errorMessage); - } - } catch (error) { - const errorMessage = `Failed to reach ${WEBSITE_URL}. Error: ${error.message}`; - log.error(errorMessage, error); +const { log } = require('../log'); +const WEBSITE_URL = process.argv[2]; + +async function checkWebsite() { + try { + const response = await fetch(WEBSITE_URL, { method: 'HEAD' }); + + if (!response.ok) { + const errorMessage = `The server at ${WEBSITE_URL} is down.`; + // Log the error using Logger class + log.error(errorMessage); } + } catch (error) { + const errorMessage = `Failed to reach ${WEBSITE_URL}. Error: ${error.message}`; + log.error(errorMessage, error); } - - checkWebsite(); - \ No newline at end of file +} + +checkWebsite();