diff --git a/.github/ISSUE_TEMPLATE/ask-for-help.yaml b/.github/ISSUE_TEMPLATE/ask-for-help.yaml
index 76a78e5c3..3442e8b73 100644
--- a/.github/ISSUE_TEMPLATE/ask-for-help.yaml
+++ b/.github/ISSUE_TEMPLATE/ask-for-help.yaml
@@ -1,6 +1,6 @@
name: "â Ask for help"
description: "Submit any question related to Uptime Kuma"
-title: "[Help] "
+#title: "[Help] "
labels: [help]
body:
- type: checkboxes
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml
index 055c3a626..2dca1556a 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yaml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yaml
@@ -1,6 +1,6 @@
name: "đ Bug Report"
description: "Submit a bug report to help us improve"
-title: "[Bug] "
+#title: "[Bug] "
labels: [bug]
body:
- type: checkboxes
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml
index 6464e276a..f0a92ede1 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yaml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yaml
@@ -1,6 +1,6 @@
name: đ Feature Request
description: "Submit a proposal for a new feature"
-title: "[Feature] "
+#title: "[Feature] "
labels: [enhancement]
body:
- type: checkboxes
diff --git a/server/model/monitor.js b/server/model/monitor.js
index f3c823c3b..c7ffa99ab 100644
--- a/server/model/monitor.js
+++ b/server/model/monitor.js
@@ -160,6 +160,8 @@ class Monitor extends BeanModel {
};
}
+ debug(`[${this.name}] Prepare Options for axios`);
+
const options = {
url: this.url,
method: (this.method || "get").toLowerCase(),
@@ -180,6 +182,8 @@ class Monitor extends BeanModel {
return checkStatusCode(status, this.getAcceptedStatuscodes());
},
};
+
+ debug(`[${this.name}] Axios Request`);
let res = await axios.request(options);
bean.msg = `${res.status} - ${res.statusText}`;
bean.ping = dayjs().valueOf() - startTime;
@@ -187,12 +191,13 @@ class Monitor extends BeanModel {
// Check certificate if https is used
let certInfoStartTime = dayjs().valueOf();
if (this.getUrl()?.protocol === "https:") {
+ debug(`[${this.name}] Check cert`);
try {
let tlsInfoObject = checkCertificate(res);
tlsInfo = await this.updateTlsInfo(tlsInfoObject);
if (!this.getIgnoreTls()) {
- debug("call sendCertNotification");
+ debug(`[${this.name}] call sendCertNotification`);
await this.sendCertNotification(tlsInfoObject);
}
@@ -371,15 +376,19 @@ class Monitor extends BeanModel {
let beatInterval = this.interval;
+ debug(`[${this.name}] Check isImportant`);
let isImportant = Monitor.isImportantBeat(isFirstBeat, previousBeat?.status, bean.status);
// Mark as important if status changed, ignore pending pings,
// Don't notify if disrupted changes to up
if (isImportant) {
bean.important = true;
+
+ debug(`[${this.name}] sendNotification`);
await Monitor.sendNotification(isFirstBeat, this, bean);
// Clear Status Page Cache
+ debug(`[${this.name}] Check isImportant`);
apicache.clear();
} else {
@@ -397,10 +406,14 @@ class Monitor extends BeanModel {
console.warn(`Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type}`);
}
+ debug(`[${this.name}] Send to socket`);
io.to(this.user_id).emit("heartbeat", bean.toJSON());
Monitor.sendStats(io, this.id, this.user_id);
+ debug(`[${this.name}] Store`);
await R.store(bean);
+
+ debug(`[${this.name}] prometheus.update`);
prometheus.update(bean, tlsInfo);
previousBeat = bean;
@@ -414,7 +427,10 @@ class Monitor extends BeanModel {
}
}
+ debug(`[${this.name}] SetTimeout for next check.`);
this.heartbeatInterval = setTimeout(safeBeat, beatInterval * 1000);
+ } else {
+ console.log(`[${this.name}] isStop = true, no next check.`);
}
};
diff --git a/server/routers/api-router.js b/server/routers/api-router.js
index fbe8136e5..79e828378 100644
--- a/server/routers/api-router.js
+++ b/server/routers/api-router.js
@@ -101,6 +101,10 @@ router.get("/api/status-page/config", async (_request, response) => {
config.statusPagePublished = true;
}
+ if (! config.statusPageTags) {
+ config.statusPageTags = false;
+ }
+
if (! config.title) {
config.title = "Uptime Kuma";
}
@@ -140,10 +144,25 @@ router.get("/api/status-page/monitor-list", cache("5 minutes"), async (_request,
try {
await checkPublished();
const publicGroupList = [];
- let list = await R.find("group", " public = 1 ORDER BY weight ");
-
+ const tagsVisible = (await getSettings("statusPage")).statusPageTags;
+ const list = await R.find("group", " public = 1 ORDER BY weight ");
for (let groupBean of list) {
- publicGroupList.push(await groupBean.toPublicJSON());
+ let monitorGroup = await groupBean.toPublicJSON();
+ if (tagsVisible) {
+ monitorGroup.monitorList = await Promise.all(monitorGroup.monitorList.map(async (monitor) => {
+ // Includes tags as an array in response, allows for tags to be displayed on public status page
+ const tags = await R.getAll(
+ `SELECT monitor_tag.monitor_id, monitor_tag.value, tag.name, tag.color
+ FROM monitor_tag
+ JOIN tag
+ ON monitor_tag.tag_id = tag.id
+ WHERE monitor_tag.monitor_id = ?`, [monitor.id]
+ );
+ return {...monitor, tags: tags}
+ }));
+ }
+
+ publicGroupList.push(monitorGroup);
}
response.json(publicGroupList);
diff --git a/src/assets/app.scss b/src/assets/app.scss
index 89639fd95..5578946bd 100644
--- a/src/assets/app.scss
+++ b/src/assets/app.scss
@@ -346,6 +346,10 @@ textarea.form-control {
&.active {
background-color: #cdf8f4;
}
+ .tags {
+ // Removes margin to line up tags list with uptime percentage
+ margin-left: -0.25rem;
+ }
}
}
diff --git a/src/components/PublicGroupList.vue b/src/components/PublicGroupList.vue
index 23d19e6cd..f30edcef5 100644
--- a/src/components/PublicGroupList.vue
+++ b/src/components/PublicGroupList.vue
@@ -41,6 +41,9 @@