mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-11-23 14:54:05 +00:00
Feat: Handle maintenance in UptimeCalculator
(#4406)
Co-authored-by: Frank Elsinga <frank@elsinga.de>
This commit is contained in:
parent
49b6dacb4d
commit
b8858f4605
2 changed files with 94 additions and 18 deletions
26
db/knex_migrations/2024-01-22-0000-stats-extras.js
Normal file
26
db/knex_migrations/2024-01-22-0000-stats-extras.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
exports.up = function (knex) {
|
||||
return knex.schema
|
||||
.alterTable("stat_daily", function (table) {
|
||||
table.text("extras").defaultTo(null).comment("Extra statistics during this time period");
|
||||
})
|
||||
.alterTable("stat_minutely", function (table) {
|
||||
table.text("extras").defaultTo(null).comment("Extra statistics during this time period");
|
||||
})
|
||||
.alterTable("stat_hourly", function (table) {
|
||||
table.text("extras").defaultTo(null).comment("Extra statistics during this time period");
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
exports.down = function (knex) {
|
||||
return knex.schema
|
||||
.alterTable("stat_daily", function (table) {
|
||||
table.dropColumn("extras");
|
||||
})
|
||||
.alterTable("stat_minutely", function (table) {
|
||||
table.dropColumn("extras");
|
||||
})
|
||||
.alterTable("stat_hourly", function (table) {
|
||||
table.dropColumn("extras");
|
||||
});
|
||||
};
|
|
@ -116,14 +116,23 @@ class UptimeCalculator {
|
|||
]);
|
||||
|
||||
for (let bean of minutelyStatBeans) {
|
||||
let key = bean.timestamp;
|
||||
this.minutelyUptimeDataList.push(key, {
|
||||
let data = {
|
||||
up: bean.up,
|
||||
down: bean.down,
|
||||
avgPing: bean.ping,
|
||||
minPing: bean.pingMin,
|
||||
maxPing: bean.pingMax,
|
||||
});
|
||||
};
|
||||
|
||||
if (bean.extras != null) {
|
||||
data = {
|
||||
...data,
|
||||
...JSON.parse(bean.extras),
|
||||
};
|
||||
}
|
||||
|
||||
let key = bean.timestamp;
|
||||
this.minutelyUptimeDataList.push(key, data);
|
||||
}
|
||||
|
||||
// Load hourly data from database (recent 30 days only)
|
||||
|
@ -133,14 +142,22 @@ class UptimeCalculator {
|
|||
]);
|
||||
|
||||
for (let bean of hourlyStatBeans) {
|
||||
let key = bean.timestamp;
|
||||
this.hourlyUptimeDataList.push(key, {
|
||||
let data = {
|
||||
up: bean.up,
|
||||
down: bean.down,
|
||||
avgPing: bean.ping,
|
||||
minPing: bean.pingMin,
|
||||
maxPing: bean.pingMax,
|
||||
});
|
||||
};
|
||||
|
||||
if (bean.extras != null) {
|
||||
data = {
|
||||
...data,
|
||||
...JSON.parse(bean.extras),
|
||||
};
|
||||
}
|
||||
|
||||
this.hourlyUptimeDataList.push(bean.timestamp, data);
|
||||
}
|
||||
|
||||
// Load daily data from database (recent 365 days only)
|
||||
|
@ -150,14 +167,22 @@ class UptimeCalculator {
|
|||
]);
|
||||
|
||||
for (let bean of dailyStatBeans) {
|
||||
let key = bean.timestamp;
|
||||
this.dailyUptimeDataList.push(key, {
|
||||
let data = {
|
||||
up: bean.up,
|
||||
down: bean.down,
|
||||
avgPing: bean.ping,
|
||||
minPing: bean.pingMin,
|
||||
maxPing: bean.pingMax,
|
||||
});
|
||||
};
|
||||
|
||||
if (bean.extras != null) {
|
||||
data = {
|
||||
...data,
|
||||
...JSON.parse(bean.extras),
|
||||
};
|
||||
}
|
||||
|
||||
this.dailyUptimeDataList.push(bean.timestamp, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,11 +195,6 @@ class UptimeCalculator {
|
|||
async update(status, ping = 0) {
|
||||
let date = this.getCurrentDate();
|
||||
|
||||
// Don't count MAINTENANCE into uptime
|
||||
if (status === MAINTENANCE) {
|
||||
return date;
|
||||
}
|
||||
|
||||
let flatStatus = this.flatStatus(status);
|
||||
|
||||
if (flatStatus === DOWN && ping > 0) {
|
||||
|
@ -189,7 +209,12 @@ class UptimeCalculator {
|
|||
let hourlyData = this.hourlyUptimeDataList[hourlyKey];
|
||||
let dailyData = this.dailyUptimeDataList[dailyKey];
|
||||
|
||||
if (flatStatus === UP) {
|
||||
if (status === MAINTENANCE) {
|
||||
minutelyData.maintenance = minutelyData.maintenance ? minutelyData.maintenance + 1 : 1;
|
||||
hourlyData.maintenance = hourlyData.maintenance ? hourlyData.maintenance + 1 : 1;
|
||||
dailyData.maintenance = dailyData.maintenance ? dailyData.maintenance + 1 : 1;
|
||||
|
||||
} else if (flatStatus === UP) {
|
||||
minutelyData.up += 1;
|
||||
hourlyData.up += 1;
|
||||
dailyData.up += 1;
|
||||
|
@ -233,7 +258,7 @@ class UptimeCalculator {
|
|||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
} else if (flatStatus === DOWN) {
|
||||
minutelyData.down += 1;
|
||||
hourlyData.down += 1;
|
||||
dailyData.down += 1;
|
||||
|
@ -263,6 +288,13 @@ class UptimeCalculator {
|
|||
dailyStatBean.ping = dailyData.avgPing;
|
||||
dailyStatBean.pingMin = dailyData.minPing;
|
||||
dailyStatBean.pingMax = dailyData.maxPing;
|
||||
{
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { up, down, avgPing, minPing, maxPing, ...extras } = dailyData;
|
||||
if (Object.keys(extras).length > 0) {
|
||||
dailyStatBean.extras = JSON.stringify(extras);
|
||||
}
|
||||
}
|
||||
await R.store(dailyStatBean);
|
||||
|
||||
let hourlyStatBean = await this.getHourlyStatBean(hourlyKey);
|
||||
|
@ -271,6 +303,13 @@ class UptimeCalculator {
|
|||
hourlyStatBean.ping = hourlyData.avgPing;
|
||||
hourlyStatBean.pingMin = hourlyData.minPing;
|
||||
hourlyStatBean.pingMax = hourlyData.maxPing;
|
||||
{
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { up, down, avgPing, minPing, maxPing, ...extras } = hourlyData;
|
||||
if (Object.keys(extras).length > 0) {
|
||||
hourlyStatBean.extras = JSON.stringify(extras);
|
||||
}
|
||||
}
|
||||
await R.store(hourlyStatBean);
|
||||
|
||||
let minutelyStatBean = await this.getMinutelyStatBean(divisionKey);
|
||||
|
@ -279,6 +318,13 @@ class UptimeCalculator {
|
|||
minutelyStatBean.ping = minutelyData.avgPing;
|
||||
minutelyStatBean.pingMin = minutelyData.minPing;
|
||||
minutelyStatBean.pingMax = minutelyData.maxPing;
|
||||
{
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { up, down, avgPing, minPing, maxPing, ...extras } = minutelyData;
|
||||
if (Object.keys(extras).length > 0) {
|
||||
minutelyStatBean.extras = JSON.stringify(extras);
|
||||
}
|
||||
}
|
||||
await R.store(minutelyStatBean);
|
||||
|
||||
// Remove the old data
|
||||
|
@ -474,7 +520,7 @@ class UptimeCalculator {
|
|||
flatStatus(status) {
|
||||
switch (status) {
|
||||
case UP:
|
||||
// case MAINTENANCE:
|
||||
case MAINTENANCE:
|
||||
return UP;
|
||||
case DOWN:
|
||||
case PENDING:
|
||||
|
@ -606,7 +652,11 @@ class UptimeCalculator {
|
|||
avgPing = totalPing / total.up;
|
||||
}
|
||||
|
||||
uptimeData.uptime = total.up / (total.up + total.down);
|
||||
if (total.up + total.down === 0) {
|
||||
uptimeData.uptime = 0;
|
||||
} else {
|
||||
uptimeData.uptime = total.up / (total.up + total.down);
|
||||
}
|
||||
uptimeData.avgPing = avgPing;
|
||||
return uptimeData;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue