From 9beb9ff0c73be6a05222a3107b303c8005a53382 Mon Sep 17 00:00:00 2001 From: MarcUs7 <96580944+MarcUs7i@users.noreply.github.com> Date: Fri, 27 Dec 2024 12:37:26 +0100 Subject: [PATCH] My Changes --- config.js | 148 ++++++++++++++++++++++++++++++++++++++++++--- static/index.html | 11 +--- static/status.json | 1 - watcher.js | 53 +++++++++------- 4 files changed, 172 insertions(+), 41 deletions(-) delete mode 100644 static/status.json diff --git a/config.js b/config.js index 5b013d6..0998188 100644 --- a/config.js +++ b/config.js @@ -1,8 +1,8 @@ export default { - interval : 15, // Interval in minutes between each pulse + interval : 1440, // Interval in minutes between each pulse; 1 day (24 * 60) nDataPoints : 90, // Number of datapoints to display on the dashboard - responseTimeGood : 300, // In milliseconds, this and below will be green - responseTimeWarning : 600, // In milliseconds, above this will be red + responseTimeGood : 500, // In milliseconds, this and below will be green + responseTimeWarning : 1000, // In milliseconds, above this will be red timeout : 5000, // In milliseconds, requests will be aborted above this verbose : true, // Whether or not to output pulse messages in the console readableStatusJson : true, // Format status.json to be human readable @@ -33,19 +33,149 @@ export default { consecutiveHighLatencyNotify : 3, // After how many consecutive High latency events should we send a notification sites : [ // List of sites to monitor { - id : 'google', // optional - name : 'Google', + id : 'marcus7i', // optional + name : 'MarcUs7i.Net', endpoints : [ // Each site is a bunch of endpoints that can be tested { id : 'homepage', // optional name : 'Homepage', // optional - link : 'https://www.google.com', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false - url : 'https://www.google.com', // required + link : 'https://marcus7i.net', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false + url : 'https://marcus7i.net', // required request : { // optional, fetch options method: 'GET', }, - mustFind : 'Feeling Lucky', // optional, String | Array | Regex | Function | AsyncFunction - mustNotFind : /Page not found/i, // optional, String | Array | Regex | Function | AsyncFunction + mustFind : 'MarcUs7i.Net', // optional, String | Array | Regex | Function | AsyncFunction + mustNotFind : ["Page not found", "Error", "cloudflare"], // optional, String | Array | Regex | Function | AsyncFunction + customCheck : async (content, response)=>{return true;}, // optional, Function | AsyncFunction -> Run your own custom checks return false in case of errors + validStatus : [200], // optional, Which http status should be considered non errors [defaults to 200-299] + }, + { + id : 'airin', // optional + name : 'Airin', // optional + link : 'https://airin.marcus7i.net', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false + url : 'https://airin.marcus7i.net', // required + request : { // optional, fetch options + method: 'GET', + }, + mustFind : 'Airin', // optional, String | Array | Regex | Function | AsyncFunction + mustNotFind : ["Page not found", "cloudflare"], // optional, String | Array | Regex | Function | AsyncFunction + customCheck : async (content, response)=>{return true;}, // optional, Function | AsyncFunction -> Run your own custom checks return false in case of errors + validStatus : [200], // optional, Which http status should be considered non errors [defaults to 200-299] + }, + { + id : 'anywave', // optional + name : 'Anywave', // optional + link : 'https://anywave.marcus7i.net', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false + url : 'https://anywave.marcus7i.net', // required + request : { // optional, fetch options + method: 'GET', + }, + mustFind : 'Anywave', // optional, String | Array | Regex | Function | AsyncFunction + mustNotFind : ["Page not found", "cloudflare"], // optional, String | Array | Regex | Function | AsyncFunction + customCheck : async (content, response)=>{return true;}, // optional, Function | AsyncFunction -> Run your own custom checks return false in case of errors + validStatus : [200], // optional, Which http status should be considered non errors [defaults to 200-299] + }, + { + id : 'btcnd', // optional + name : 'Bitcoin Node', // optional + link : 'https://btcnd.marcus7i.net', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false + url : 'https://btcnd.marcus7i.net', // required + request : { // optional, fetch options + method: 'GET', + }, + mustFind : 'Anywave', // optional, String | Array | Regex | Function | AsyncFunction + mustNotFind : ["Page not found", "cloudflare"], // optional, String | Array | Regex | Function | AsyncFunction + customCheck : async (content, response)=>{return true;}, // optional, Function | AsyncFunction -> Run your own custom checks return false in case of errors + validStatus : [200, 520], // optional, Which http status should be considered non errors [defaults to 200-299] + }, + { + id : 'fs', // optional + name : 'File Sharing', // optional + link : 'https://fs.marcus7i.net', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false + url : 'https://fs.marcus7i.net', // required + request : { // optional, fetch options + method: 'GET', + }, + mustFind : 'nginx', // optional, String | Array | Regex | Function | AsyncFunction + mustNotFind : ["Page not found", "cloudflare"], // optional, String | Array | Regex | Function | AsyncFunction + customCheck : async (content, response)=>{return true;}, // optional, Function | AsyncFunction -> Run your own custom checks return false in case of errors + validStatus : [200, 403], // optional, Which http status should be considered non errors [defaults to 200-299] + }, + { + id : 'git', // optional + name : 'MarcUs7i Git', // optional + link : 'https://git.marcus7i.net', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false + url : 'https://git.marcus7i.net', // required + request : { // optional, fetch options + method: 'GET', + }, + mustFind : 'Home', // optional, String | Array | Regex | Function | AsyncFunction + mustNotFind : ["Page not found", "cloudflare"], // optional, String | Array | Regex | Function | AsyncFunction + customCheck : async (content, response)=>{return true;}, // optional, Function | AsyncFunction -> Run your own custom checks return false in case of errors + validStatus : [200], // optional, Which http status should be considered non errors [defaults to 200-299] + }, + { + id : 'ollama', // optional + name : 'Ollama Webui', // optional + link : 'https://ollama.marcus7i.net', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false + url : 'https://ollama.marcus7i.net', // required + request : { // optional, fetch options + method: 'GET', + }, + mustFind : '', // optional, String | Array | Regex | Function | AsyncFunction + mustNotFind : ["Page not found", "cloudflare"], // optional, String | Array | Regex | Function | AsyncFunction + customCheck : async (content, response)=>{return true;}, // optional, Function | AsyncFunction -> Run your own custom checks return false in case of errors + validStatus : [200], // optional, Which http status should be considered non errors [defaults to 200-299] + }, + { + id : 'ollama-api', // optional + name : 'Ollama API', // optional + link : 'https://ollama.marcus7i.net/api/chat/completions', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false + url : 'https://ollama.marcus7i.net/api/chat/completions', // required + request : { // optional, fetch options + method: 'POST', + }, + mustFind : '{\"detail\":\"Not authenticated\"}', // optional, String | Array | Regex | Function | AsyncFunction + mustNotFind : ["Page not found", "cloudflare"], // optional, String | Array | Regex | Function | AsyncFunction + customCheck : async (content, response)=>{return true;}, // optional, Function | AsyncFunction -> Run your own custom checks return false in case of errors + validStatus : [200, 401], // optional, Which http status should be considered non errors [defaults to 200-299] + }, + { + id : 'sd', // optional + name : 'Stable Diffusion API', // optional + link : 'https://sd.marcus7i.net', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false + url : 'https://sd.marcus7i.net', // required + request : { // optional, fetch options + method: 'GET', + }, + mustFind : 'Login', // optional, String | Array | Regex | Function | AsyncFunction + mustNotFind : ["Page not found", "cloudflare"], // optional, String | Array | Regex | Function | AsyncFunction + customCheck : async (content, response)=>{return true;}, // optional, Function | AsyncFunction -> Run your own custom checks return false in case of errors + validStatus : [200], // optional, Which http status should be considered non errors [defaults to 200-299] + }, + { + id : 'u', // optional + name : 'Link shortener', // optional + link : 'https://u.marcus7i.net', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false + url : 'https://u.marcus7i.net', // required + request : { // optional, fetch options + method: 'GET', + }, + mustFind : '', // optional, String | Array | Regex | Function | AsyncFunction + mustNotFind : ["Page not found", "cloudflare"], // optional, String | Array | Regex | Function | AsyncFunction + customCheck : async (content, response)=>{return true;}, // optional, Function | AsyncFunction -> Run your own custom checks return false in case of errors + validStatus : [200], // optional, Which http status should be considered non errors [defaults to 200-299] + }, + { + id : 'xmrnd', // optional + name : 'Monero Node', // optional + link : 'https://xmrnd.marcus7i.net', // optional, for notifications and dashboard only, [defaults to endpoint.url], can be disabled by setting it to false + url : 'https://xmrnd.marcus7i.net', // required + request : { // optional, fetch options + method: 'GET', + }, + mustFind : '', // optional, String | Array | Regex | Function | AsyncFunction + mustNotFind : ["Page not found", "cloudflare"], // optional, String | Array | Regex | Function | AsyncFunction customCheck : async (content, response)=>{return true;}, // optional, Function | AsyncFunction -> Run your own custom checks return false in case of errors validStatus : [200], // optional, Which http status should be considered non errors [defaults to 200-299] } diff --git a/static/index.html b/static/index.html index dc76964..4b26384 100644 --- a/static/index.html +++ b/static/index.html @@ -1,7 +1,7 @@ - aPulse — Server Status + MarcUs7i - Status @@ -14,16 +14,9 @@
-

aPulseaPulse

+

MarcUs7i - StatusMarcUs7i - Status

- -
- Follow @ybouane - -
\ No newline at end of file diff --git a/static/status.json b/static/status.json deleted file mode 100644 index 9e26dfe..0000000 --- a/static/status.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/watcher.js b/watcher.js index 658393f..f31e820 100644 --- a/watcher.js +++ b/watcher.js @@ -43,18 +43,17 @@ const sendTelegramMessage = async (text) => { return await response.json(); }; const sendDiscordMessage = async (text) => { - const webhookUrl = 'YOUR_DISCORD_WEBHOOK_URL'; - const response = await fetch(config.discord.webhookUrl, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - content: text - }) - }); - if (!response.ok) { - throw new Error(`[Discord] Failed to send message: ${response.statusText}`); + try { + const response = await fetch(config.discord.webhookUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ content: text }) + }); + const data = await response.json(); + return data; + } catch (error) { + console.error('Error sending Discord message:', error); } - return await response.json(); }; const sendSMSMessage = async (text) => { const response = await fetch(`https://api.twilio.com/2010-04-01/Accounts/${config.twilio.accountSid}/Messages.json`, { @@ -112,16 +111,20 @@ const sendEmailMessage = async (text) => { return await response.json(); }; const sendNotification = async (message) => { - if(config.telegram?.botToken && config.telegram?.chatId) - await sendTelegramMessage(message); - if(config.slack?.botToken && config.slack?.channelId) - await sendSlackMessage(message); - if(config.discord?.webhookUrl) - await sendDiscordMessage(message); - if(config.twilio?.accountSid && config.twilio?.accountToken && config.twilio?.toNumber && config.twilio?.twilioNumber) - await sendSMSMessage(message); - if(config.sendgrid?.apiKey && config.sendgrid?.toEmail && config.sendgrid?.toFromEmail) - await sendEmailMessage(message); + try { + if(config.telegram?.botToken && config.telegram?.chatId) + await sendTelegramMessage(message); + if(config.slack?.botToken && config.slack?.channelId) + await sendSlackMessage(message); + if(config.discord?.webhookUrl) + await sendDiscordMessage(message); + if(config.twilio?.accountSid && config.twilio?.accountToken && config.twilio?.toNumber && config.twilio?.twilioNumber) + await sendSMSMessage(message); + if(config.sendgrid?.apiKey && config.sendgrid?.toEmail && config.sendgrid?.toFromEmail) + await sendEmailMessage(message); + } catch (error) { + console.error('Error sending notification:', error); + } } while(true) { @@ -131,7 +134,13 @@ while(true) { try { try { status = JSON.parse((await fs.readFile(statusFile)).toString()); // We re-read the file each time in case it was manually modified. - } catch(e) {console.error(`Could not find status.json file [${statusFile}], will create it.`)} + } catch(e) { + if (e instanceof SyntaxError) { + console.error(`Syntax error in status.json file [${statusFile}]:`, e); + } else { + console.error(`Could not find status.json file [${statusFile}], will create it.`); + } + } status = status || {}; status.sites = status.sites || {}; status.config = {