Skip to content

Commit

Permalink
WIP: Store min & max pings
Browse files Browse the repository at this point in the history
  • Loading branch information
chakflying committed Dec 20, 2023
1 parent 996ff28 commit 72e94a0
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 2 deletions.
24 changes: 24 additions & 0 deletions db/knex_migrations/2023-12-21-0000-stat-ping-min-max.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
exports.up = function (knex) {
return knex.schema
.alterTable("stat_daily", function (table) {
table.float("ping_min").notNullable().defaultTo(0).comment("Minimum ping during this period in milliseconds");
table.float("ping_max").notNullable().defaultTo(0).comment("Maximum ping during this period in milliseconds");
})
.alterTable("stat_minutely", function (table) {
table.float("ping_min").notNullable().defaultTo(0).comment("Minimum ping during this period in milliseconds");
table.float("ping_max").notNullable().defaultTo(0).comment("Maximum ping during this period in milliseconds");
});

};

exports.down = function (knex) {
return knex.schema
.alterTable("stat_daily", function (table) {
table.dropColumn("ping_min");
table.dropColumn("ping_max");
})
.alterTable("stat_minutely", function (table) {
table.dropColumn("ping_min");
table.dropColumn("ping_max");
});
};
82 changes: 80 additions & 2 deletions server/uptime-calculator.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ class UptimeCalculator {
* @returns {Promise<UptimeCalculator>} UptimeCalculator
*/
static async getUptimeCalculator(monitorID) {
if (monitorID === undefined || monitorID === null) {
throw new Error("Monitor ID is required");
}

if (!UptimeCalculator.list[monitorID]) {
UptimeCalculator.list[monitorID] = new UptimeCalculator();
await UptimeCalculator.list[monitorID].init(monitorID);
Expand Down Expand Up @@ -108,6 +112,8 @@ class UptimeCalculator {
up: bean.up,
down: bean.down,
avgPing: bean.ping,
minPing: bean.pingMin,
maxPing: bean.pingMax,
});
}

Expand All @@ -123,6 +129,8 @@ class UptimeCalculator {
up: bean.up,
down: bean.down,
avgPing: bean.ping,
minPing: bean.pingMin,
maxPing: bean.pingMax,
});
}
}
Expand Down Expand Up @@ -163,16 +171,24 @@ class UptimeCalculator {
// The first beat of the minute, the ping is the current ping
if (minutelyData.up === 1) {
minutelyData.avgPing = ping;
minutelyData.minPing = ping;
minutelyData.maxPing = ping;
} else {
minutelyData.avgPing = (minutelyData.avgPing * (minutelyData.up - 1) + ping) / minutelyData.up;
minutelyData.minPing = Math.min(minutelyData.minPing, ping);
minutelyData.maxPing = Math.max(minutelyData.maxPing, ping);
}

// Add avg ping (daily)
// The first beat of the day, the ping is the current ping
if (minutelyData.up === 1) {
if (dailyData.up === 1) {
dailyData.avgPing = ping;
dailyData.minPing = ping;
dailyData.maxPing = ping;
} else {
dailyData.avgPing = (dailyData.avgPing * (dailyData.up - 1) + ping) / dailyData.up;
dailyData.minPing = Math.min(dailyData.minPing, ping);
dailyData.maxPing = Math.max(dailyData.maxPing, ping);
}
}

Expand All @@ -199,12 +215,16 @@ class UptimeCalculator {
dailyStatBean.up = dailyData.up;
dailyStatBean.down = dailyData.down;
dailyStatBean.ping = dailyData.avgPing;
dailyStatBean.pingMin = dailyData.minPing;
dailyStatBean.pingMax = dailyData.maxPing;
await R.store(dailyStatBean);

let minutelyStatBean = await this.getMinutelyStatBean(divisionKey);
minutelyStatBean.up = minutelyData.up;
minutelyStatBean.down = minutelyData.down;
minutelyStatBean.ping = minutelyData.avgPing;
minutelyStatBean.pingMin = minutelyData.minPing;
minutelyStatBean.pingMax = minutelyData.maxPing;
await R.store(minutelyStatBean);

// Remove the old data
Expand Down Expand Up @@ -283,6 +303,8 @@ class UptimeCalculator {
up: 0,
down: 0,
avgPing: 0,
minPing: 0,
maxPing: 0,
});
}

Expand All @@ -307,6 +329,8 @@ class UptimeCalculator {
up: 0,
down: 0,
avgPing: 0,
minPing: 0,
maxPing: 0,
});
}

Expand Down Expand Up @@ -416,6 +440,60 @@ class UptimeCalculator {
return uptimeData;
}

/**
* Get data in form of an array
* @param {number} num the number of data points which are expected to be returned
* @param {"day" | "minute"} type the type of data which is expected to be returned
* @returns {Array<object>} uptime data
* @throws {Error} The maximum number of minutes greater than 1440
*/
getDataArray(num, type = "day") {
let key;

if (type === "day") {
key = this.getDailyKey(this.getCurrentDate().unix());
} else {
if (num > 24 * 60) {
throw new Error("The maximum number of minutes is 1440");
}
key = this.getMinutelyKey(this.getCurrentDate());
}

let result = [];

let endTimestamp;

if (type === "day") {
endTimestamp = key - 86400 * (num - 1);
} else {
endTimestamp = key - 60 * (num - 1);
}

while (key >= endTimestamp) {
let data;

if (type === "day") {
data = this.dailyUptimeDataList[key];
} else {
data = this.minutelyUptimeDataList[key];
}

if (data) {
data.timestamp = key;
result.push(data);
}

// Previous day
if (type === "day") {
key -= 86400;
} else {
key -= 60;
}
}

return result;
}

/**
* Get the uptime data by duration
* @param {'24h'|'30d'|'1y'} duration Only accept 24h, 30d, 1y
Expand Down Expand Up @@ -464,7 +542,7 @@ class UptimeCalculator {
}

/**
* @returns {dayjs.Dayjs} Current date
* @returns {dayjs.Dayjs} Current datetime in UTC
*/
getCurrentDate() {
return dayjs.utc();
Expand Down

0 comments on commit 72e94a0

Please sign in to comment.