From a8b102ad4a0f8a146af04fd12e17adce7ff3662f Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 19 Jul 2021 18:23:06 +0200 Subject: [PATCH 01/13] add retries for pinging function backend: - new field for monitor: maxretries - new pending status while service is retrying: 2 - pending status event is not marked important - pending pings however register as downtime in the calculation frontend: - added pending status while service is retrying - added color for new pending status - added field to configure amount of retries database: - IMPORTANT: THIS REQUIRES MIGRATION!!!! - added field: maxretries with default value 0 --- .gitignore | 1 + db/kuma.db | Bin 57344 -> 61440 bytes server/model/monitor.js | 15 +++++++++++---- server/server.js | 1 + src/assets/vars.scss | 3 ++- src/components/HeartbeatBar.vue | 6 +++++- src/components/Status.vue | 6 +++++- src/components/Uptime.vue | 2 ++ src/mixins/socket.js | 5 +++++ src/pages/DashboardHome.vue | 2 ++ src/pages/EditMonitor.vue | 8 +++++++- 11 files changed, 41 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 8d435974f..9caa313cb 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ dist-ssr /data !/data/.gitkeep +.vscode \ No newline at end of file diff --git a/db/kuma.db b/db/kuma.db index 07c93cf89abb94bac751a47894d5e0fff94aa17b..6e02ccc01fefc1d40029c18cbec08a6039cf723f 100644 GIT binary patch delta 1162 zcmd^9y>Hq;6t}@OU}Bu8Qcy*tT&yYrDQbX-p;K|;NZlHP%uyv1a>6Nb%U6s`5_KR$ zrHn0N>d=L?Q-!+s&*+%{phK8Cl-?O5l4k1Asgj?q`@PS5zxRCc&3|#_{}5YI7>1FE zh(uT-qruirLSY^~`7ZKPM&wi`(u+J4{o=LoShx=51Czj~fXX9IUHaY7oeG^fHJGA=#?SAyr3k7aBk> zA)r?^ZHwS7vx()?}&j!-7)P5J)GJN$Pam?mD+iN@p@|MV+?2 z@S~=OHZ~nxuhq$$WKF3>SV2m$Om(mE`DxoGSDs&N9;IoX+1Rly+;yvd(5G3;hFVmN zeeeSA$7!R0Qbi?ICw(nK9ntKCk^$9SeP%K5MFJSG01c?;U zpSiHiJRkc5>l_zZV~69-@O!qXNqm$rcw)8c_{^INk1F0JAKg!3n&4G7P+IAq;$Fd@8)myq~$1xGcFo zbGop9VV}$H$@ZTuWV4{aIo8P`Y^zy3c-X`@GqcOHur$Z9vTs)7?q{6*fs@U>Ait<2 zR>9LR#MRw3NJoK}OFI1xUs!gn0V828THM20&%AQ!C5!i&A10!W@H~ zJsg8Hj7&{6H#6}v39~T>Ffi~x-^``(fL~0Kv$Qz12 { console.log(`Monitor ${this.id}: Heartbeat`) @@ -109,12 +110,18 @@ class Monitor extends BeanModel { bean.status = 1; } + retries = 0; + } catch (error) { + if ((this.maxretries > 0) && (retries < this.maxretries)) { + retries++; + bean.status = 2; + } bean.msg = error.message; } - // Mark as important if status changed - if (! previousBeat || previousBeat.status !== bean.status) { + // Mark as important if status changed, ignore pending pings + if ((! previousBeat || previousBeat.status !== bean.status) && bean.status !== 2) { bean.important = true; // Do not send if first beat is UP @@ -233,7 +240,7 @@ class Monitor extends BeanModel { } total += value; - if (row.status === 0) { + if (row.status === 0 || row.status === 2) { downtime += value; } } diff --git a/server/server.js b/server/server.js index bd5894775..567ff490c 100644 --- a/server/server.js +++ b/server/server.js @@ -219,6 +219,7 @@ let needSetup = false; bean.url = monitor.url bean.interval = monitor.interval bean.hostname = monitor.hostname; + bean.maxretries = monitor.maxretries; bean.port = monitor.port; bean.keyword = monitor.keyword; diff --git a/src/assets/vars.scss b/src/assets/vars.scss index 31b0262d8..ebec378a5 100644 --- a/src/assets/vars.scss +++ b/src/assets/vars.scss @@ -1,7 +1,8 @@ $primary: #5CDD8B; $danger: #DC3545; +$warning: #f8a306; $link-color: #111; $border-radius: 50rem; $highlight: #7ce8a4; -$highlight-white: #e7faec; +$highlight-white: #e7faec; \ No newline at end of file diff --git a/src/components/HeartbeatBar.vue b/src/components/HeartbeatBar.vue index 48ffd2926..03cdceca6 100644 --- a/src/components/HeartbeatBar.vue +++ b/src/components/HeartbeatBar.vue @@ -3,7 +3,7 @@
span { - width: 45px; + width: 54px; } diff --git a/src/components/Uptime.vue b/src/components/Uptime.vue index ad8114fcb..322b35f70 100644 --- a/src/components/Uptime.vue +++ b/src/components/Uptime.vue @@ -30,6 +30,8 @@ export default { return "danger" } else if (this.lastHeartBeat.status === 1) { return "primary" + } else if (this.lastHeartBeat.status === 2) { + return "warning" } else { return "secondary" } diff --git a/src/mixins/socket.js b/src/mixins/socket.js index f0a3b1a6a..42de1eb3f 100644 --- a/src/mixins/socket.js +++ b/src/mixins/socket.js @@ -274,6 +274,11 @@ export default { text: "Down", color: "danger" }; + } else if (lastHeartBeat.status === 2) { + result[monitorID] = { + text: "Pending", + color: "warning" + }; } else { result[monitorID] = unknown; } diff --git a/src/pages/DashboardHome.vue b/src/pages/DashboardHome.vue index 820842bac..87380c7c2 100644 --- a/src/pages/DashboardHome.vue +++ b/src/pages/DashboardHome.vue @@ -90,6 +90,8 @@ export default { result.up++; } else if (beat.status === 0) { result.down++; + } else if (beat.status === 2) { + result.up++; } else { result.unknown++; } diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index 01af50610..e4898c33d 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -48,6 +48,11 @@
+
+ + +
+
@@ -61,7 +66,7 @@

Notifications

Not available, please setup.

-
+
-
+
From 14e1d1f1057854ae7217a3028bca73aaf5da378e Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 20 Jul 2021 17:39:21 +0200 Subject: [PATCH 04/13] add .vscode directory to dockerignore --- .dockerignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.dockerignore b/.dockerignore index d439b2db5..825d58038 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,3 +11,4 @@ LICENSE README.md .editorconfig +.vscode From 32a5e838bab12dba60b825c3155344abcbef8579 Mon Sep 17 00:00:00 2001 From: LouisLam Date: Thu, 22 Jul 2021 17:44:59 +0800 Subject: [PATCH 05/13] add patch3.sql and fix duplicate id in EditMonitor.vue --- db/patch3.sql | 37 +++++++++++++++++++++++++++++++++++++ src/pages/EditMonitor.vue | 4 ++-- 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 db/patch3.sql diff --git a/db/patch3.sql b/db/patch3.sql new file mode 100644 index 000000000..e615632f9 --- /dev/null +++ b/db/patch3.sql @@ -0,0 +1,37 @@ +-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. +-- Add maxretries column to monitor +PRAGMA foreign_keys=off; + +BEGIN TRANSACTION; + +create table monitor_dg_tmp +( + id INTEGER not null + primary key autoincrement, + name VARCHAR(150), + active BOOLEAN default 1 not null, + user_id INTEGER + references user + on update cascade on delete set null, + interval INTEGER default 20 not null, + url TEXT, + type VARCHAR(20), + weight INTEGER default 2000, + hostname VARCHAR(255), + port INTEGER, + created_date DATETIME, + keyword VARCHAR(255), + maxretries INTEGER NOT NULL DEFAULT 0 +); + +insert into monitor_dg_tmp(id, name, active, user_id, interval, url, type, weight, hostname, port, created_date, keyword) select id, name, active, user_id, interval, url, type, weight, hostname, port, created_date, keyword from monitor; + +drop table monitor; + +alter table monitor_dg_tmp rename to monitor; + +create index user_id on monitor (user_id); + +COMMIT; + +PRAGMA foreign_keys=on; diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index f5d71703a..69cd41625 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -49,8 +49,8 @@
- - + +
From 70b1f197c1a71d78e1c8b05a8269ef42e8264e8a Mon Sep 17 00:00:00 2001 From: LouisLam Date: Thu, 22 Jul 2021 19:02:44 +0800 Subject: [PATCH 06/13] rename "Retry Pings" to "Retries" --- src/pages/EditMonitor.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index 69cd41625..03fa66e95 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -49,8 +49,9 @@
- + +
Maximum retries before the service is marked as down and send notifications
From 5a219554b30322cce5620e75aa67b8199d04f10c Mon Sep 17 00:00:00 2001 From: LouisLam Date: Thu, 22 Jul 2021 19:49:46 +0800 Subject: [PATCH 07/13] grammar --- src/pages/EditMonitor.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue index 03fa66e95..75d7d4b9b 100644 --- a/src/pages/EditMonitor.vue +++ b/src/pages/EditMonitor.vue @@ -51,7 +51,7 @@
-
Maximum retries before the service is marked as down and send notifications
+
Maximum retries before the service is marked as down and a notification is sent
From b7a32d4ab6ffde5cb36152a82715963eeefcc07f Mon Sep 17 00:00:00 2001 From: Niyas Date: Thu, 22 Jul 2021 19:26:54 +0530 Subject: [PATCH 08/13] Pushover enhancements --- server/notification.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/notification.js b/server/notification.js index 3c0e9f2a4..9da8a0dc8 100644 --- a/server/notification.js +++ b/server/notification.js @@ -204,7 +204,7 @@ class Notification { } let data = { - "message": "Uptime Kuma Alert\n\nMessage:" +msg + '\nTime (UTC):' +time, + "message": "Uptime Kuma Alert\n\nMessage:"+msg+ '\nTime (UTC):' +heartbeatJSON["time"], "user":notification.pushoveruserkey, "token": notification.pushoverapptoken, "sound": notification.pushoversounds, From 77fbfc23be9a3bf16a861c755f82ccd545745bc0 Mon Sep 17 00:00:00 2001 From: Niyas Date: Thu, 22 Jul 2021 19:28:25 +0530 Subject: [PATCH 09/13] Pushover enhancements --- src/components/NotificationDialog.vue | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue index 6df8b9566..afbfc0d4e 100644 --- a/src/components/NotificationDialog.vue +++ b/src/components/NotificationDialog.vue @@ -223,16 +223,22 @@
From 1d4d7fa9c4c9626f4451fe7449171669ad8a808a Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 22 Jul 2021 20:25:03 +0200 Subject: [PATCH 10/13] fix parenthesis mistake --- server/model/monitor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/model/monitor.js b/server/model/monitor.js index 2479688ac..1beaa5475 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -120,7 +120,7 @@ class Monitor extends BeanModel { // Mark as important if status changed, ignore pending pings, // Don't notify if disrupted changes to up - if ((! previousBeat || previousBeat.status !== bean.status) && bean.status !== 2 && !(previousBeat.status === 2 && bean.status !== 0)) { + if ((!previousBeat) || ((previousBeat.status !== bean.status) && bean.status !== 2 && !(previousBeat.status === 2 && bean.status !== 0))) { bean.important = true; // Do not send if first beat is UP From 2450b3d08234e03a6c9a2f0fedf1be3303d0c3c1 Mon Sep 17 00:00:00 2001 From: rezzorix <72935517+rezzorix@users.noreply.github.com> Date: Fri, 23 Jul 2021 11:48:39 +0800 Subject: [PATCH 11/13] Small grammar updates to Settings.vue Just small grammar corrections. --- src/pages/Settings.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Settings.vue b/src/pages/Settings.vue index daa521981..f4bf156a8 100644 --- a/src/pages/Settings.vue +++ b/src/pages/Settings.vue @@ -36,7 +36,7 @@
- The repeat password is not match. + The repeat password does not match.
@@ -56,7 +56,7 @@

Notifications

Not available, please setup.

-

Please assign the notification to monitor(s) to get it works.

+

Please assign a notification to monitor(s) to get it to work.

  • From 280ba84acae766948ab77183341ededa643c1a48 Mon Sep 17 00:00:00 2001 From: rezzorix <72935517+rezzorix@users.noreply.github.com> Date: Fri, 23 Jul 2021 12:41:02 +0800 Subject: [PATCH 12/13] Apple touch icon 192px with preserved transparency Resized icon.png to 192px but preserved transparency --- public/apple-touch-icon.png | Bin 4086 -> 2582 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png index 3bb82e4c9aa30a7291fa98c89153785d909f97f3..0e9c109f33c926aad9c43ecd3d97db907e24c522 100644 GIT binary patch literal 2582 zcmX|DdpOhkAOCLVerb{WZ6d9l2)RTVwJ|D5w?k>D+(S6IoO9ajVSvi){b^cG2tb37mqBC7;iikW41?`}gn5{{@f7<8rx@agN88sFDx}1e3g3 z3G65Gnk$^w5$qDtUT=g;~RO4Oh5{o;g#8C)2bz+Udi_|nw>{hi!*kJxQ5 z=X-`1Kh?~2Je%v3NY(7uuQ&s*IYa#mV~z8DEu8)d9!s(-S#09;Nen#;BUJ9t^SQ1r z?uV|$5A6$YTR8*m+_(LUW3_X1DtEA+)BASu^T;Bjl{?VLc~dbcMXZ_nd^^ViX!A0Y6M8x}~H*2hbLd^FxC76260ek2UITdXA^W#inB z;AB~{nuu){&u))&0)X63cdW~agz<%vp2#T=E!WC|Z5rKX7$CC`UhJv_+u`9{9~va3 z=$f);kGq3>!0uF`sHQpURx17dS!X}dne(wK24T^n?MU8qSFR!EDk$7r1JvLZ&9h`t z8Si<)vjE%JZeuSRFt||!#VL@&O}a2maHMJvKersfy2gOUS^)os9-#tef9k@l=6N7T zXG|nA15ouaAVwEJ)xqq2F3irJ2S}e~0DL51Vh1=!N{w46r#{k5GPCG@K!$J&RhEV5sU;sZ0zdJl%V*`UOe?f(d!)~@Kd-a9a554L5+w0F4gQ$Lmy z;C$sP)=FN@;*uTCPd&={>F*0x!FLg0r0PG_{xCS0)!^RCh}@%kry4H>`kl`D*Zmh{ zc!Rsi$pD$rb!ERhFTlvA#3OmI#kwlHUxi<0wjMz2UaizIHKzV19h=gSaDwx4K5KQGsif465i8KNX3Omok>h zw_K5mTQAs5XDo60;B5UF>E+eS;}=|$!_J_HREna!hF7zmP*+xT=CN6}JCF#|B1=a2 zJ0s^yRf@Awb+6&lwaR?(aj{1f$syU{1ZcSxI#pGct~!*oH|CbU@B_F#z6|Jdp!e_l(ak(A1jVbT<(e&74`2f00NDxJ&SFK4t<*EU)Hk$kkN}sY?O|17m&+EK$Lor;p3EOfNGqO6p1*LPxI+md4yx6K&tjlTMjb`(Xn|I1ZYl$IuPvyevDb) zPD}B62-7MTg|>hxUzWczGAL~UZ#rz(N(eDvr9>ZwFIll#_eTU)WfNxafe=6|fI+J{hLtC7^z#Ge#; zG5A=d*VNEVpPUQeR4c&d}up*zDi%hQ*qkGKrQl0>{Xi>Q#C`gPi z6#te+EPbwsEj7CxaSCdbo)&AX8$I1Xj6%tFfMYj?&@LoS>;$E+-1Gk=l)^_rjZ)L% z3_BB4lgt$g?aV<}NVLuXzwLr_&K-1)(Oe6cPTpHKMO>euSU4ad-y;__hDsNO zCwvKA!A0+cd{fd$Bm1?9yWSiGZlOh4TfjT|P(B@pirES2P{#aLo#M7aI?!Jp9o|wA zkdwUFER(urMsQs|gnyIw@olj|eq$OSP*;5gZYwAv1?KVV@gi9R(B^^7`}9Fq)dRv- zhauvci%Sl?)Oke#*aZ1ryJonfl!X@VKaFHA6OI2+m;T0&SZx696oO%1?s^3jFvY4Y z`6?FLv)1aBxr+XFo?rMVL`w&jx2T_jsd>vguZ_*T1T;i@NcRSbw0rtJ2+Dzw5}h{ z!Xt-LqWY%?A{Ij}M zAKul;JYl98>Nn{2aQJ}HU25a-yTZvZ+p;jy(F^GOUQ=XV2?pgT_R;M=Zgx9E9HBh( z=wn|8@o$;s4}C#X7)PnSoWGwlDFx)d&S}`0jf63gcoXqHGEYxjrT}5)ioINx#qIg) zhCOh&v0ZCI8tukbn-*jmEp)53qh=OOgbj>?7m)sY)A`d~gJUeh9d4C^9Nv3Y@{s`C Mah}*G2mHzZ0~dTv1ONa4 delta 4089 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 From d556509d079aab93467a4ef188f4e54acb9ccfbb Mon Sep 17 00:00:00 2001 From: LouisLam Date: Sat, 24 Jul 2021 11:42:14 +0800 Subject: [PATCH 13/13] =?UTF-8?q?=E6=88=88mprove=20the=20readibility=20of?= =?UTF-8?q?=20important=20condition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/model/monitor.js | 45 ++++++++++++++++++++++++++++++----------- server/util.js | 4 ++++ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/server/model/monitor.js b/server/model/monitor.js index 1beaa5475..133088671 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -5,6 +5,7 @@ var timezone = require('dayjs/plugin/timezone') dayjs.extend(utc) dayjs.extend(timezone) const axios = require("axios"); +const {UP, DOWN, PENDING} = require("../util"); const {tcping, ping} = require("../util-server"); const {R} = require("redbean-node"); const {BeanModel} = require("redbean-node/dist/bean-model"); @@ -49,19 +50,22 @@ class Monitor extends BeanModel { let retries = 0; const beat = async () => { + if (! previousBeat) { previousBeat = await R.findOne("heartbeat", " monitor_id = ? ORDER BY time DESC", [ this.id ]) } + const isFirstBeat = !previousBeat; + let bean = R.dispense("heartbeat") bean.monitor_id = this.id; bean.time = R.isoDateTime(dayjs.utc()); - bean.status = 0; + bean.status = DOWN; // Duration - if (previousBeat) { + if (! isFirstBeat) { bean.duration = dayjs(bean.time).diff(dayjs(previousBeat.time), 'second'); } else { bean.duration = 0; @@ -77,7 +81,7 @@ class Monitor extends BeanModel { bean.ping = dayjs().valueOf() - startTime; if (this.type === "http") { - bean.status = 1; + bean.status = UP; } else { let data = res.data; @@ -89,7 +93,7 @@ class Monitor extends BeanModel { if (data.includes(this.keyword)) { bean.msg += ", keyword is found" - bean.status = 1; + bean.status = UP; } else { throw new Error(bean.msg + ", but keyword is not found") } @@ -100,12 +104,12 @@ class Monitor extends BeanModel { } else if (this.type === "port") { bean.ping = await tcping(this.hostname, this.port); bean.msg = "" - bean.status = 1; + bean.status = UP; } else if (this.type === "ping") { bean.ping = await ping(this.hostname); bean.msg = "" - bean.status = 1; + bean.status = UP; } retries = 0; @@ -113,24 +117,39 @@ class Monitor extends BeanModel { } catch (error) { if ((this.maxretries > 0) && (retries < this.maxretries)) { retries++; - bean.status = 2; + bean.status = PENDING; } bean.msg = error.message; } + // * ? -> ANY STATUS = important [isFirstBeat] + // UP -> PENDING = not important + // * UP -> DOWN = important + // UP -> UP = not important + // PENDING -> PENDING = not important + // * PENDING -> DOWN = important + // PENDING -> UP = not important + // DOWN -> PENDING = this case not exists + // DOWN -> DOWN = not important + // * DOWN -> UP = important + let isImportant = isFirstBeat || + (previousBeat.status === UP && bean.status === DOWN) || + (previousBeat.status === DOWN && bean.status === UP) || + (previousBeat.status === PENDING && bean.status === DOWN); + // Mark as important if status changed, ignore pending pings, // Don't notify if disrupted changes to up - if ((!previousBeat) || ((previousBeat.status !== bean.status) && bean.status !== 2 && !(previousBeat.status === 2 && bean.status !== 0))) { + if (isImportant) { bean.important = true; - // Do not send if first beat is UP - if (previousBeat || bean.status !== 1) { + // Send only if the first beat is DOWN + if (!isFirstBeat || bean.status === DOWN) { let notificationList = await R.getAll(`SELECT notification.* FROM notification, monitor_notification WHERE monitor_id = ? AND monitor_notification.notification_id = notification.id `, [ this.id ]) let text; - if (bean.status === 1) { + if (bean.status === UP) { text = "✅ Up" } else { text = "🔴 Down" @@ -151,8 +170,10 @@ class Monitor extends BeanModel { bean.important = false; } - if (bean.status === 1) { + if (bean.status === UP) { console.info(`Monitor #${this.id} '${this.name}': Successful Response: ${bean.ping} ms | Interval: ${this.interval} seconds | Type: ${this.type}`) + } else if (bean.status === PENDING) { + console.warn(`Monitor #${this.id} '${this.name}': Pending: ${bean.msg} | Type: ${this.type}`) } else { console.warn(`Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Type: ${this.type}`) } diff --git a/server/util.js b/server/util.js index 0a8877b80..33b306b5c 100644 --- a/server/util.js +++ b/server/util.js @@ -1,6 +1,10 @@ // Common JS cannot be used in frontend sadly // sleep, ucfirst is duplicated in ../src/util-frontend.js +exports.DOWN = 0; +exports.UP = 1; +exports.PENDING = 2; + exports.sleep = function (ms) { return new Promise(resolve => setTimeout(resolve, ms)); }