diff --git a/db/patch-add-monitor-checks-table.sql b/db/patch-add-monitor-checks-table.sql index d43f6b6..de821f4 100644 --- a/db/patch-add-monitor-checks-table.sql +++ b/db/patch-add-monitor-checks-table.sql @@ -50,11 +50,12 @@ create table monitor_dg_tmp maxredirects INTEGER default 10 not null, dns_resolve_type VARCHAR(5), dns_resolve_server VARCHAR(255), - dns_last_result VARCHAR(255) + dns_last_result VARCHAR(255), + retry_interval INTEGER default 0 not null ); insert into monitor_dg_tmp(id, name, active, user_id, interval, url, type, weight, hostname, port, created_date, maxretries, ignore_tls, upside_down, - maxredirects, dns_resolve_type, dns_resolve_server, dns_last_result) + maxredirects, dns_resolve_type, dns_resolve_server, dns_last_result, retry_interval) select id, name, active, @@ -72,7 +73,8 @@ select id, maxredirects, dns_resolve_type, dns_resolve_server, - dns_last_result + dns_last_result, + retry_interval from monitor; drop table monitor; diff --git a/server/model/monitor.js b/server/model/monitor.js index ae43b09..1acbda0 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -6,7 +6,7 @@ dayjs.extend(utc); dayjs.extend(timezone); const axios = require("axios"); const { Prometheus } = require("../prometheus"); -const { debug, UP, DOWN, PENDING, flipStatus, TimeLogger, MONITOR_CHECK_SELECTOR_TYPES, HTTP_STATUS_CODE_SHOULD_EQUAL } = require("../../src/util"); +const { debug, UP, DOWN, PENDING, flipStatus, TimeLogger, MONITOR_CHECK_SELECTOR_TYPES } = require("../../src/util"); const { tcping, ping, dnsResolve, checkCertificate, getTotalClientInRoom } = require("../util-server"); const { R } = require("redbean-node"); const { BeanModel } = require("redbean-node/dist/bean-model"); @@ -537,7 +537,7 @@ class Monitor extends BeanModel { if (MONITOR_CHECK_SELECTOR_TYPES.includes(check.type) && typeof check.value === "string" && check.value.startsWith("{")) { check.value = JSON.parse(check.value); } - if (check.type === HTTP_STATUS_CODE_SHOULD_EQUAL && typeof check.value === "string" && check.value.startsWith("[")) { + if (check.type === "HTTP_STATUS_CODE_SHOULD_EQUAL" && typeof check.value === "string" && check.value.startsWith("[")) { check.value = JSON.parse(check.value); } }); diff --git a/server/server.js b/server/server.js index 5b82263..9fed769 100644 --- a/server/server.js +++ b/server/server.js @@ -6,10 +6,7 @@ if (!process.env.NODE_ENV) { console.log("Node Env: " + process.env.NODE_ENV); -const { sleep, debug, getRandomInt, genSecret, - HTTP_STATUS_CODE_SHOULD_EQUAL, - RESPONSE_SHOULD_CONTAIN_TEXT -} = require("../src/util"); +const { sleep, debug, getRandomInt, genSecret } = require("../src/util"); console.log("Importing Node libraries"); const fs = require("fs"); @@ -1062,19 +1059,19 @@ exports.entryPage = "dashboard"; // --- End --- let monitor = { - name: monitorList[i].name, - type: monitorList[i].type, - url: monitorList[i].url, - interval: monitorList[i].interval, - hostname: monitorList[i].hostname, - maxretries: monitorList[i].maxretries, - port: monitorList[i].port, - ignoreTls: monitorList[i].ignoreTls, - upsideDown: monitorList[i].upsideDown, - maxredirects: monitorList[i].maxredirects, - checks: monitorList[i].checks, - dns_resolve_type: monitorList[i].dns_resolve_type, - dns_resolve_server: monitorList[i].dns_resolve_server, + name: monitorListData[i].name, + type: monitorListData[i].type, + url: monitorListData[i].url, + interval: monitorListData[i].interval, + hostname: monitorListData[i].hostname, + maxretries: monitorListData[i].maxretries, + port: monitorListData[i].port, + ignoreTls: monitorListData[i].ignoreTls, + upsideDown: monitorListData[i].upsideDown, + maxredirects: monitorListData[i].maxredirects, + checks: monitorListData[i].checks, + dns_resolve_type: monitorListData[i].dns_resolve_type, + dns_resolve_server: monitorListData[i].dns_resolve_server, notificationIDList: {}, }; @@ -1085,35 +1082,29 @@ exports.entryPage = "dashboard"; // TODO remove this if clause once we no longer expect export files to contain the old accepted_statuscodes and keyword format if (monitor.type === "http" || monitor.type === "keyword") { - if (monitor.accepted_statuscodes) { + if (monitorListData[i].accepted_statuscodes) { // old format for checking http status codes // Convert to new format which uses separate monitor check monitor.checks = monitor.checks || []; monitor.checks.push({ - monitor_id: monitor.id, - type: HTTP_STATUS_CODE_SHOULD_EQUAL, - value: monitor.accepted_statuscodes, + type: "HTTP_STATUS_CODE_SHOULD_EQUAL", + value: monitorListData[i].accepted_statuscodes, }); } - if (monitor.keyword) { + if (monitorListData[i].keyword) { // old format for checking response contains keyword // Convert to new format which uses separate monitor check monitor.checks = monitor.checks || []; monitor.checks.push({ - monitor_id: monitor.id, - type: RESPONSE_SHOULD_CONTAIN_TEXT, - value: monitor.keyword, + type: "RESPONSE_SHOULD_CONTAIN_TEXT", + value: monitorListData[i].keyword, }); } monitor.type = "http"; - delete monitor.accepted_statuscodes; - delete monitor.keyword; } - monitor.checks_json = JSON.stringify(monitor.checks); - const checks = monitor.checks; delete monitor.checks; diff --git a/server/util-server.js b/server/util-server.js index 0cd1e2b..a0d12f0 100644 --- a/server/util-server.js +++ b/server/util-server.js @@ -293,17 +293,18 @@ exports.updateMonitorChecks = async (monitorId, checks) => { let trx = await R.begin(); try { // delete existing checks for monitor - const existingMonitorChecks = await R.find("monitor_checks", " monitor_id = ?", [bean.id]); - await trx.trashAll(existingMonitorChecks); + await trx.exec("DELETE FROM monitor_checks WHERE monitor_id = ?", [monitorId]); // Replace them with new checks for (let i = 0; i < (checks || []).length; i++) { let checkBean = trx.dispense("monitor_checks"); - checks[i].monitor_id = monitorId; - checks[i].value = typeof checks[i].value === "object" ? JSON.stringify(checks[i].value) : checks[i].value; - checkBean.import(checks[i]); + checkBean.monitor_id = monitorId; + checkBean.type = checks[i].type; + checkBean.value = typeof checks[i].value === "object" ? JSON.stringify(checks[i].value) : checks[i].value; await trx.store(checkBean); } + + await trx.commit(); } catch (err) { await trx.rollback(); throw err; diff --git a/src/util.ts b/src/util.ts index 36a2041..1fc1767 100644 --- a/src/util.ts +++ b/src/util.ts @@ -19,6 +19,7 @@ export const STATUS_PAGE_ALL_DOWN = 0; export const STATUS_PAGE_ALL_UP = 1; export const STATUS_PAGE_PARTIAL_DOWN = 2; +// Monitor check types export const HTTP_STATUS_CODE_SHOULD_EQUAL = "HTTP_STATUS_CODE_SHOULD_EQUAL"; export const RESPONSE_SHOULD_CONTAIN_TEXT = "RESPONSE_SHOULD_CONTAIN_TEXT"; export const RESPONSE_SHOULD_NOT_CONTAIN_TEXT = "RESPONSE_SHOULD_NOT_CONTAIN_TEXT"; @@ -29,8 +30,8 @@ export const RESPONSE_SELECTOR_SHOULD_NOT_EQUAL = "RESPONSE_SELECTOR_SHOULD_NOT_ export const RESPONSE_SELECTOR_SHOULD_MATCH_REGEX = "RESPONSE_SELECTOR_SHOULD_MATCH_REGEX"; export const RESPONSE_SELECTOR_SHOULD_NOT_MATCH_REGEX = "RESPONSE_SELECTOR_SHOULD_NOT_MATCH_REGEX"; -export const MONITOR_CHECK_STRING_TYPES = ["RESPONSE_SHOULD_CONTAIN_TEXT", "RESPONSE_SHOULD_NOT_CONTAIN_TEXT", "RESPONSE_SHOULD_MATCH_REGEX", "RESPONSE_SHOULD_NOT_MATCH_REGEX"]; -export const MONITOR_CHECK_SELECTOR_TYPES = ["RESPONSE_SELECTOR_SHOULD_EQUAL", "RESPONSE_SELECTOR_SHOULD_NOT_EQUAL", "RESPONSE_SELECTOR_SHOULD_MATCH_REGEX", "RESPONSE_SELECTOR_SHOULD_NOT_MATCH_REGEX"]; +export const MONITOR_CHECK_STRING_TYPES = [RESPONSE_SHOULD_CONTAIN_TEXT, RESPONSE_SHOULD_NOT_CONTAIN_TEXT, RESPONSE_SHOULD_MATCH_REGEX, RESPONSE_SHOULD_NOT_MATCH_REGEX]; +export const MONITOR_CHECK_SELECTOR_TYPES = [RESPONSE_SELECTOR_SHOULD_EQUAL, RESPONSE_SELECTOR_SHOULD_NOT_EQUAL, RESPONSE_SELECTOR_SHOULD_MATCH_REGEX, RESPONSE_SELECTOR_SHOULD_NOT_MATCH_REGEX]; export function flipStatus(s: number) { if (s === UP) {