[status page] implement rest api for heartbeat

This commit is contained in:
LouisLam 2021-09-19 23:24:51 +08:00
parent 6350c43cc3
commit 7ee98d989c
5 changed files with 67 additions and 38 deletions

View file

@ -4,17 +4,7 @@ const { R } = require("redbean-node");
class Group extends BeanModel { class Group extends BeanModel {
async toPublicJSON() { async toPublicJSON() {
let monitorBeanList = await this.getMonitorList();
let monitorBeanList = R.convertToBeans("monitor", await R.getAll(`
SELECT * FROM monitor, monitor_group
WHERE monitor.id = monitor_group.monitor_id
AND group_id = ?
`, [
this.id,
]));
console.log(monitorBeanList);
let monitorList = []; let monitorList = [];
for (let bean of monitorBeanList) { for (let bean of monitorBeanList) {
@ -28,6 +18,16 @@ class Group extends BeanModel {
monitorList, monitorList,
}; };
} }
async getMonitorList() {
return R.convertToBeans("monitor", await R.getAll(`
SELECT monitor.* FROM monitor, monitor_group
WHERE monitor.id = monitor_group.monitor_id
AND group_id = ?
`, [
this.id,
]));
}
} }
module.exports = Group; module.exports = Group;

View file

@ -1,8 +1,8 @@
const dayjs = require("dayjs"); const dayjs = require("dayjs");
const utc = require("dayjs/plugin/utc") const utc = require("dayjs/plugin/utc");
let timezone = require("dayjs/plugin/timezone") let timezone = require("dayjs/plugin/timezone");
dayjs.extend(utc) dayjs.extend(utc);
dayjs.extend(timezone) dayjs.extend(timezone);
const { BeanModel } = require("redbean-node/dist/bean-model"); const { BeanModel } = require("redbean-node/dist/bean-model");
/** /**
@ -13,6 +13,15 @@ const { BeanModel } = require("redbean-node/dist/bean-model");
*/ */
class Heartbeat extends BeanModel { class Heartbeat extends BeanModel {
toPublicJSON() {
return {
status: this.status,
time: this.time,
msg: "", // Hide for public
ping: this.ping,
};
}
toJSON() { toJSON() {
return { return {
monitorID: this.monitor_id, monitorID: this.monitor_id,

View file

@ -38,9 +38,15 @@ router.get("/api/status-page/incident", async (_, response) => {
try { try {
await checkPublished(); await checkPublished();
let incident = await R.findOne("incident", " pin = 1 AND active = 1");
if (incident) {
incident = incident.toPublicJSON();
}
response.json({ response.json({
ok: true, ok: true,
incident: (await R.findOne("incident", " pin = 1 AND active = 1")).toPublicJSON(), incident,
}); });
} catch (error) { } catch (error) {
@ -56,7 +62,7 @@ router.get("/api/status-page/monitor-list", async (_request, response) => {
try { try {
await checkPublished(); await checkPublished();
const publicGroupList = []; const publicGroupList = [];
let list = await R.find("group", " public = 1 ORDER BY weight, name "); let list = await R.find("group", " public = 1 ORDER BY weight ");
for (let groupBean of list) { for (let groupBean of list) {
publicGroupList.push(await groupBean.toPublicJSON()); publicGroupList.push(await groupBean.toPublicJSON());
@ -76,16 +82,30 @@ router.get("/api/status-page/heartbeat", async (_request, response) => {
try { try {
await checkPublished(); await checkPublished();
const monitorList = {}; let heartbeatList = {};
let list = await R.find("", " ", [
]);
for (let monitor of list) { let monitorIDList = await R.getCol(`
monitorList[monitor.id] = await monitor.toJSON(); SELECT monitor_group.monitor_id FROM monitor_group, \`group\`
WHERE monitor_group.group_id = \`group\`.id
AND public = 1
`);
for (let monitorID of monitorIDList) {
let list = await R.getAll(`
SELECT * FROM heartbeat
WHERE monitor_id = ?
ORDER BY time DESC
LIMIT 100
`, [
monitorID,
]);
list = R.convertToBeans("heartbeat", list);
heartbeatList[monitorID] = list.reverse().map(row => row.toPublicJSON());
} }
response.json({ response.json({
monitorList: monitorList, heartbeatList,
}); });
} catch (error) { } catch (error) {

View file

@ -17,8 +17,6 @@ export default {
publicMonitorList() { publicMonitorList() {
let result = {}; let result = {};
console.log(this.publicGroupList);
for (let group of this.publicGroupList) { for (let group of this.publicGroupList) {
for (let monitor of group.monitorList) { for (let monitor of group.monitorList) {
result[monitor.id] = monitor; result[monitor.id] = monitor;

View file

@ -30,10 +30,10 @@
Edit Status Page Edit Status Page
</button> </button>
<router-link to="/dashboard" class="btn btn-info"> <a href="/dashboard" class="btn btn-info">
<font-awesome-icon icon="tachometer-alt" /> <font-awesome-icon icon="tachometer-alt" />
Go to Dashboard Go to Dashboard
</router-link> </a>
</div> </div>
<div v-else> <div v-else>
@ -168,13 +168,10 @@
</div> </div>
<div class="mt-3"> <div class="mt-3">
<VueMultiselect <label>Add a monitor:</label>
v-model="selectedMonitor" <select v-model="selectedMonitor" class="form-control">
:options="allMonitorList" <option v-for="monitor in allMonitorList" :key="monitor.id" :value="monitor">{{ monitor.name }}</option>
:custom-label="monitorSelectorLabel" </select>
:searchable="true"
placeholder="Add a monitor"
></VueMultiselect>
</div> </div>
</div> </div>
@ -382,16 +379,21 @@ export default {
}); });
// 5mins a loop // 5mins a loop
this.updateHeartbeatList();
feedInterval = setInterval(() => { feedInterval = setInterval(() => {
this.updateHeartbeatList();
}, 10 * 1000);
},
methods: {
updateHeartbeatList() {
// If editMode, it will use the data from websocket. // If editMode, it will use the data from websocket.
if (! this.editMode) { if (! this.editMode) {
axios.get("/api/status-page/heartbeat").then((res) => { axios.get("/api/status-page/heartbeat").then((res) => {
// TODO this.$root.heartbeatList = res.data.heartbeatList;
}); });
} }
}, 5 * 60 * 1000); },
},
methods: {
edit() { edit() {
this.$root.initSocketIO(true); this.$root.initSocketIO(true);